OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2007, 2008, 2009 Apple Computer, Inc. | 2 * Copyright (C) 2007, 2008, 2009 Apple Computer, Inc. |
3 * Copyright (C) 2010, 2011 Google Inc. All rights reserved. | 3 * Copyright (C) 2010, 2011 Google Inc. All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. 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 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
156 | 156 |
157 class HTMLElementEquivalent : public NoBaseWillBeGarbageCollected<HTMLElementEqu ivalent> { | 157 class HTMLElementEquivalent : public NoBaseWillBeGarbageCollected<HTMLElementEqu ivalent> { |
158 WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED; | 158 WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED; |
159 DECLARE_EMPTY_VIRTUAL_DESTRUCTOR_WILL_BE_REMOVED(HTMLElementEquivalent); | 159 DECLARE_EMPTY_VIRTUAL_DESTRUCTOR_WILL_BE_REMOVED(HTMLElementEquivalent); |
160 public: | 160 public: |
161 static PassOwnPtrWillBeRawPtr<HTMLElementEquivalent> create(CSSPropertyID pr opertyID, CSSValueID primitiveValue, const HTMLQualifiedName& tagName) | 161 static PassOwnPtrWillBeRawPtr<HTMLElementEquivalent> create(CSSPropertyID pr opertyID, CSSValueID primitiveValue, const HTMLQualifiedName& tagName) |
162 { | 162 { |
163 return adoptPtrWillBeNoop(new HTMLElementEquivalent(propertyID, primitiv eValue, tagName)); | 163 return adoptPtrWillBeNoop(new HTMLElementEquivalent(propertyID, primitiv eValue, tagName)); |
164 } | 164 } |
165 | 165 |
166 virtual bool matches(const Element* element) const { return !m_tagName || el ement->hasTagName(*m_tagName); } | 166 virtual bool matches(const HTMLElement* element) const { return !m_tagName | | element->hasTagName(*m_tagName); } |
167 virtual bool hasAttribute() const { return false; } | 167 virtual bool hasAttribute() const { return false; } |
168 virtual bool propertyExistsInStyle(const StylePropertySet* style) const { re turn style->getPropertyCSSValue(m_propertyID); } | 168 virtual bool propertyExistsInStyle(const StylePropertySet* style) const { re turn style->getPropertyCSSValue(m_propertyID); } |
169 virtual bool valueIsPresentInStyle(Element*, StylePropertySet*) const; | 169 virtual bool valueIsPresentInStyle(HTMLElement*, StylePropertySet*) const; |
170 virtual void addToStyle(Element*, EditingStyle*) const; | 170 virtual void addToStyle(HTMLElement*, EditingStyle*) const; |
171 | 171 |
172 virtual void trace(Visitor* visitor) { visitor->trace(m_primitiveValue); } | 172 virtual void trace(Visitor* visitor) { visitor->trace(m_primitiveValue); } |
173 | 173 |
174 protected: | 174 protected: |
175 HTMLElementEquivalent(CSSPropertyID); | 175 HTMLElementEquivalent(CSSPropertyID); |
176 HTMLElementEquivalent(CSSPropertyID, const HTMLQualifiedName& tagName); | 176 HTMLElementEquivalent(CSSPropertyID, const HTMLQualifiedName& tagName); |
177 HTMLElementEquivalent(CSSPropertyID, CSSValueID primitiveValue, const HTMLQu alifiedName& tagName); | 177 HTMLElementEquivalent(CSSPropertyID, CSSValueID primitiveValue, const HTMLQu alifiedName& tagName); |
178 const CSSPropertyID m_propertyID; | 178 const CSSPropertyID m_propertyID; |
179 const RefPtrWillBeMember<CSSPrimitiveValue> m_primitiveValue; | 179 const RefPtrWillBeMember<CSSPrimitiveValue> m_primitiveValue; |
180 const HTMLQualifiedName* m_tagName; // We can store a pointer because HTML t ag names are const global. | 180 const HTMLQualifiedName* m_tagName; // We can store a pointer because HTML t ag names are const global. |
(...skipping 14 matching lines...) Expand all Loading... | |
195 } | 195 } |
196 | 196 |
197 HTMLElementEquivalent::HTMLElementEquivalent(CSSPropertyID id, CSSValueID primit iveValue, const HTMLQualifiedName& tagName) | 197 HTMLElementEquivalent::HTMLElementEquivalent(CSSPropertyID id, CSSValueID primit iveValue, const HTMLQualifiedName& tagName) |
198 : m_propertyID(id) | 198 : m_propertyID(id) |
199 , m_primitiveValue(CSSPrimitiveValue::createIdentifier(primitiveValue)) | 199 , m_primitiveValue(CSSPrimitiveValue::createIdentifier(primitiveValue)) |
200 , m_tagName(&tagName) | 200 , m_tagName(&tagName) |
201 { | 201 { |
202 ASSERT(primitiveValue != CSSValueInvalid); | 202 ASSERT(primitiveValue != CSSValueInvalid); |
203 } | 203 } |
204 | 204 |
205 bool HTMLElementEquivalent::valueIsPresentInStyle(Element* element, StylePropert ySet* style) const | 205 bool HTMLElementEquivalent::valueIsPresentInStyle(HTMLElement* element, StylePro pertySet* style) const |
206 { | 206 { |
207 RefPtrWillBeRawPtr<CSSValue> value = style->getPropertyCSSValue(m_propertyID ); | 207 RefPtrWillBeRawPtr<CSSValue> value = style->getPropertyCSSValue(m_propertyID ); |
208 return matches(element) && value && value->isPrimitiveValue() && toCSSPrimit iveValue(value.get())->getValueID() == m_primitiveValue->getValueID(); | 208 return matches(element) && value && value->isPrimitiveValue() && toCSSPrimit iveValue(value.get())->getValueID() == m_primitiveValue->getValueID(); |
209 } | 209 } |
210 | 210 |
211 void HTMLElementEquivalent::addToStyle(Element*, EditingStyle* style) const | 211 void HTMLElementEquivalent::addToStyle(HTMLElement*, EditingStyle* style) const |
212 { | 212 { |
213 style->setProperty(m_propertyID, m_primitiveValue->cssText()); | 213 style->setProperty(m_propertyID, m_primitiveValue->cssText()); |
214 } | 214 } |
215 | 215 |
216 class HTMLTextDecorationEquivalent FINAL : public HTMLElementEquivalent { | 216 class HTMLTextDecorationEquivalent FINAL : public HTMLElementEquivalent { |
217 public: | 217 public: |
218 static PassOwnPtrWillBeRawPtr<HTMLElementEquivalent> create(CSSValueID primi tiveValue, const HTMLQualifiedName& tagName) | 218 static PassOwnPtrWillBeRawPtr<HTMLElementEquivalent> create(CSSValueID primi tiveValue, const HTMLQualifiedName& tagName) |
219 { | 219 { |
220 return adoptPtrWillBeNoop(new HTMLTextDecorationEquivalent(primitiveValu e, tagName)); | 220 return adoptPtrWillBeNoop(new HTMLTextDecorationEquivalent(primitiveValu e, tagName)); |
221 } | 221 } |
222 virtual bool propertyExistsInStyle(const StylePropertySet*) const OVERRIDE; | 222 virtual bool propertyExistsInStyle(const StylePropertySet*) const OVERRIDE; |
223 virtual bool valueIsPresentInStyle(Element*, StylePropertySet*) const OVERRI DE; | 223 virtual bool valueIsPresentInStyle(HTMLElement*, StylePropertySet*) const OV ERRIDE; |
224 | 224 |
225 virtual void trace(Visitor* visitor) OVERRIDE { HTMLElementEquivalent::trace (visitor); } | 225 virtual void trace(Visitor* visitor) OVERRIDE { HTMLElementEquivalent::trace (visitor); } |
226 | 226 |
227 private: | 227 private: |
228 HTMLTextDecorationEquivalent(CSSValueID primitiveValue, const HTMLQualifiedN ame& tagName); | 228 HTMLTextDecorationEquivalent(CSSValueID primitiveValue, const HTMLQualifiedN ame& tagName); |
229 }; | 229 }; |
230 | 230 |
231 HTMLTextDecorationEquivalent::HTMLTextDecorationEquivalent(CSSValueID primitiveV alue, const HTMLQualifiedName& tagName) | 231 HTMLTextDecorationEquivalent::HTMLTextDecorationEquivalent(CSSValueID primitiveV alue, const HTMLQualifiedName& tagName) |
232 : HTMLElementEquivalent(textDecorationPropertyForEditing(), primitiveValue, tagName) | 232 : HTMLElementEquivalent(textDecorationPropertyForEditing(), primitiveValue, tagName) |
233 // m_propertyID is used in HTMLElementEquivalent::addToStyle | 233 // m_propertyID is used in HTMLElementEquivalent::addToStyle |
234 { | 234 { |
235 } | 235 } |
236 | 236 |
237 bool HTMLTextDecorationEquivalent::propertyExistsInStyle(const StylePropertySet* style) const | 237 bool HTMLTextDecorationEquivalent::propertyExistsInStyle(const StylePropertySet* style) const |
238 { | 238 { |
239 return style->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect) | 239 return style->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect) |
240 || style->getPropertyCSSValue(textDecorationPropertyForEditing()); | 240 || style->getPropertyCSSValue(textDecorationPropertyForEditing()); |
241 } | 241 } |
242 | 242 |
243 bool HTMLTextDecorationEquivalent::valueIsPresentInStyle(Element* element, Style PropertySet* style) const | 243 bool HTMLTextDecorationEquivalent::valueIsPresentInStyle(HTMLElement* element, S tylePropertySet* style) const |
244 { | 244 { |
245 RefPtrWillBeRawPtr<CSSValue> styleValue = style->getPropertyCSSValue(CSSProp ertyWebkitTextDecorationsInEffect); | 245 RefPtrWillBeRawPtr<CSSValue> styleValue = style->getPropertyCSSValue(CSSProp ertyWebkitTextDecorationsInEffect); |
246 if (!styleValue) | 246 if (!styleValue) |
247 styleValue = style->getPropertyCSSValue(textDecorationPropertyForEditing ()); | 247 styleValue = style->getPropertyCSSValue(textDecorationPropertyForEditing ()); |
248 return matches(element) && styleValue && styleValue->isValueList() && toCSSV alueList(styleValue.get())->hasValue(m_primitiveValue.get()); | 248 return matches(element) && styleValue && styleValue->isValueList() && toCSSV alueList(styleValue.get())->hasValue(m_primitiveValue.get()); |
249 } | 249 } |
250 | 250 |
251 class HTMLAttributeEquivalent : public HTMLElementEquivalent { | 251 class HTMLAttributeEquivalent : public HTMLElementEquivalent { |
252 public: | 252 public: |
253 static PassOwnPtrWillBeRawPtr<HTMLAttributeEquivalent> create(CSSPropertyID propertyID, const HTMLQualifiedName& tagName, const QualifiedName& attrName) | 253 static PassOwnPtrWillBeRawPtr<HTMLAttributeEquivalent> create(CSSPropertyID propertyID, const HTMLQualifiedName& tagName, const QualifiedName& attrName) |
254 { | 254 { |
255 return adoptPtrWillBeNoop(new HTMLAttributeEquivalent(propertyID, tagNam e, attrName)); | 255 return adoptPtrWillBeNoop(new HTMLAttributeEquivalent(propertyID, tagNam e, attrName)); |
256 } | 256 } |
257 static PassOwnPtrWillBeRawPtr<HTMLAttributeEquivalent> create(CSSPropertyID propertyID, const QualifiedName& attrName) | 257 static PassOwnPtrWillBeRawPtr<HTMLAttributeEquivalent> create(CSSPropertyID propertyID, const QualifiedName& attrName) |
258 { | 258 { |
259 return adoptPtrWillBeNoop(new HTMLAttributeEquivalent(propertyID, attrNa me)); | 259 return adoptPtrWillBeNoop(new HTMLAttributeEquivalent(propertyID, attrNa me)); |
260 } | 260 } |
261 | 261 |
262 virtual bool matches(const Element* elem) const OVERRIDE { return HTMLElemen tEquivalent::matches(elem) && elem->hasAttribute(m_attrName); } | 262 virtual bool matches(const HTMLElement* element) const OVERRIDE { return HTM LElementEquivalent::matches(element) && element->hasAttribute(m_attrName); } |
263 virtual bool hasAttribute() const OVERRIDE { return true; } | 263 virtual bool hasAttribute() const OVERRIDE { return true; } |
264 virtual bool valueIsPresentInStyle(Element*, StylePropertySet*) const OVERRI DE; | 264 virtual bool valueIsPresentInStyle(HTMLElement*, StylePropertySet*) const OV ERRIDE; |
265 virtual void addToStyle(Element*, EditingStyle*) const OVERRIDE; | 265 virtual void addToStyle(HTMLElement*, EditingStyle*) const OVERRIDE; |
266 virtual PassRefPtrWillBeRawPtr<CSSValue> attributeValueAsCSSValue(Element*) const; | 266 virtual PassRefPtrWillBeRawPtr<CSSValue> attributeValueAsCSSValue(HTMLElemen t*) const; |
267 inline const QualifiedName& attributeName() const { return m_attrName; } | 267 inline const QualifiedName& attributeName() const { return m_attrName; } |
268 | 268 |
269 virtual void trace(Visitor* visitor) OVERRIDE { HTMLElementEquivalent::trace (visitor); } | 269 virtual void trace(Visitor* visitor) OVERRIDE { HTMLElementEquivalent::trace (visitor); } |
270 | 270 |
271 protected: | 271 protected: |
272 HTMLAttributeEquivalent(CSSPropertyID, const HTMLQualifiedName& tagName, con st QualifiedName& attrName); | 272 HTMLAttributeEquivalent(CSSPropertyID, const HTMLQualifiedName& tagName, con st QualifiedName& attrName); |
273 HTMLAttributeEquivalent(CSSPropertyID, const QualifiedName& attrName); | 273 HTMLAttributeEquivalent(CSSPropertyID, const QualifiedName& attrName); |
274 const QualifiedName& m_attrName; // We can store a reference because HTML at tribute names are const global. | 274 const QualifiedName& m_attrName; // We can store a reference because HTML at tribute names are const global. |
275 }; | 275 }; |
276 | 276 |
277 HTMLAttributeEquivalent::HTMLAttributeEquivalent(CSSPropertyID id, const HTMLQua lifiedName& tagName, const QualifiedName& attrName) | 277 HTMLAttributeEquivalent::HTMLAttributeEquivalent(CSSPropertyID id, const HTMLQua lifiedName& tagName, const QualifiedName& attrName) |
278 : HTMLElementEquivalent(id, tagName) | 278 : HTMLElementEquivalent(id, tagName) |
279 , m_attrName(attrName) | 279 , m_attrName(attrName) |
280 { | 280 { |
281 } | 281 } |
282 | 282 |
283 HTMLAttributeEquivalent::HTMLAttributeEquivalent(CSSPropertyID id, const Qualifi edName& attrName) | 283 HTMLAttributeEquivalent::HTMLAttributeEquivalent(CSSPropertyID id, const Qualifi edName& attrName) |
284 : HTMLElementEquivalent(id) | 284 : HTMLElementEquivalent(id) |
285 , m_attrName(attrName) | 285 , m_attrName(attrName) |
286 { | 286 { |
287 } | 287 } |
288 | 288 |
289 bool HTMLAttributeEquivalent::valueIsPresentInStyle(Element* element, StylePrope rtySet* style) const | 289 bool HTMLAttributeEquivalent::valueIsPresentInStyle(HTMLElement* element, StyleP ropertySet* style) const |
290 { | 290 { |
291 RefPtrWillBeRawPtr<CSSValue> value = attributeValueAsCSSValue(element); | 291 RefPtrWillBeRawPtr<CSSValue> value = attributeValueAsCSSValue(element); |
292 RefPtrWillBeRawPtr<CSSValue> styleValue = style->getPropertyCSSValue(m_prope rtyID); | 292 RefPtrWillBeRawPtr<CSSValue> styleValue = style->getPropertyCSSValue(m_prope rtyID); |
293 | 293 |
294 return compareCSSValuePtr(value, styleValue); | 294 return compareCSSValuePtr(value, styleValue); |
295 } | 295 } |
296 | 296 |
297 void HTMLAttributeEquivalent::addToStyle(Element* element, EditingStyle* style) const | 297 void HTMLAttributeEquivalent::addToStyle(HTMLElement* element, EditingStyle* sty le) const |
298 { | 298 { |
299 if (RefPtrWillBeRawPtr<CSSValue> value = attributeValueAsCSSValue(element)) | 299 if (RefPtrWillBeRawPtr<CSSValue> value = attributeValueAsCSSValue(element)) |
300 style->setProperty(m_propertyID, value->cssText()); | 300 style->setProperty(m_propertyID, value->cssText()); |
301 } | 301 } |
302 | 302 |
303 PassRefPtrWillBeRawPtr<CSSValue> HTMLAttributeEquivalent::attributeValueAsCSSVal ue(Element* element) const | 303 PassRefPtrWillBeRawPtr<CSSValue> HTMLAttributeEquivalent::attributeValueAsCSSVal ue(HTMLElement* element) const |
304 { | 304 { |
305 ASSERT(element); | 305 ASSERT(element); |
306 const AtomicString& value = element->getAttribute(m_attrName); | 306 const AtomicString& value = element->getAttribute(m_attrName); |
307 if (value.isNull()) | 307 if (value.isNull()) |
308 return nullptr; | 308 return nullptr; |
309 | 309 |
310 RefPtrWillBeRawPtr<MutableStylePropertySet> dummyStyle = nullptr; | 310 RefPtrWillBeRawPtr<MutableStylePropertySet> dummyStyle = nullptr; |
311 dummyStyle = MutableStylePropertySet::create(); | 311 dummyStyle = MutableStylePropertySet::create(); |
312 dummyStyle->setProperty(m_propertyID, value); | 312 dummyStyle->setProperty(m_propertyID, value); |
313 return dummyStyle->getPropertyCSSValue(m_propertyID); | 313 return dummyStyle->getPropertyCSSValue(m_propertyID); |
314 } | 314 } |
315 | 315 |
316 class HTMLFontSizeEquivalent FINAL : public HTMLAttributeEquivalent { | 316 class HTMLFontSizeEquivalent FINAL : public HTMLAttributeEquivalent { |
317 public: | 317 public: |
318 static PassOwnPtrWillBeRawPtr<HTMLFontSizeEquivalent> create() | 318 static PassOwnPtrWillBeRawPtr<HTMLFontSizeEquivalent> create() |
319 { | 319 { |
320 return adoptPtrWillBeNoop(new HTMLFontSizeEquivalent()); | 320 return adoptPtrWillBeNoop(new HTMLFontSizeEquivalent()); |
321 } | 321 } |
322 virtual PassRefPtrWillBeRawPtr<CSSValue> attributeValueAsCSSValue(Element*) const OVERRIDE; | 322 virtual PassRefPtrWillBeRawPtr<CSSValue> attributeValueAsCSSValue(HTMLElemen t*) const OVERRIDE; |
323 | 323 |
324 virtual void trace(Visitor* visitor) OVERRIDE { HTMLAttributeEquivalent::tra ce(visitor); } | 324 virtual void trace(Visitor* visitor) OVERRIDE { HTMLAttributeEquivalent::tra ce(visitor); } |
325 | 325 |
326 private: | 326 private: |
327 HTMLFontSizeEquivalent(); | 327 HTMLFontSizeEquivalent(); |
328 }; | 328 }; |
329 | 329 |
330 HTMLFontSizeEquivalent::HTMLFontSizeEquivalent() | 330 HTMLFontSizeEquivalent::HTMLFontSizeEquivalent() |
331 : HTMLAttributeEquivalent(CSSPropertyFontSize, HTMLNames::fontTag, HTMLNames ::sizeAttr) | 331 : HTMLAttributeEquivalent(CSSPropertyFontSize, HTMLNames::fontTag, HTMLNames ::sizeAttr) |
332 { | 332 { |
333 } | 333 } |
334 | 334 |
335 PassRefPtrWillBeRawPtr<CSSValue> HTMLFontSizeEquivalent::attributeValueAsCSSValu e(Element* element) const | 335 PassRefPtrWillBeRawPtr<CSSValue> HTMLFontSizeEquivalent::attributeValueAsCSSValu e(HTMLElement* element) const |
336 { | 336 { |
337 ASSERT(element); | 337 ASSERT(element); |
338 const AtomicString& value = element->getAttribute(m_attrName); | 338 const AtomicString& value = element->getAttribute(m_attrName); |
339 if (value.isNull()) | 339 if (value.isNull()) |
340 return nullptr; | 340 return nullptr; |
341 CSSValueID size; | 341 CSSValueID size; |
342 if (!HTMLFontElement::cssValueFromFontSizeNumber(value, size)) | 342 if (!HTMLFontElement::cssValueFromFontSizeNumber(value, size)) |
343 return nullptr; | 343 return nullptr; |
344 return CSSPrimitiveValue::createIdentifier(size); | 344 return CSSPrimitiveValue::createIdentifier(size); |
345 } | 345 } |
346 | 346 |
347 float EditingStyle::NoFontDelta = 0.0f; | 347 float EditingStyle::NoFontDelta = 0.0f; |
348 | 348 |
349 EditingStyle::EditingStyle() | 349 EditingStyle::EditingStyle() |
350 : m_fixedPitchFontType(NonFixedPitchFont) | 350 : m_fixedPitchFontType(NonFixedPitchFont) |
351 , m_fontSizeDelta(NoFontDelta) | 351 , m_fontSizeDelta(NoFontDelta) |
352 { | 352 { |
353 } | 353 } |
354 | 354 |
355 EditingStyle::EditingStyle(Node* node, PropertiesToInclude propertiesToInclude) | 355 EditingStyle::EditingStyle(ContainerNode* node, PropertiesToInclude propertiesTo Include) |
356 : m_fixedPitchFontType(NonFixedPitchFont) | 356 : m_fixedPitchFontType(NonFixedPitchFont) |
357 , m_fontSizeDelta(NoFontDelta) | 357 , m_fontSizeDelta(NoFontDelta) |
358 { | 358 { |
359 init(node, propertiesToInclude); | 359 init(node, propertiesToInclude); |
360 } | 360 } |
361 | 361 |
362 EditingStyle::EditingStyle(const Position& position, PropertiesToInclude propert iesToInclude) | 362 EditingStyle::EditingStyle(const Position& position, PropertiesToInclude propert iesToInclude) |
363 : m_fixedPitchFontType(NonFixedPitchFont) | 363 : m_fixedPitchFontType(NonFixedPitchFont) |
364 , m_fontSizeDelta(NoFontDelta) | 364 , m_fontSizeDelta(NoFontDelta) |
365 { | 365 { |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
620 } | 620 } |
621 | 621 |
622 void EditingStyle::removeBlockProperties() | 622 void EditingStyle::removeBlockProperties() |
623 { | 623 { |
624 if (!m_mutableStyle) | 624 if (!m_mutableStyle) |
625 return; | 625 return; |
626 | 626 |
627 m_mutableStyle->removeBlockProperties(); | 627 m_mutableStyle->removeBlockProperties(); |
628 } | 628 } |
629 | 629 |
630 void EditingStyle::removeStyleAddedByNode(Node* node) | 630 void EditingStyle::removeStyleAddedByElement(Element* element) |
631 { | 631 { |
632 if (!node || !node->parentNode()) | 632 if (!element || !element->parentNode()) |
633 return; | 633 return; |
634 RefPtrWillBeRawPtr<MutableStylePropertySet> parentStyle = editingStyleFromCo mputedStyle(CSSComputedStyleDeclaration::create(node->parentNode()), AllEditingP roperties); | 634 RefPtrWillBeRawPtr<MutableStylePropertySet> parentStyle = editingStyleFromCo mputedStyle(CSSComputedStyleDeclaration::create(element->parentNode()), AllEditi ngProperties); |
635 RefPtrWillBeRawPtr<MutableStylePropertySet> nodeStyle = editingStyleFromComp utedStyle(CSSComputedStyleDeclaration::create(node), AllEditingProperties); | 635 RefPtrWillBeRawPtr<MutableStylePropertySet> nodeStyle = editingStyleFromComp utedStyle(CSSComputedStyleDeclaration::create(element), AllEditingProperties); |
636 nodeStyle->removeEquivalentProperties(parentStyle.get()); | 636 nodeStyle->removeEquivalentProperties(parentStyle.get()); |
637 m_mutableStyle->removeEquivalentProperties(nodeStyle.get()); | 637 m_mutableStyle->removeEquivalentProperties(nodeStyle.get()); |
638 } | 638 } |
639 | 639 |
640 void EditingStyle::removeStyleConflictingWithStyleOfNode(Node* node) | 640 void EditingStyle::removeStyleConflictingWithStyleOfElement(Element* element) |
641 { | 641 { |
642 if (!node || !node->parentNode() || !m_mutableStyle) | 642 if (!element || !element->parentNode() || !m_mutableStyle) |
643 return; | 643 return; |
644 | 644 |
645 RefPtrWillBeRawPtr<MutableStylePropertySet> parentStyle = editingStyleFromCo mputedStyle(CSSComputedStyleDeclaration::create(node->parentNode()), AllEditingP roperties); | 645 RefPtrWillBeRawPtr<MutableStylePropertySet> parentStyle = editingStyleFromCo mputedStyle(CSSComputedStyleDeclaration::create(element->parentNode()), AllEditi ngProperties); |
646 RefPtrWillBeRawPtr<MutableStylePropertySet> nodeStyle = editingStyleFromComp utedStyle(CSSComputedStyleDeclaration::create(node), AllEditingProperties); | 646 RefPtrWillBeRawPtr<MutableStylePropertySet> nodeStyle = editingStyleFromComp utedStyle(CSSComputedStyleDeclaration::create(element), AllEditingProperties); |
647 nodeStyle->removeEquivalentProperties(parentStyle.get()); | 647 nodeStyle->removeEquivalentProperties(parentStyle.get()); |
648 | 648 |
649 unsigned propertyCount = nodeStyle->propertyCount(); | 649 unsigned propertyCount = nodeStyle->propertyCount(); |
650 for (unsigned i = 0; i < propertyCount; ++i) | 650 for (unsigned i = 0; i < propertyCount; ++i) |
651 m_mutableStyle->removeProperty(nodeStyle->propertyAt(i).id()); | 651 m_mutableStyle->removeProperty(nodeStyle->propertyAt(i).id()); |
652 } | 652 } |
653 | 653 |
654 void EditingStyle::collapseTextDecorationProperties() | 654 void EditingStyle::collapseTextDecorationProperties() |
655 { | 655 { |
656 if (!m_mutableStyle) | 656 if (!m_mutableStyle) |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
725 } | 725 } |
726 } | 726 } |
727 } | 727 } |
728 if (node == selection.end().deprecatedNode()) | 728 if (node == selection.end().deprecatedNode()) |
729 break; | 729 break; |
730 } | 730 } |
731 | 731 |
732 return state; | 732 return state; |
733 } | 733 } |
734 | 734 |
735 bool EditingStyle::conflictsWithInlineStyleOfElement(Element* element, EditingSt yle* extractedStyle, Vector<CSSPropertyID>* conflictingProperties) const | 735 bool EditingStyle::conflictsWithInlineStyleOfElement(HTMLElement* element, Editi ngStyle* extractedStyle, Vector<CSSPropertyID>* conflictingProperties) const |
736 { | 736 { |
737 ASSERT(element); | 737 ASSERT(element); |
738 ASSERT(!conflictingProperties || conflictingProperties->isEmpty()); | 738 ASSERT(!conflictingProperties || conflictingProperties->isEmpty()); |
739 | 739 |
740 const StylePropertySet* inlineStyle = element->inlineStyle(); | 740 const StylePropertySet* inlineStyle = element->inlineStyle(); |
741 if (!m_mutableStyle || !inlineStyle) | 741 if (!m_mutableStyle || !inlineStyle) |
742 return false; | 742 return false; |
743 | 743 |
744 unsigned propertyCount = m_mutableStyle->propertyCount(); | 744 unsigned propertyCount = m_mutableStyle->propertyCount(); |
745 for (unsigned i = 0; i < propertyCount; ++i) { | 745 for (unsigned i = 0; i < propertyCount; ++i) { |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
982 { | 982 { |
983 ASSERT(document); | 983 ASSERT(document); |
984 | 984 |
985 RefPtrWillBeRawPtr<EditingStyle> typingStyle = document->frame()->selection( ).typingStyle(); | 985 RefPtrWillBeRawPtr<EditingStyle> typingStyle = document->frame()->selection( ).typingStyle(); |
986 if (!typingStyle || typingStyle == this) | 986 if (!typingStyle || typingStyle == this) |
987 return; | 987 return; |
988 | 988 |
989 mergeStyle(typingStyle->style(), OverrideValues); | 989 mergeStyle(typingStyle->style(), OverrideValues); |
990 } | 990 } |
991 | 991 |
992 void EditingStyle::mergeInlineStyleOfElement(Element* element, CSSPropertyOverri deMode mode, PropertiesToInclude propertiesToInclude) | 992 void EditingStyle::mergeInlineStyleOfElement(HTMLElement* element, CSSPropertyOv errideMode mode, PropertiesToInclude propertiesToInclude) |
993 { | 993 { |
994 ASSERT(element); | 994 ASSERT(element); |
995 if (!element->inlineStyle()) | 995 if (!element->inlineStyle()) |
996 return; | 996 return; |
997 | 997 |
998 switch (propertiesToInclude) { | 998 switch (propertiesToInclude) { |
999 case AllProperties: | 999 case AllProperties: |
1000 mergeStyle(element->inlineStyle(), mode); | 1000 mergeStyle(element->inlineStyle(), mode); |
1001 return; | 1001 return; |
1002 case OnlyEditingInheritableProperties: | 1002 case OnlyEditingInheritableProperties: |
1003 mergeStyle(copyEditingProperties(element->inlineStyle(), OnlyInheritable EditingProperties).get(), mode); | 1003 mergeStyle(copyEditingProperties(element->inlineStyle(), OnlyInheritable EditingProperties).get(), mode); |
1004 return; | 1004 return; |
1005 case EditingPropertiesInEffect: | 1005 case EditingPropertiesInEffect: |
1006 mergeStyle(copyEditingProperties(element->inlineStyle(), AllEditingPrope rties).get(), mode); | 1006 mergeStyle(copyEditingProperties(element->inlineStyle(), AllEditingPrope rties).get(), mode); |
1007 return; | 1007 return; |
1008 } | 1008 } |
1009 } | 1009 } |
1010 | 1010 |
1011 static inline bool elementMatchesAndPropertyIsNotInInlineStyleDecl(const HTMLEle mentEquivalent* equivalent, const Element* element, | 1011 static inline bool elementMatchesAndPropertyIsNotInInlineStyleDecl(const HTMLEle mentEquivalent* equivalent, const HTMLElement* element, |
1012 EditingStyle::CSSPropertyOverrideMode mode, StylePropertySet* style) | 1012 EditingStyle::CSSPropertyOverrideMode mode, StylePropertySet* style) |
1013 { | 1013 { |
1014 return equivalent->matches(element) && (!element->inlineStyle() || !equivale nt->propertyExistsInStyle(element->inlineStyle())) | 1014 return equivalent->matches(element) && (!element->inlineStyle() || !equivale nt->propertyExistsInStyle(element->inlineStyle())) |
1015 && (mode == EditingStyle::OverrideValues || !equivalent->propertyExistsI nStyle(style)); | 1015 && (mode == EditingStyle::OverrideValues || !equivalent->propertyExistsI nStyle(style)); |
1016 } | 1016 } |
1017 | 1017 |
1018 static PassRefPtrWillBeRawPtr<MutableStylePropertySet> extractEditingProperties( const StylePropertySet* style, EditingStyle::PropertiesToInclude propertiesToInc lude) | 1018 static PassRefPtrWillBeRawPtr<MutableStylePropertySet> extractEditingProperties( const StylePropertySet* style, EditingStyle::PropertiesToInclude propertiesToInc lude) |
1019 { | 1019 { |
1020 if (!style) | 1020 if (!style) |
1021 return nullptr; | 1021 return nullptr; |
(...skipping 14 matching lines...) Expand all Loading... | |
1036 { | 1036 { |
1037 RefPtrWillBeRawPtr<EditingStyle> styleFromRules = EditingStyle::create(); | 1037 RefPtrWillBeRawPtr<EditingStyle> styleFromRules = EditingStyle::create(); |
1038 styleFromRules->mergeStyleFromRulesForSerialization(element); | 1038 styleFromRules->mergeStyleFromRulesForSerialization(element); |
1039 | 1039 |
1040 if (element->inlineStyle()) | 1040 if (element->inlineStyle()) |
1041 styleFromRules->m_mutableStyle->mergeAndOverrideOnConflict(element->inli neStyle()); | 1041 styleFromRules->m_mutableStyle->mergeAndOverrideOnConflict(element->inli neStyle()); |
1042 | 1042 |
1043 styleFromRules->m_mutableStyle = extractEditingProperties(styleFromRules->m_ mutableStyle.get(), propertiesToInclude); | 1043 styleFromRules->m_mutableStyle = extractEditingProperties(styleFromRules->m_ mutableStyle.get(), propertiesToInclude); |
1044 mergeStyle(styleFromRules->m_mutableStyle.get(), mode); | 1044 mergeStyle(styleFromRules->m_mutableStyle.get(), mode); |
1045 | 1045 |
1046 if (!element->isHTMLElement()) | |
pdr.
2014/07/29 22:33:14
Nit: Unlike the other cases, this seems like it co
Inactive
2014/07/29 23:14:59
Ok, I'll drop this part of this change.
Inactive
2014/07/29 23:34:33
Done.
| |
1047 return; | |
1048 | |
1049 HTMLElement* htmlElement = toHTMLElement(element); | |
1046 const WillBeHeapVector<OwnPtrWillBeMember<HTMLElementEquivalent> >& elementE quivalents = htmlElementEquivalents(); | 1050 const WillBeHeapVector<OwnPtrWillBeMember<HTMLElementEquivalent> >& elementE quivalents = htmlElementEquivalents(); |
1047 for (size_t i = 0; i < elementEquivalents.size(); ++i) { | 1051 for (size_t i = 0; i < elementEquivalents.size(); ++i) { |
1048 if (elementMatchesAndPropertyIsNotInInlineStyleDecl(elementEquivalents[i ].get(), element, mode, m_mutableStyle.get())) | 1052 if (elementMatchesAndPropertyIsNotInInlineStyleDecl(elementEquivalents[i ].get(), htmlElement, mode, m_mutableStyle.get())) |
1049 elementEquivalents[i]->addToStyle(element, this); | 1053 elementEquivalents[i]->addToStyle(htmlElement, this); |
1050 } | 1054 } |
1051 | 1055 |
1052 const WillBeHeapVector<OwnPtrWillBeMember<HTMLAttributeEquivalent> >& attrib uteEquivalents = htmlAttributeEquivalents(); | 1056 const WillBeHeapVector<OwnPtrWillBeMember<HTMLAttributeEquivalent> >& attrib uteEquivalents = htmlAttributeEquivalents(); |
1053 for (size_t i = 0; i < attributeEquivalents.size(); ++i) { | 1057 for (size_t i = 0; i < attributeEquivalents.size(); ++i) { |
1054 if (attributeEquivalents[i]->attributeName() == HTMLNames::dirAttr) | 1058 if (attributeEquivalents[i]->attributeName() == HTMLNames::dirAttr) |
1055 continue; // We don't want to include directionality | 1059 continue; // We don't want to include directionality |
1056 if (elementMatchesAndPropertyIsNotInInlineStyleDecl(attributeEquivalents [i].get(), element, mode, m_mutableStyle.get())) | 1060 if (elementMatchesAndPropertyIsNotInInlineStyleDecl(attributeEquivalents [i].get(), htmlElement, mode, m_mutableStyle.get())) |
1057 attributeEquivalents[i]->addToStyle(element, this); | 1061 attributeEquivalents[i]->addToStyle(htmlElement, this); |
1058 } | 1062 } |
1059 } | 1063 } |
1060 | 1064 |
1061 PassRefPtrWillBeRawPtr<EditingStyle> EditingStyle::wrappingStyleForSerialization (Node* context, bool shouldAnnotate) | 1065 PassRefPtrWillBeRawPtr<EditingStyle> EditingStyle::wrappingStyleForSerialization (ContainerNode* context, bool shouldAnnotate) |
1062 { | 1066 { |
1063 RefPtrWillBeRawPtr<EditingStyle> wrappingStyle = nullptr; | 1067 RefPtrWillBeRawPtr<EditingStyle> wrappingStyle = nullptr; |
1064 if (shouldAnnotate) { | 1068 if (shouldAnnotate) { |
1065 wrappingStyle = EditingStyle::create(context, EditingStyle::EditingPrope rtiesInEffect); | 1069 wrappingStyle = EditingStyle::create(context, EditingStyle::EditingPrope rtiesInEffect); |
1066 | 1070 |
1067 // Styles that Mail blockquotes contribute should only be placed on the Mail blockquote, | 1071 // Styles that Mail blockquotes contribute should only be placed on the Mail blockquote, |
1068 // to help us differentiate those styles from ones that the user has app lied. | 1072 // to help us differentiate those styles from ones that the user has app lied. |
1069 // This helps us get the color of content pasted into blockquotes right. | 1073 // This helps us get the color of content pasted into blockquotes right. |
1070 wrappingStyle->removeStyleAddedByNode(enclosingNodeOfType(firstPositionI nOrBeforeNode(context), isMailBlockquote, CanCrossEditingBoundary)); | 1074 wrappingStyle->removeStyleAddedByElement(toHTMLElement(enclosingNodeOfTy pe(firstPositionInOrBeforeNode(context), isMailBlockquote, CanCrossEditingBounda ry))); |
1071 | 1075 |
1072 // Call collapseTextDecorationProperties first or otherwise it'll copy t he value over from in-effect to text-decorations. | 1076 // Call collapseTextDecorationProperties first or otherwise it'll copy t he value over from in-effect to text-decorations. |
1073 wrappingStyle->collapseTextDecorationProperties(); | 1077 wrappingStyle->collapseTextDecorationProperties(); |
1074 | 1078 |
1075 return wrappingStyle.release(); | 1079 return wrappingStyle.release(); |
1076 } | 1080 } |
1077 | 1081 |
1078 wrappingStyle = EditingStyle::create(); | 1082 wrappingStyle = EditingStyle::create(); |
1079 | 1083 |
1080 // When not annotating for interchange, we only preserve inline style declar ations. | 1084 // When not annotating for interchange, we only preserve inline style declar ations. |
1081 for (Node* node = context; node && !node->isDocumentNode(); node = node->par entNode()) { | 1085 for (ContainerNode* node = context; node && !node->isDocumentNode(); node = node->parentNode()) { |
1082 if (node->isStyledElement() && !isMailBlockquote(node)) { | 1086 if (node->isStyledElement() && !isMailBlockquote(node)) { |
1083 wrappingStyle->mergeInlineAndImplicitStyleOfElement(toElement(node), EditingStyle::DoNotOverrideValues, | 1087 wrappingStyle->mergeInlineAndImplicitStyleOfElement(toElement(node), EditingStyle::DoNotOverrideValues, |
1084 EditingStyle::EditingPropertiesInEffect); | 1088 EditingStyle::EditingPropertiesInEffect); |
1085 } | 1089 } |
1086 } | 1090 } |
1087 | 1091 |
1088 return wrappingStyle.release(); | 1092 return wrappingStyle.release(); |
1089 } | 1093 } |
1090 | 1094 |
1091 | 1095 |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1181 static void removePropertiesInStyle(MutableStylePropertySet* styleToRemoveProper tiesFrom, StylePropertySet* style) | 1185 static void removePropertiesInStyle(MutableStylePropertySet* styleToRemoveProper tiesFrom, StylePropertySet* style) |
1182 { | 1186 { |
1183 unsigned propertyCount = style->propertyCount(); | 1187 unsigned propertyCount = style->propertyCount(); |
1184 Vector<CSSPropertyID> propertiesToRemove(propertyCount); | 1188 Vector<CSSPropertyID> propertiesToRemove(propertyCount); |
1185 for (unsigned i = 0; i < propertyCount; ++i) | 1189 for (unsigned i = 0; i < propertyCount; ++i) |
1186 propertiesToRemove[i] = style->propertyAt(i).id(); | 1190 propertiesToRemove[i] = style->propertyAt(i).id(); |
1187 | 1191 |
1188 styleToRemovePropertiesFrom->removePropertiesInSet(propertiesToRemove.data() , propertiesToRemove.size()); | 1192 styleToRemovePropertiesFrom->removePropertiesInSet(propertiesToRemove.data() , propertiesToRemove.size()); |
1189 } | 1193 } |
1190 | 1194 |
1191 void EditingStyle::removeStyleFromRulesAndContext(Element* element, Node* contex t) | 1195 void EditingStyle::removeStyleFromRulesAndContext(Element* element, ContainerNod e* context) |
1192 { | 1196 { |
1193 ASSERT(element); | 1197 ASSERT(element); |
1194 if (!m_mutableStyle) | 1198 if (!m_mutableStyle) |
1195 return; | 1199 return; |
1196 | 1200 |
1197 // 1. Remove style from matched rules because style remain without repeating it in inline style declaration | 1201 // 1. Remove style from matched rules because style remain without repeating it in inline style declaration |
1198 RefPtrWillBeRawPtr<MutableStylePropertySet> styleFromMatchedRules = styleFro mMatchedRulesForElement(element, StyleResolver::AllButEmptyCSSRules); | 1202 RefPtrWillBeRawPtr<MutableStylePropertySet> styleFromMatchedRules = styleFro mMatchedRulesForElement(element, StyleResolver::AllButEmptyCSSRules); |
1199 if (styleFromMatchedRules && !styleFromMatchedRules->isEmpty()) | 1203 if (styleFromMatchedRules && !styleFromMatchedRules->isEmpty()) |
1200 m_mutableStyle = getPropertiesNotIn(m_mutableStyle.get(), styleFromMatch edRules->ensureCSSStyleDeclaration()); | 1204 m_mutableStyle = getPropertiesNotIn(m_mutableStyle.get(), styleFromMatch edRules->ensureCSSStyleDeclaration()); |
1201 | 1205 |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1350 | 1354 |
1351 // The selection is either a caret with no typing attributes or a range in w hich no embedding is added, so just use the start position | 1355 // The selection is either a caret with no typing attributes or a range in w hich no embedding is added, so just use the start position |
1352 // to decide. | 1356 // to decide. |
1353 Node* block = enclosingBlock(node); | 1357 Node* block = enclosingBlock(node); |
1354 WritingDirection foundDirection = NaturalWritingDirection; | 1358 WritingDirection foundDirection = NaturalWritingDirection; |
1355 | 1359 |
1356 for (; node != block; node = node->parentNode()) { | 1360 for (; node != block; node = node->parentNode()) { |
1357 if (!node->isStyledElement()) | 1361 if (!node->isStyledElement()) |
1358 continue; | 1362 continue; |
1359 | 1363 |
1360 RefPtrWillBeRawPtr<CSSComputedStyleDeclaration> style = CSSComputedStyle Declaration::create(node); | 1364 Element* element = toElement(node); |
1365 RefPtrWillBeRawPtr<CSSComputedStyleDeclaration> style = CSSComputedStyle Declaration::create(element); | |
1361 RefPtrWillBeRawPtr<CSSValue> unicodeBidi = style->getPropertyCSSValue(CS SPropertyUnicodeBidi); | 1366 RefPtrWillBeRawPtr<CSSValue> unicodeBidi = style->getPropertyCSSValue(CS SPropertyUnicodeBidi); |
1362 if (!unicodeBidi || !unicodeBidi->isPrimitiveValue()) | 1367 if (!unicodeBidi || !unicodeBidi->isPrimitiveValue()) |
1363 continue; | 1368 continue; |
1364 | 1369 |
1365 CSSValueID unicodeBidiValue = toCSSPrimitiveValue(unicodeBidi.get())->ge tValueID(); | 1370 CSSValueID unicodeBidiValue = toCSSPrimitiveValue(unicodeBidi.get())->ge tValueID(); |
1366 if (unicodeBidiValue == CSSValueNormal) | 1371 if (unicodeBidiValue == CSSValueNormal) |
1367 continue; | 1372 continue; |
1368 | 1373 |
1369 if (unicodeBidiValue == CSSValueBidiOverride) | 1374 if (unicodeBidiValue == CSSValueBidiOverride) |
1370 return NaturalWritingDirection; | 1375 return NaturalWritingDirection; |
1371 | 1376 |
1372 ASSERT(unicodeBidiValue == CSSValueEmbed); | 1377 ASSERT(unicodeBidiValue == CSSValueEmbed); |
1373 RefPtrWillBeRawPtr<CSSValue> direction = style->getPropertyCSSValue(CSSP ropertyDirection); | 1378 RefPtrWillBeRawPtr<CSSValue> direction = style->getPropertyCSSValue(CSSP ropertyDirection); |
1374 if (!direction || !direction->isPrimitiveValue()) | 1379 if (!direction || !direction->isPrimitiveValue()) |
1375 continue; | 1380 continue; |
1376 | 1381 |
1377 int directionValue = toCSSPrimitiveValue(direction.get())->getValueID(); | 1382 int directionValue = toCSSPrimitiveValue(direction.get())->getValueID(); |
1378 if (directionValue != CSSValueLtr && directionValue != CSSValueRtl) | 1383 if (directionValue != CSSValueLtr && directionValue != CSSValueRtl) |
1379 continue; | 1384 continue; |
1380 | 1385 |
1381 if (foundDirection != NaturalWritingDirection) | 1386 if (foundDirection != NaturalWritingDirection) |
1382 return NaturalWritingDirection; | 1387 return NaturalWritingDirection; |
1383 | 1388 |
1384 // In the range case, make sure that the embedding element persists unti l the end of the range. | 1389 // In the range case, make sure that the embedding element persists unti l the end of the range. |
1385 if (selection.isRange() && !end.deprecatedNode()->isDescendantOf(node)) | 1390 if (selection.isRange() && !end.deprecatedNode()->isDescendantOf(element )) |
1386 return NaturalWritingDirection; | 1391 return NaturalWritingDirection; |
1387 | 1392 |
1388 foundDirection = directionValue == CSSValueLtr ? LeftToRightWritingDirec tion : RightToLeftWritingDirection; | 1393 foundDirection = directionValue == CSSValueLtr ? LeftToRightWritingDirec tion : RightToLeftWritingDirection; |
1389 } | 1394 } |
1390 hasNestedOrMultipleEmbeddings = false; | 1395 hasNestedOrMultipleEmbeddings = false; |
1391 return foundDirection; | 1396 return foundDirection; |
1392 } | 1397 } |
1393 | 1398 |
1394 void EditingStyle::trace(Visitor* visitor) | 1399 void EditingStyle::trace(Visitor* visitor) |
1395 { | 1400 { |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1676 { | 1681 { |
1677 for (Node* ancestor = node; ancestor; ancestor = ancestor->parentNode()) { | 1682 for (Node* ancestor = node; ancestor; ancestor = ancestor->parentNode()) { |
1678 RefPtrWillBeRawPtr<CSSComputedStyleDeclaration> ancestorStyle = CSSCompu tedStyleDeclaration::create(ancestor); | 1683 RefPtrWillBeRawPtr<CSSComputedStyleDeclaration> ancestorStyle = CSSCompu tedStyleDeclaration::create(ancestor); |
1679 if (!hasTransparentBackgroundColor(ancestorStyle.get())) | 1684 if (!hasTransparentBackgroundColor(ancestorStyle.get())) |
1680 return ancestorStyle->getPropertyCSSValue(CSSPropertyBackgroundColor ); | 1685 return ancestorStyle->getPropertyCSSValue(CSSPropertyBackgroundColor ); |
1681 } | 1686 } |
1682 return nullptr; | 1687 return nullptr; |
1683 } | 1688 } |
1684 | 1689 |
1685 } | 1690 } |
OLD | NEW |