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

Side by Side Diff: third_party/WebKit/Source/core/layout/LayoutGeometryMap.cpp

Issue 1308273010: Adapt and reland old position sticky implementation (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Merge and attempt to fix base URL Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2012 Apple Inc. All rights reserved. 2 * Copyright (C) 2012 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 20 matching lines...) Expand all
31 #include "core/paint/PaintLayer.h" 31 #include "core/paint/PaintLayer.h"
32 #include "platform/geometry/TransformState.h" 32 #include "platform/geometry/TransformState.h"
33 #include "wtf/TemporaryChange.h" 33 #include "wtf/TemporaryChange.h"
34 34
35 namespace blink { 35 namespace blink {
36 36
37 LayoutGeometryMap::LayoutGeometryMap(MapCoordinatesFlags flags) 37 LayoutGeometryMap::LayoutGeometryMap(MapCoordinatesFlags flags)
38 : m_insertionPosition(kNotFound) 38 : m_insertionPosition(kNotFound)
39 , m_nonUniformStepsCount(0) 39 , m_nonUniformStepsCount(0)
40 , m_transformedStepsCount(0) 40 , m_transformedStepsCount(0)
41 , m_fixedStepsCount(0) 41 , m_viewportConstrainedStepsCount(0)
42 , m_mapCoordinatesFlags(flags) 42 , m_mapCoordinatesFlags(flags)
43 { 43 {
44 } 44 }
45 45
46 LayoutGeometryMap::~LayoutGeometryMap() 46 LayoutGeometryMap::~LayoutGeometryMap()
47 { 47 {
48 } 48 }
49 49
50 void LayoutGeometryMap::mapToContainer(TransformState& transformState, const Lay outBoxModelObject* container) const 50 void LayoutGeometryMap::mapToContainer(TransformState& transformState, const Lay outBoxModelObject* container) const
51 { 51 {
52 // If the mapping includes something like columns, we have to go via layoutO bjects. 52 // If the mapping includes something like columns, we have to go via layoutO bjects.
53 if (hasNonUniformStep()) { 53 if (hasNonUniformStep()) {
54 m_mapping.last().m_layoutObject->mapLocalToContainer(container, transfor mState, ApplyContainerFlip | m_mapCoordinatesFlags); 54 m_mapping.last().m_layoutObject->mapLocalToContainer(container, transfor mState, ApplyContainerFlip | m_mapCoordinatesFlags);
55 transformState.flatten(); 55 transformState.flatten();
56 return; 56 return;
57 } 57 }
58 58
59 bool inFixed = false; 59 bool inFixed = false;
60 #if ENABLE(ASSERT) 60 #if ENABLE(ASSERT)
61 bool foundContainer = !container || (m_mapping.size() && m_mapping[0].m_layo utObject == container); 61 bool foundContainer = !container || (m_mapping.size() && m_mapping[0].m_layo utObject == container);
62 #endif 62 #endif
63 63
64 for (int i = m_mapping.size() - 1; i >= 0; --i) { 64 for (int i = m_mapping.size() - 1; i >= 0; --i) {
65 const LayoutGeometryMapStep& currentStep = m_mapping[i]; 65 const LayoutGeometryMapStep& currentStep = m_mapping[i];
66 66
67 // If container is the root LayoutView (step 0) we want to apply its fix ed position offset. 67 // If container is the root LayoutView (step 0) we want to apply its vie wport constrained position offset.
chrishtr 2015/11/04 01:55:18 Sticky elements are not quite viewport constrained
flackr 2015/11/25 20:47:52 Yes, I rethought this and it seems we can get by w
68 if (i > 0 && currentStep.m_layoutObject == container) { 68 if (i > 0 && currentStep.m_layoutObject == container) {
69 #if ENABLE(ASSERT) 69 #if ENABLE(ASSERT)
70 foundContainer = true; 70 foundContainer = true;
71 #endif 71 #endif
72 break; 72 break;
73 } 73 }
74 74
75 // If this box has a transform, it acts as a fixed position container 75 // If this box has a transform, it acts as a viewport constrained positi on container
76 // for fixed descendants, which prevents the propagation of 'fixed' 76 // for viewport constrained descendants, which prevents the propagation of viewport constrained
77 // unless the layer itself is also fixed position. 77 // unless the layer itself is also a viewport constrained position.
78 if (i && currentStep.m_hasTransform && !currentStep.m_isFixedPosition) 78 // TODO(flackr): Verify how fixed and sticky elements should interact wi th each other.
chrishtr 2015/11/04 01:55:18 Meaning: what should happen with a sticky element
flackr 2015/11/25 20:47:52 Correct. FWIW I have now tested both of these and
79 if (i && currentStep.m_hasTransform && !currentStep.m_isViewportConstrai ned)
79 inFixed = false; 80 inFixed = false;
80 else if (currentStep.m_isFixedPosition) 81 else if (currentStep.m_isViewportConstrained)
81 inFixed = true; 82 inFixed = true;
82 83
83 ASSERT(!i == isTopmostLayoutView(currentStep.m_layoutObject)); 84 ASSERT(!i == isTopmostLayoutView(currentStep.m_layoutObject));
84 85
85 if (!i) { 86 if (!i) {
86 // A null container indicates mapping through the root LayoutView, s o including its transform (the page scale). 87 // A null container indicates mapping through the root LayoutView, s o including its transform (the page scale).
87 if (!container && currentStep.m_transform) 88 if (!container && currentStep.m_transform)
88 transformState.applyTransform(*currentStep.m_transform.get()); 89 transformState.applyTransform(*currentStep.m_transform.get());
89 } else { 90 } else {
90 TransformState::TransformAccumulation accumulate = currentStep.m_acc umulatingTransform ? TransformState::AccumulateTransform : TransformState::Flatt enTransform; 91 TransformState::TransformAccumulation accumulate = currentStep.m_acc umulatingTransform ? TransformState::AccumulateTransform : TransformState::Flatt enTransform;
91 if (currentStep.m_transform) 92 if (currentStep.m_transform)
92 transformState.applyTransform(*currentStep.m_transform.get(), ac cumulate); 93 transformState.applyTransform(*currentStep.m_transform.get(), ac cumulate);
93 else 94 else
94 transformState.move(currentStep.m_offset.width(), currentStep.m_ offset.height(), accumulate); 95 transformState.move(currentStep.m_offset.width(), currentStep.m_ offset.height(), accumulate);
95 } 96 }
96 97
97 if (inFixed && !currentStep.m_offsetForFixedPosition.isZero()) { 98 if (inFixed && !currentStep.m_offsetForViewportConstrained.isZero()) {
98 ASSERT(currentStep.m_layoutObject->isLayoutView()); 99 ASSERT(currentStep.m_layoutObject->isLayoutView());
99 transformState.move(currentStep.m_offsetForFixedPosition); 100 transformState.move(currentStep.m_offsetForViewportConstrained);
100 } 101 }
101 } 102 }
102 103
103 ASSERT(foundContainer); 104 ASSERT(foundContainer);
104 transformState.flatten(); 105 transformState.flatten();
105 } 106 }
106 107
107 FloatPoint LayoutGeometryMap::mapToContainer(const FloatPoint& p, const LayoutBo xModelObject* container) const 108 FloatPoint LayoutGeometryMap::mapToContainer(const FloatPoint& p, const LayoutBo xModelObject* container) const
108 { 109 {
109 FloatPoint result; 110 FloatPoint result;
110 111
111 if (!hasFixedPositionStep() && !hasTransformStep() && !hasNonUniformStep() & & (!container || (m_mapping.size() && container == m_mapping[0].m_layoutObject)) ) { 112 if (!hasViewportConstrainedStep() && !hasTransformStep() && !hasNonUniformSt ep() && (!container || (m_mapping.size() && container == m_mapping[0].m_layoutOb ject))) {
112 result = p + m_accumulatedOffset; 113 result = p + m_accumulatedOffset;
113 } else { 114 } else {
114 TransformState transformState(TransformState::ApplyTransformDirection, p ); 115 TransformState transformState(TransformState::ApplyTransformDirection, p );
115 mapToContainer(transformState, container); 116 mapToContainer(transformState, container);
116 result = transformState.lastPlanarPoint(); 117 result = transformState.lastPlanarPoint();
117 } 118 }
118 119
119 #if ENABLE(ASSERT) 120 #if ENABLE(ASSERT)
120 if (m_mapping.size() > 0) { 121 if (m_mapping.size() > 0) {
121 const LayoutObject* lastLayoutObject = m_mapping.last().m_layoutObject; 122 const LayoutObject* lastLayoutObject = m_mapping.last().m_layoutObject;
(...skipping 27 matching lines...) Expand all
149 fprintf(stderr, " hasTransform"); 150 fprintf(stderr, " hasTransform");
150 fprintf(stderr, "\n"); 151 fprintf(stderr, "\n");
151 } 152 }
152 } 153 }
153 #endif 154 #endif
154 155
155 FloatQuad LayoutGeometryMap::mapToContainer(const FloatRect& rect, const LayoutB oxModelObject* container) const 156 FloatQuad LayoutGeometryMap::mapToContainer(const FloatRect& rect, const LayoutB oxModelObject* container) const
156 { 157 {
157 FloatQuad result; 158 FloatQuad result;
158 159
159 if (!hasFixedPositionStep() && !hasTransformStep() && !hasNonUniformStep() & & (!container || (m_mapping.size() && container == m_mapping[0].m_layoutObject)) ) { 160 if (!hasViewportConstrainedStep() && !hasTransformStep() && !hasNonUniformSt ep() && (!container || (m_mapping.size() && container == m_mapping[0].m_layoutOb ject))) {
160 result = rect; 161 result = rect;
161 result.move(m_accumulatedOffset); 162 result.move(m_accumulatedOffset);
162 } else { 163 } else {
163 TransformState transformState(TransformState::ApplyTransformDirection, r ect.center(), rect); 164 TransformState transformState(TransformState::ApplyTransformDirection, r ect.center(), rect);
164 mapToContainer(transformState, container); 165 mapToContainer(transformState, container);
165 result = transformState.lastPlanarQuad(); 166 result = transformState.lastPlanarQuad();
166 } 167 }
167 168
168 #if ENABLE(ASSERT) 169 #if ENABLE(ASSERT)
169 if (m_mapping.size() > 0) { 170 if (m_mapping.size() > 0) {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 layer->convertToLayerCoords(ancestorLayer, layerOffset); 235 layer->convertToLayerCoords(ancestorLayer, layerOffset);
235 236
236 // The LayoutView must be pushed first. 237 // The LayoutView must be pushed first.
237 if (!m_mapping.size()) { 238 if (!m_mapping.size()) {
238 ASSERT(ancestorLayer->layoutObject()->isLayoutView()); 239 ASSERT(ancestorLayer->layoutObject()->isLayoutView());
239 pushMappingsToAncestor(ancestorLayer->layoutObject(), 0); 240 pushMappingsToAncestor(ancestorLayer->layoutObject(), 0);
240 } 241 }
241 242
242 TemporaryChange<size_t> positionChange(m_insertionPosition, m_mapping.si ze()); 243 TemporaryChange<size_t> positionChange(m_insertionPosition, m_mapping.si ze());
243 bool accumulatingTransform = layer->layoutObject()->style()->preserves3D () || ancestorLayer->layoutObject()->style()->preserves3D(); 244 bool accumulatingTransform = layer->layoutObject()->style()->preserves3D () || ancestorLayer->layoutObject()->style()->preserves3D();
244 push(layoutObject, toLayoutSize(layerOffset), accumulatingTransform, /*i sNonUniform*/ false, /*isFixedPosition*/ false, /*hasTransform*/ false); 245 push(layoutObject, toLayoutSize(layerOffset), accumulatingTransform, /*i sNonUniform*/ false, /*isViewportConstrained*/ false, /*hasTransform*/ false);
245 return; 246 return;
246 } 247 }
247 const LayoutBoxModelObject* ancestorLayoutObject = ancestorLayer ? ancestorL ayer->layoutObject() : 0; 248 const LayoutBoxModelObject* ancestorLayoutObject = ancestorLayer ? ancestorL ayer->layoutObject() : 0;
248 pushMappingsToAncestor(layoutObject, ancestorLayoutObject); 249 pushMappingsToAncestor(layoutObject, ancestorLayoutObject);
249 } 250 }
250 251
251 void LayoutGeometryMap::push(const LayoutObject* layoutObject, const LayoutSize& offsetFromContainer, bool accumulatingTransform, bool isNonUniform, bool isFixe dPosition, bool hasTransform, LayoutSize offsetForFixedPosition) 252 void LayoutGeometryMap::push(const LayoutObject* layoutObject, const LayoutSize& offsetFromContainer, bool accumulatingTransform, bool isNonUniform, bool isView portConstrained, bool hasTransform, LayoutSize offsetForViewportConstrained)
252 { 253 {
253 // fprintf(stderr, "LayoutGeometryMap::push %p %d,%d isNonUniform=%d\n", layo utObject, offsetFromContainer.width().toInt(), offsetFromContainer.height().toIn t(), isNonUniform); 254 // fprintf(stderr, "LayoutGeometryMap::push %p %d,%d isNonUniform=%d\n", layo utObject, offsetFromContainer.width().toInt(), offsetFromContainer.height().toIn t(), isNonUniform);
254 255
255 ASSERT(m_insertionPosition != kNotFound); 256 ASSERT(m_insertionPosition != kNotFound);
256 ASSERT(!layoutObject->isLayoutView() || !m_insertionPosition || m_mapCoordin atesFlags & TraverseDocumentBoundaries); 257 ASSERT(!layoutObject->isLayoutView() || !m_insertionPosition || m_mapCoordin atesFlags & TraverseDocumentBoundaries);
257 ASSERT(offsetForFixedPosition.isZero() || layoutObject->isLayoutView()); 258 ASSERT(offsetForViewportConstrained.isZero() || layoutObject->isLayoutView() );
258 259
259 m_mapping.insert(m_insertionPosition, LayoutGeometryMapStep(layoutObject, ac cumulatingTransform, isNonUniform, isFixedPosition, hasTransform)); 260 m_mapping.insert(m_insertionPosition, LayoutGeometryMapStep(layoutObject, ac cumulatingTransform, isNonUniform, isViewportConstrained, hasTransform));
260 261
261 LayoutGeometryMapStep& step = m_mapping[m_insertionPosition]; 262 LayoutGeometryMapStep& step = m_mapping[m_insertionPosition];
262 step.m_offset = offsetFromContainer; 263 step.m_offset = offsetFromContainer;
263 step.m_offsetForFixedPosition = offsetForFixedPosition; 264 step.m_offsetForViewportConstrained = offsetForViewportConstrained;
264 265
265 stepInserted(step); 266 stepInserted(step);
266 } 267 }
267 268
268 void LayoutGeometryMap::push(const LayoutObject* layoutObject, const Transformat ionMatrix& t, bool accumulatingTransform, bool isNonUniform, bool isFixedPositio n, bool hasTransform, LayoutSize offsetForFixedPosition) 269 void LayoutGeometryMap::push(const LayoutObject* layoutObject, const Transformat ionMatrix& t, bool accumulatingTransform, bool isNonUniform, bool isViewportCons trained, bool hasTransform, LayoutSize offsetForViewportConstrained)
269 { 270 {
270 ASSERT(m_insertionPosition != kNotFound); 271 ASSERT(m_insertionPosition != kNotFound);
271 ASSERT(!layoutObject->isLayoutView() || !m_insertionPosition || m_mapCoordin atesFlags & TraverseDocumentBoundaries); 272 ASSERT(!layoutObject->isLayoutView() || !m_insertionPosition || m_mapCoordin atesFlags & TraverseDocumentBoundaries);
272 ASSERT(offsetForFixedPosition.isZero() || layoutObject->isLayoutView()); 273 ASSERT(offsetForViewportConstrained.isZero() || layoutObject->isLayoutView() );
273 274
274 m_mapping.insert(m_insertionPosition, LayoutGeometryMapStep(layoutObject, ac cumulatingTransform, isNonUniform, isFixedPosition, hasTransform)); 275 m_mapping.insert(m_insertionPosition, LayoutGeometryMapStep(layoutObject, ac cumulatingTransform, isNonUniform, isViewportConstrained, hasTransform));
275 276
276 LayoutGeometryMapStep& step = m_mapping[m_insertionPosition]; 277 LayoutGeometryMapStep& step = m_mapping[m_insertionPosition];
277 step.m_offsetForFixedPosition = offsetForFixedPosition; 278 step.m_offsetForViewportConstrained = offsetForViewportConstrained;
278 279
279 if (!t.isIntegerTranslation()) 280 if (!t.isIntegerTranslation())
280 step.m_transform = adoptPtr(new TransformationMatrix(t)); 281 step.m_transform = adoptPtr(new TransformationMatrix(t));
281 else 282 else
282 step.m_offset = LayoutSize(t.e(), t.f()); 283 step.m_offset = LayoutSize(t.e(), t.f());
283 284
284 stepInserted(step); 285 stepInserted(step);
285 } 286 }
286 287
287 void LayoutGeometryMap::popMappingsToAncestor(const LayoutBoxModelObject* ancest orLayoutObject) 288 void LayoutGeometryMap::popMappingsToAncestor(const LayoutBoxModelObject* ancest orLayoutObject)
(...skipping 15 matching lines...) Expand all
303 void LayoutGeometryMap::stepInserted(const LayoutGeometryMapStep& step) 304 void LayoutGeometryMap::stepInserted(const LayoutGeometryMapStep& step)
304 { 305 {
305 m_accumulatedOffset += step.m_offset; 306 m_accumulatedOffset += step.m_offset;
306 307
307 if (step.m_isNonUniform) 308 if (step.m_isNonUniform)
308 ++m_nonUniformStepsCount; 309 ++m_nonUniformStepsCount;
309 310
310 if (step.m_transform) 311 if (step.m_transform)
311 ++m_transformedStepsCount; 312 ++m_transformedStepsCount;
312 313
313 if (step.m_isFixedPosition) 314 if (step.m_isViewportConstrained)
314 ++m_fixedStepsCount; 315 ++m_viewportConstrainedStepsCount;
315 } 316 }
316 317
317 void LayoutGeometryMap::stepRemoved(const LayoutGeometryMapStep& step) 318 void LayoutGeometryMap::stepRemoved(const LayoutGeometryMapStep& step)
318 { 319 {
319 m_accumulatedOffset -= step.m_offset; 320 m_accumulatedOffset -= step.m_offset;
320 321
321 if (step.m_isNonUniform) { 322 if (step.m_isNonUniform) {
322 ASSERT(m_nonUniformStepsCount); 323 ASSERT(m_nonUniformStepsCount);
323 --m_nonUniformStepsCount; 324 --m_nonUniformStepsCount;
324 } 325 }
325 326
326 if (step.m_transform) { 327 if (step.m_transform) {
327 ASSERT(m_transformedStepsCount); 328 ASSERT(m_transformedStepsCount);
328 --m_transformedStepsCount; 329 --m_transformedStepsCount;
329 } 330 }
330 331
331 if (step.m_isFixedPosition) { 332 if (step.m_isViewportConstrained) {
332 ASSERT(m_fixedStepsCount); 333 ASSERT(m_viewportConstrainedStepsCount);
333 --m_fixedStepsCount; 334 --m_viewportConstrainedStepsCount;
334 } 335 }
335 } 336 }
336 337
337 #if ENABLE(ASSERT) 338 #if ENABLE(ASSERT)
338 bool LayoutGeometryMap::isTopmostLayoutView(const LayoutObject* layoutObject) co nst 339 bool LayoutGeometryMap::isTopmostLayoutView(const LayoutObject* layoutObject) co nst
339 { 340 {
340 if (!layoutObject->isLayoutView()) 341 if (!layoutObject->isLayoutView())
341 return false; 342 return false;
342 343
343 // If we're not working with multiple LayoutViews, then any view is consider ed 344 // If we're not working with multiple LayoutViews, then any view is consider ed
344 // "topmost" (to preserve original behavior). 345 // "topmost" (to preserve original behavior).
345 if (!(m_mapCoordinatesFlags & TraverseDocumentBoundaries)) 346 if (!(m_mapCoordinatesFlags & TraverseDocumentBoundaries))
346 return true; 347 return true;
347 348
348 return layoutObject->frame()->isMainFrame(); 349 return layoutObject->frame()->isMainFrame();
349 } 350 }
350 #endif 351 #endif
351 352
352 } // namespace blink 353 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698