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

Side by Side Diff: Source/core/layout/LayoutRuby.cpp

Issue 1124313004: Remove special handling of ::before and ::after on RUBY elements. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2009 Google Inc. All rights reserved. 2 * Copyright (C) 2009 Google 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 are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 16 matching lines...) Expand all
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31 #include "config.h" 31 #include "config.h"
32 32
33 #include "core/layout/LayoutRuby.h" 33 #include "core/layout/LayoutRuby.h"
34 34
35 #include "core/frame/UseCounter.h" 35 #include "core/frame/UseCounter.h"
36 #include "core/layout/LayoutRubyRun.h" 36 #include "core/layout/LayoutRubyRun.h"
37 #include "core/style/ComputedStyle.h"
38 #include "wtf/RefPtr.h"
39 37
40 namespace blink { 38 namespace blink {
41 39
42 // === generic helper functions to avoid excessive code duplication === 40 // === generic helper functions to avoid excessive code duplication ===
43 41
44 static inline bool isAnonymousRubyInlineBlock(const LayoutObject* object)
45 {
46 ASSERT(!object
47 || !object->parent()->isRuby()
48 || object->isRubyRun()
49 || (object->isInline() && (object->isBeforeContent() || object->isAfterC ontent()))
50 || (object->isAnonymous() && object->isLayoutBlock() && object->style()- >display() == INLINE_BLOCK));
51
52 return object
53 && object->parent()->isRuby()
54 && object->isLayoutBlock()
55 && !object->isRubyRun();
56 }
57
58 static inline bool isRubyBeforeBlock(const LayoutObject* object)
59 {
60 return isAnonymousRubyInlineBlock(object)
61 && !object->previousSibling()
62 && toLayoutBlock(object)->firstChild()
63 && toLayoutBlock(object)->firstChild()->style()->styleType() == BEFORE;
64 }
65
66 static inline bool isRubyAfterBlock(const LayoutObject* object)
67 {
68 return isAnonymousRubyInlineBlock(object)
69 && !object->nextSibling()
70 && toLayoutBlock(object)->firstChild()
71 && toLayoutBlock(object)->firstChild()->style()->styleType() == AFTER;
72 }
73
74 static inline LayoutBlock* rubyBeforeBlock(const LayoutObject* ruby)
75 {
76 LayoutObject* child = ruby->slowFirstChild();
77 return isRubyBeforeBlock(child) ? toLayoutBlock(child) : 0;
78 }
79
80 static inline LayoutBlock* rubyAfterBlock(const LayoutObject* ruby)
81 {
82 LayoutObject* child = ruby->slowLastChild();
83 return isRubyAfterBlock(child) ? toLayoutBlock(child) : 0;
84 }
85
86 static LayoutBlockFlow* createAnonymousRubyInlineBlock(LayoutObject* ruby)
87 {
88 RefPtr<ComputedStyle> newStyle = ComputedStyle::createAnonymousStyleWithDisp lay(ruby->styleRef(), INLINE_BLOCK);
89 LayoutBlockFlow* newBlock = LayoutBlockFlow::createAnonymous(&ruby->document ());
90 newBlock->setStyle(newStyle.release());
91 return newBlock;
92 }
93
94 static LayoutRubyRun* lastRubyRun(const LayoutObject* ruby) 42 static LayoutRubyRun* lastRubyRun(const LayoutObject* ruby)
95 { 43 {
96 LayoutObject* child = ruby->slowLastChild(); 44 LayoutObject* child = ruby->slowLastChild();
97 if (child && !child->isRubyRun()) 45 ASSERT(!child || child->isRubyRun());
98 child = child->previousSibling(); 46 return toLayoutRubyRun(child);
99 ASSERT(!child || child->isRubyRun() || child->isBeforeContent() || child == rubyBeforeBlock(ruby));
100 return child && child->isRubyRun() ? toLayoutRubyRun(child) : 0;
101 } 47 }
102 48
103 static inline LayoutRubyRun* findRubyRunParent(LayoutObject* child) 49 static inline LayoutRubyRun* findRubyRunParent(LayoutObject* child)
104 { 50 {
105 while (child && !child->isRubyRun()) 51 while (child && !child->isRubyRun())
106 child = child->parent(); 52 child = child->parent();
107 return toLayoutRubyRun(child); 53 return toLayoutRubyRun(child);
108 } 54 }
109 55
110 // === ruby as inline object === 56 // === ruby as inline object ===
111 57
112 LayoutRubyAsInline::LayoutRubyAsInline(Element* element) 58 LayoutRubyAsInline::LayoutRubyAsInline(Element* element)
113 : LayoutInline(element) 59 : LayoutInline(element)
114 { 60 {
115 UseCounter::count(document(), UseCounter::RenderRuby); 61 UseCounter::count(document(), UseCounter::RenderRuby);
116 } 62 }
117 63
118 LayoutRubyAsInline::~LayoutRubyAsInline() 64 LayoutRubyAsInline::~LayoutRubyAsInline()
119 { 65 {
120 } 66 }
121 67
122 void LayoutRubyAsInline::styleDidChange(StyleDifference diff, const ComputedStyl e* oldStyle) 68 void LayoutRubyAsInline::styleDidChange(StyleDifference diff, const ComputedStyl e* oldStyle)
123 { 69 {
124 LayoutInline::styleDidChange(diff, oldStyle); 70 LayoutInline::styleDidChange(diff, oldStyle);
125 propagateStyleToAnonymousChildren(); 71 propagateStyleToAnonymousChildren();
126 } 72 }
127 73
128 void LayoutRubyAsInline::addChild(LayoutObject* child, LayoutObject* beforeChild ) 74 void LayoutRubyAsInline::addChild(LayoutObject* child, LayoutObject* beforeChild )
129 { 75 {
130 // Insert :before and :after content before/after the LayoutRubyRun(s)
131 if (child->isBeforeContent()) {
132 if (child->isInline()) {
133 // Add generated inline content normally
134 LayoutInline::addChild(child, firstChild());
135 } else {
136 // Wrap non-inline content with an anonymous inline-block.
137 LayoutBlock* beforeBlock = rubyBeforeBlock(this);
138 if (!beforeBlock) {
139 beforeBlock = createAnonymousRubyInlineBlock(this);
140 LayoutInline::addChild(beforeBlock, firstChild());
141 }
142 beforeBlock->addChild(child);
143 }
144 return;
145 }
146 if (child->isAfterContent()) {
147 if (child->isInline()) {
148 // Add generated inline content normally
149 LayoutInline::addChild(child);
150 } else {
151 // Wrap non-inline content with an anonymous inline-block.
152 LayoutBlock* afterBlock = rubyAfterBlock(this);
153 if (!afterBlock) {
154 afterBlock = createAnonymousRubyInlineBlock(this);
155 LayoutInline::addChild(afterBlock);
156 }
157 afterBlock->addChild(child);
158 }
159 return;
160 }
161
162 // If the child is a ruby run, just add it normally. 76 // If the child is a ruby run, just add it normally.
163 if (child->isRubyRun()) { 77 if (child->isRubyRun()) {
164 LayoutInline::addChild(child, beforeChild); 78 LayoutInline::addChild(child, beforeChild);
165 return; 79 return;
166 } 80 }
167 81
168 if (beforeChild && !isAfterContent(beforeChild)) { 82 if (beforeChild) {
169 // insert child into run 83 // insert child into run
170 LayoutObject* run = beforeChild; 84 LayoutObject* run = beforeChild;
171 while (run && !run->isRubyRun()) 85 while (run && !run->isRubyRun())
172 run = run->parent(); 86 run = run->parent();
173 if (run) { 87 if (run) {
174 if (beforeChild == run) 88 if (beforeChild == run)
175 beforeChild = toLayoutRubyRun(beforeChild)->firstChild(); 89 beforeChild = toLayoutRubyRun(beforeChild)->firstChild();
176 ASSERT(!beforeChild || beforeChild->isDescendantOf(run)); 90 ASSERT(!beforeChild || beforeChild->isDescendantOf(run));
177 run->addChild(child, beforeChild); 91 run->addChild(child, beforeChild);
178 return; 92 return;
179 } 93 }
180 ASSERT_NOT_REACHED(); // beforeChild should always have a run as parent! 94 ASSERT_NOT_REACHED(); // beforeChild should always have a run as parent!
181 // Emergency fallback: fall through and just append. 95 // Emergency fallback: fall through and just append.
182 } 96 }
183 97
184 // If the new child would be appended, try to add the child to the previous run 98 // If the new child would be appended, try to add the child to the previous run
185 // if possible, or create a new run otherwise. 99 // if possible, or create a new run otherwise.
186 // (The LayoutRubyRun object will handle the details) 100 // (The LayoutRubyRun object will handle the details)
187 LayoutRubyRun* lastRun = lastRubyRun(this); 101 LayoutRubyRun* lastRun = lastRubyRun(this);
188 if (!lastRun || lastRun->hasRubyText()) { 102 if (!lastRun || lastRun->hasRubyText()) {
189 lastRun = LayoutRubyRun::staticCreateRubyRun(this); 103 lastRun = LayoutRubyRun::staticCreateRubyRun(this);
190 LayoutInline::addChild(lastRun, beforeChild); 104 LayoutInline::addChild(lastRun, beforeChild);
191 } 105 }
192 lastRun->addChild(child); 106 lastRun->addChild(child);
193 } 107 }
194 108
195 void LayoutRubyAsInline::removeChild(LayoutObject* child) 109 void LayoutRubyAsInline::removeChild(LayoutObject* child)
196 { 110 {
197 // If the child's parent is *this (must be a ruby run or generated content o r anonymous block), 111 // If the child's parent is *this (must be a ruby run), just use the normal remove method.
198 // just use the normal remove method.
199 if (child->parent() == this) { 112 if (child->parent() == this) {
200 ASSERT(child->isRubyRun() || child->isBeforeContent() || child->isAfterC ontent() || isAnonymousRubyInlineBlock(child)); 113 ASSERT(child->isRubyRun());
201 LayoutInline::removeChild(child); 114 LayoutInline::removeChild(child);
202 return; 115 return;
203 } 116 }
204 // If the child's parent is an anoymous block (must be generated :before/:af ter content)
205 // just use the block's remove method.
206 if (isAnonymousRubyInlineBlock(child->parent())) {
207 ASSERT(child->isBeforeContent() || child->isAfterContent());
208 child->parent()->removeChild(child);
209 removeChild(child->parent());
210 return;
211 }
212 117
213 // Otherwise find the containing run and remove it from there. 118 // Otherwise find the containing run and remove it from there.
214 LayoutRubyRun* run = findRubyRunParent(child); 119 LayoutRubyRun* run = findRubyRunParent(child);
215 ASSERT(run); 120 ASSERT(run);
216 run->removeChild(child); 121 run->removeChild(child);
217 } 122 }
218 123
219 // === ruby as block object === 124 // === ruby as block object ===
220 125
221 LayoutRubyAsBlock::LayoutRubyAsBlock(Element* element) 126 LayoutRubyAsBlock::LayoutRubyAsBlock(Element* element)
222 : LayoutBlockFlow(element) 127 : LayoutBlockFlow(element)
223 { 128 {
224 UseCounter::count(document(), UseCounter::RenderRuby); 129 UseCounter::count(document(), UseCounter::RenderRuby);
225 } 130 }
226 131
227 LayoutRubyAsBlock::~LayoutRubyAsBlock() 132 LayoutRubyAsBlock::~LayoutRubyAsBlock()
228 { 133 {
229 } 134 }
230 135
231 void LayoutRubyAsBlock::styleDidChange(StyleDifference diff, const ComputedStyle * oldStyle) 136 void LayoutRubyAsBlock::styleDidChange(StyleDifference diff, const ComputedStyle * oldStyle)
232 { 137 {
233 LayoutBlockFlow::styleDidChange(diff, oldStyle); 138 LayoutBlockFlow::styleDidChange(diff, oldStyle);
234 propagateStyleToAnonymousChildren(); 139 propagateStyleToAnonymousChildren();
235 } 140 }
236 141
237 void LayoutRubyAsBlock::addChild(LayoutObject* child, LayoutObject* beforeChild) 142 void LayoutRubyAsBlock::addChild(LayoutObject* child, LayoutObject* beforeChild)
238 { 143 {
239 // Insert :before and :after content before/after the LayoutRubyRun(s)
240 if (child->isBeforeContent()) {
241 if (child->isInline()) {
242 // Add generated inline content normally
243 LayoutBlockFlow::addChild(child, firstChild());
244 } else {
245 // Wrap non-inline content with an anonymous inline-block.
246 LayoutBlock* beforeBlock = rubyBeforeBlock(this);
247 if (!beforeBlock) {
248 beforeBlock = createAnonymousRubyInlineBlock(this);
249 LayoutBlockFlow::addChild(beforeBlock, firstChild());
250 }
251 beforeBlock->addChild(child);
252 }
253 return;
254 }
255 if (child->isAfterContent()) {
256 if (child->isInline()) {
257 // Add generated inline content normally
258 LayoutBlockFlow::addChild(child);
259 } else {
260 // Wrap non-inline content with an anonymous inline-block.
261 LayoutBlock* afterBlock = rubyAfterBlock(this);
262 if (!afterBlock) {
263 afterBlock = createAnonymousRubyInlineBlock(this);
264 LayoutBlockFlow::addChild(afterBlock);
265 }
266 afterBlock->addChild(child);
267 }
268 return;
269 }
270
271 // If the child is a ruby run, just add it normally. 144 // If the child is a ruby run, just add it normally.
272 if (child->isRubyRun()) { 145 if (child->isRubyRun()) {
273 LayoutBlockFlow::addChild(child, beforeChild); 146 LayoutBlockFlow::addChild(child, beforeChild);
274 return; 147 return;
275 } 148 }
276 149
277 if (beforeChild && !isAfterContent(beforeChild)) { 150 if (beforeChild) {
278 // insert child into run 151 // insert child into run
279 LayoutObject* run = beforeChild; 152 LayoutObject* run = beforeChild;
280 while (run && !run->isRubyRun()) 153 while (run && !run->isRubyRun())
281 run = run->parent(); 154 run = run->parent();
282 if (run) { 155 if (run) {
283 if (beforeChild == run) 156 if (beforeChild == run)
284 beforeChild = toLayoutRubyRun(beforeChild)->firstChild(); 157 beforeChild = toLayoutRubyRun(beforeChild)->firstChild();
285 ASSERT(!beforeChild || beforeChild->isDescendantOf(run)); 158 ASSERT(!beforeChild || beforeChild->isDescendantOf(run));
286 run->addChild(child, beforeChild); 159 run->addChild(child, beforeChild);
287 return; 160 return;
288 } 161 }
289 ASSERT_NOT_REACHED(); // beforeChild should always have a run as parent! 162 ASSERT_NOT_REACHED(); // beforeChild should always have a run as parent!
290 // Emergency fallback: fall through and just append. 163 // Emergency fallback: fall through and just append.
291 } 164 }
292 165
293 // If the new child would be appended, try to add the child to the previous run 166 // If the new child would be appended, try to add the child to the previous run
294 // if possible, or create a new run otherwise. 167 // if possible, or create a new run otherwise.
295 // (The LayoutRubyRun object will handle the details) 168 // (The LayoutRubyRun object will handle the details)
296 LayoutRubyRun* lastRun = lastRubyRun(this); 169 LayoutRubyRun* lastRun = lastRubyRun(this);
297 if (!lastRun || lastRun->hasRubyText()) { 170 if (!lastRun || lastRun->hasRubyText()) {
298 lastRun = LayoutRubyRun::staticCreateRubyRun(this); 171 lastRun = LayoutRubyRun::staticCreateRubyRun(this);
299 LayoutBlockFlow::addChild(lastRun, beforeChild); 172 LayoutBlockFlow::addChild(lastRun, beforeChild);
300 } 173 }
301 lastRun->addChild(child); 174 lastRun->addChild(child);
302 } 175 }
303 176
304 void LayoutRubyAsBlock::removeChild(LayoutObject* child) 177 void LayoutRubyAsBlock::removeChild(LayoutObject* child)
305 { 178 {
306 // If the child's parent is *this (must be a ruby run or generated content o r anonymous block), 179 // If the child's parent is *this (must be a ruby run), just use the normal remove method.
307 // just use the normal remove method.
308 if (child->parent() == this) { 180 if (child->parent() == this) {
309 ASSERT(child->isRubyRun() || child->isBeforeContent() || child->isAfterC ontent() || isAnonymousRubyInlineBlock(child)); 181 ASSERT(child->isRubyRun());
310 LayoutBlockFlow::removeChild(child); 182 LayoutBlockFlow::removeChild(child);
311 return; 183 return;
312 } 184 }
313 // If the child's parent is an anoymous block (must be generated :before/:af ter content)
314 // just use the block's remove method.
315 if (isAnonymousRubyInlineBlock(child->parent())) {
316 ASSERT(child->isBeforeContent() || child->isAfterContent());
317 child->parent()->removeChild(child);
318 removeChild(child->parent());
319 return;
320 }
321 185
322 // Otherwise find the containing run and remove it from there. 186 // Otherwise find the containing run and remove it from there.
323 LayoutRubyRun* run = findRubyRunParent(child); 187 LayoutRubyRun* run = findRubyRunParent(child);
324 ASSERT(run); 188 ASSERT(run);
325 run->removeChild(child); 189 run->removeChild(child);
326 } 190 }
327 191
328 } // namespace blink 192 } // namespace blink
OLDNEW
« no previous file with comments | « LayoutTests/virtual/slimmingpaint/fast/ruby/ruby-inline-style-not-updated-with-before-after-content-expected.txt ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698