Changeset 81092 in webkit
- Timestamp:
- Mar 14, 2011 6:19:14 PM (13 years ago)
- Location:
- trunk
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r81091 r81092 1 2011-03-14 Anton Muhin <antonm@chromium.org> 2 3 Reviewed by Adam Barth. 4 5 [v8] Rework object group building. 6 https://bugs.webkit.org/show_bug.cgi?id=55399 7 8 Instead of going top-down (from owner to owned elements), go up---from objects 9 to their group ids. That fits better to v8's object grouping model and guarantees 10 that each wrapper belongs to the single group. 11 12 Alas, this cannot be implemented for one kind of objects---CSSProperties. 13 14 Part of core GC algorithm and tested extensively by exisiting layout tests. 15 16 * platform/chromium/test_expectations.txt: Temporary suppress text differences. 17 1 18 2011-03-14 Ryosuke Niwa <rniwa@webkit.org> 2 19 -
trunk/LayoutTests/platform/chromium/test_expectations.txt
r81083 r81092 3391 3391 BUGCR75639 MAC LEOPARD : fast/canvas/webgl/uninitialized-test.html = TIMEOUT 3392 3392 3393 // I (antonm) am working on proper fix for it. Temporary suppressing text differences. 3394 BUGWK55399 : fast/dom/StyleSheet/gc-inline-style-cssvalues.html = TEXT 3395 3393 3396 // Test changed in Wk r80743, throws an exception rather than returning 'true' 3394 3397 BUGCR75740 : fast/js/regexp-test-null-string.html = FAIL -
trunk/Source/WebCore/ChangeLog
r81088 r81092 1 2011-03-14 Anton Muhin <antonm@chromium.org> 2 3 Reviewed by Adam Barth. 4 5 [v8] Rework object group building. 6 https://bugs.webkit.org/show_bug.cgi?id=55399 7 8 Instead of going top-down (from owner to owned elements), go up---from objects 9 to their group ids. That fits better to v8's object grouping model and guarantees 10 that each wrapper belongs to the single group. 11 12 Alas, this cannot be implemented for one kind of objects---CSSProperties. 13 14 Part of core GC algorithm and tested extensively by exisiting layout tests. 15 16 * bindings/scripts/CodeGeneratorV8.pm: 17 * bindings/scripts/test/V8/V8TestInterface.cpp: 18 * bindings/scripts/test/V8/V8TestMediaQueryListListener.cpp: 19 * bindings/scripts/test/V8/V8TestObj.cpp: 20 * bindings/v8/V8GCController.cpp: 21 (WebCore::calculateGroupId): 22 (WebCore::calculateRootStyleSheet): 23 (WebCore::GrouperVisitor::visitDOMWrapper): 24 (WebCore::GrouperVisitor::applyGrouping): 25 (WebCore::V8GCController::gcPrologue): 26 * bindings/v8/WrapperTypeInfo.h: 27 (WebCore::WrapperTypeInfo::isSubclass): 28 * css/CSSRuleList.h: 29 (WebCore::CSSRuleList::styleList): 30 * css/StyleSheetList.h: 31 (WebCore::StyleSheetList::document): 32 1 33 2011-03-14 Kent Tamura <tkent@chromium.org> 2 34 -
trunk/Source/WebCore/bindings/scripts/CodeGeneratorV8.pm
r80536 r81092 1717 1717 my $toActive = IsActiveDomType($interfaceName) ? "${className}::toActiveDOMObject" : "0"; 1718 1718 1719 # Find the super descriptor. 1720 my $parentClass = ""; 1721 my $parentClassTemplate = ""; 1722 foreach (@{$dataNode->parents}) { 1723 my $parent = $codeGenerator->StripModule($_); 1724 if ($parent eq "EventTarget") { 1725 next; 1726 } 1727 $implIncludes{"V8${parent}.h"} = 1; 1728 $parentClass = "V8" . $parent; 1729 $parentClassTemplate = $parentClass . "::GetTemplate()"; 1730 last; 1731 } 1719 1732 push(@implContentDecls, "namespace WebCore {\n\n"); 1720 push(@implContentDecls, "WrapperTypeInfo ${className}::info = { ${className}::GetTemplate, ${className}::derefObject, ${toActive} };\n\n"); 1733 my $parentClassInfo = $parentClass ? "&${parentClass}::info" : "0"; 1734 push(@implContentDecls, "WrapperTypeInfo ${className}::info = { ${className}::GetTemplate, ${className}::derefObject, ${toActive}, ${parentClassInfo} };\n\n"); 1721 1735 push(@implContentDecls, "namespace ${interfaceName}Internal {\n\n"); 1722 1736 push(@implContentDecls, "template <typename T> void V8_USE(T) { }\n\n"); … … 1942 1956 } 1943 1957 1944 # find the super descriptor1945 my $parentClassTemplate = "";1946 foreach (@{$dataNode->parents}) {1947 my $parent = $codeGenerator->StripModule($_);1948 if ($parent eq "EventTarget") { next; }1949 $implIncludes{"V8${parent}.h"} = 1;1950 $parentClassTemplate = "V8" . $parent . "::GetTemplate()";1951 last;1952 }1953 1958 if (!$parentClassTemplate) { 1954 1959 $parentClassTemplate = "v8::Persistent<v8::FunctionTemplate>()"; -
trunk/Source/WebCore/bindings/scripts/test/V8/V8TestInterface.cpp
r80072 r81092 34 34 namespace WebCore { 35 35 36 WrapperTypeInfo V8TestInterface::info = { V8TestInterface::GetTemplate, V8TestInterface::derefObject, 0 };36 WrapperTypeInfo V8TestInterface::info = { V8TestInterface::GetTemplate, V8TestInterface::derefObject, 0, 0 }; 37 37 38 38 namespace TestInterfaceInternal { -
trunk/Source/WebCore/bindings/scripts/test/V8/V8TestMediaQueryListListener.cpp
r72728 r81092 34 34 namespace WebCore { 35 35 36 WrapperTypeInfo V8TestMediaQueryListListener::info = { V8TestMediaQueryListListener::GetTemplate, V8TestMediaQueryListListener::derefObject, 0 };36 WrapperTypeInfo V8TestMediaQueryListListener::info = { V8TestMediaQueryListListener::GetTemplate, V8TestMediaQueryListListener::derefObject, 0, 0 }; 37 37 38 38 namespace TestMediaQueryListListenerInternal { -
trunk/Source/WebCore/bindings/scripts/test/V8/V8TestObj.cpp
r76277 r81092 47 47 namespace WebCore { 48 48 49 WrapperTypeInfo V8TestObj::info = { V8TestObj::GetTemplate, V8TestObj::derefObject, 0 };49 WrapperTypeInfo V8TestObj::info = { V8TestObj::GetTemplate, V8TestObj::derefObject, 0, 0 }; 50 50 51 51 namespace TestObjInternal { -
trunk/Source/WebCore/bindings/v8/V8GCController.cpp
r80842 r81092 35 35 #include "Attr.h" 36 36 #include "DOMDataStore.h" 37 #include " Frame.h"37 #include "DOMImplementation.h" 38 38 #include "HTMLImageElement.h" 39 39 #include "HTMLNames.h" 40 40 #include "MessagePort.h" 41 41 #include "PlatformBridge.h" 42 #include "SVGElement.h"43 42 #include "V8Binding.h" 44 #include "V8CSSCharsetRule.h" 45 #include "V8CSSFontFaceRule.h" 46 #include "V8CSSImportRule.h" 47 #include "V8CSSMediaRule.h" 43 #include "V8CSSRule.h" 48 44 #include "V8CSSRuleList.h" 49 45 #include "V8CSSStyleDeclaration.h" 50 #include "V8CSSStyleRule.h" 51 #include "V8CSSStyleSheet.h" 52 #include "V8DOMMap.h" 53 #include "V8HTMLLinkElement.h" 54 #include "V8HTMLStyleElement.h" 46 #include "V8DOMImplementation.h" 55 47 #include "V8MessagePort.h" 56 #include "V8ProcessingInstruction.h" 57 #include "V8Proxy.h" 48 #include "V8StyleSheet.h" 58 49 #include "V8StyleSheetList.h" 59 50 #include "WrapperTypeInfo.h" … … 199 190 typedef Vector<GrouperItem> GrouperList; 200 191 201 void makeV8ObjectGroups(GrouperList& grouper) 202 { 203 // Group by sorting by the group id. 204 std::sort(grouper.begin(), grouper.end()); 205 206 // FIXME Should probably work in iterators here, but indexes were easier for my simple mind. 207 for (size_t i = 0; i < grouper.size(); ) { 208 // Seek to the next key (or the end of the list). 209 size_t nextKeyIndex = grouper.size(); 210 for (size_t j = i; j < grouper.size(); ++j) { 211 if (grouper[i].groupId() != grouper[j].groupId()) { 212 nextKeyIndex = j; 213 break; 214 } 215 } 216 217 ASSERT(nextKeyIndex > i); 218 219 // We only care about a group if it has more than one object. If it only 220 // has one object, it has nothing else that needs to be kept alive. 221 if (nextKeyIndex - i <= 1) { 222 i = nextKeyIndex; 223 continue; 224 } 225 226 Vector<v8::Persistent<v8::Value> > group; 227 group.reserveCapacity(nextKeyIndex - i); 228 for (; i < nextKeyIndex; ++i) { 229 v8::Persistent<v8::Value> wrapper = grouper[i].wrapper(); 230 if (!wrapper.IsEmpty()) 231 group.append(wrapper); 232 } 233 234 if (group.size() > 1) 235 v8::V8::AddObjectGroup(&group[0], group.size()); 236 237 ASSERT(i == nextKeyIndex); 238 } 239 } 240 241 class NodeGrouperVisitor : public DOMWrapperMap<Node>::Visitor { 242 public: 243 NodeGrouperVisitor() 244 { 245 // FIXME: grouper_.reserveCapacity(node_map.size()); ? 246 } 247 248 void visitDOMWrapper(DOMDataStore* store, Node* node, v8::Persistent<v8::Object> wrapper) 249 { 250 // If the node is in document, put it in the ownerDocument's object group. 251 // 252 // If an image element was created by JavaScript "new Image", 253 // it is not in a document. However, if the load event has not 254 // been fired (still onloading), it is treated as in the document. 255 // 256 // Otherwise, the node is put in an object group identified by the root 257 // element of the tree to which it belongs. 258 uintptr_t groupId; 259 if (node->inDocument() || (node->hasTagName(HTMLNames::imgTag) && !static_cast<HTMLImageElement*>(node)->haveFiredLoadEvent())) 260 groupId = reinterpret_cast<uintptr_t>(node->document()); 261 else { 262 Node* root = node; 263 if (node->isAttributeNode()) { 264 root = static_cast<Attr*>(node)->ownerElement(); 265 // If the attribute has no element, no need to put it in the group, 266 // because it'll always be a group of 1. 267 if (!root) 268 return; 269 } else { 270 while (root->parentNode()) 271 root = root->parentNode(); 272 273 // If the node is alone in its DOM tree (doesn't have a parent or any 274 // children) then the group will be filtered out later anyway. 275 if (root == node && !node->hasChildNodes() && !node->hasAttributes()) 276 return; 277 } 278 groupId = reinterpret_cast<uintptr_t>(root); 279 } 280 m_grouper.append(GrouperItem(groupId, wrapper)); 281 282 // If the node is styled and there is a wrapper for the inline 283 // style declaration, we need to keep that style declaration 284 // wrapper alive as well, so we add it to the object group. 285 if (node->isStyledElement()) { 286 StyledElement* element = reinterpret_cast<StyledElement*>(node); 287 addDOMObjectToGroup(store, groupId, element->inlineStyleDecl()); 288 } 289 290 if (node->isDocumentNode()) { 291 Document* document = reinterpret_cast<Document*>(node); 292 addDOMObjectToGroup(store, groupId, document->styleSheets()); 293 addDOMObjectToGroup(store, groupId, document->implementation()); 294 } 295 296 WrapperTypeInfo* typeInfo = V8DOMWrapper::domWrapperType(wrapper); 297 298 if (V8HTMLLinkElement::info.equals(typeInfo)) { 299 HTMLLinkElement* htmlLinkElement = static_cast<HTMLLinkElement*>(node); 300 addDOMObjectToGroup(store, groupId, htmlLinkElement->sheet()); 301 } 302 303 if (V8HTMLStyleElement::info.equals(typeInfo)) { 304 HTMLStyleElement* htmlStyleElement = static_cast<HTMLStyleElement*>(node); 305 addDOMObjectToGroup(store, groupId, htmlStyleElement->sheet()); 306 } 307 308 if (V8ProcessingInstruction::info.equals(typeInfo)) { 309 ProcessingInstruction* processingInstruction = static_cast<ProcessingInstruction*>(node); 310 addDOMObjectToGroup(store, groupId, processingInstruction->sheet()); 311 } 312 } 313 314 void applyGrouping() 315 { 316 makeV8ObjectGroups(m_grouper); 317 } 318 319 private: 320 GrouperList m_grouper; 321 322 void addDOMObjectToGroup(DOMDataStore* store, uintptr_t groupId, void* object) 323 { 324 if (!object) 325 return; 326 v8::Persistent<v8::Object> wrapper = store->domObjectMap().get(object); 327 if (!wrapper.IsEmpty()) 328 m_grouper.append(GrouperItem(groupId, wrapper)); 329 } 330 }; 192 // If the node is in document, put it in the ownerDocument's object group. 193 // 194 // If an image element was created by JavaScript "new Image", 195 // it is not in a document. However, if the load event has not 196 // been fired (still onloading), it is treated as in the document. 197 // 198 // Otherwise, the node is put in an object group identified by the root 199 // element of the tree to which it belongs. 200 static uintptr_t calculateGroupId(Node* node) 201 { 202 if (node->inDocument() || (node->hasTagName(HTMLNames::imgTag) && !static_cast<HTMLImageElement*>(node)->haveFiredLoadEvent())) 203 return reinterpret_cast<uintptr_t>(node->document()); 204 205 Node* root = node; 206 if (node->isAttributeNode()) { 207 root = static_cast<Attr*>(node)->ownerElement(); 208 // If the attribute has no element, no need to put it in the group, 209 // because it'll always be a group of 1. 210 if (!root) 211 return 0; 212 } else { 213 while (Node* parent = root->parentNode()) 214 root = parent; 215 } 216 217 return reinterpret_cast<uintptr_t>(root); 218 } 331 219 332 220 static uintptr_t calculateGroupId(StyleBase* styleBase) … … 336 224 StyleSheet* styleSheet = 0; 337 225 while (true) { 338 // Special case: CSSStyleDeclarations should have CSSRule as a parent 339 // to proceed with parent traversal, otherwise they are coming from 340 // inlined style declaration and should be treated as a root. 226 // Special case: CSSStyleDeclarations might be either inline and in this case 227 // we need to group them with their node or regular ones. 341 228 if (current->isMutableStyleDeclaration()) { 342 229 CSSMutableStyleDeclaration* cssMutableStyleDeclaration = static_cast<CSSMutableStyleDeclaration*>(current); 343 if (CSSRule* parentRule = cssMutableStyleDeclaration->parentRule()) 344 current = parentRule; 345 else 346 return reinterpret_cast<uintptr_t>(cssMutableStyleDeclaration); 230 if (cssMutableStyleDeclaration->isInlineStyleDeclaration()) { 231 ASSERT(cssMutableStyleDeclaration->parent()->isStyleSheet()); 232 return calculateGroupId(cssMutableStyleDeclaration->node()); 233 } 234 // Either we have no parent, or this parent is a CSSRule. 235 ASSERT(cssMutableStyleDeclaration->parent() == cssMutableStyleDeclaration->parentRule()); 347 236 } 348 237 … … 356 245 } 357 246 358 if (styleSheet) 247 if (styleSheet) { 248 if (Node* ownerNode = styleSheet->ownerNode()) 249 return calculateGroupId(ownerNode); 359 250 return reinterpret_cast<uintptr_t>(styleSheet); 251 } 360 252 361 253 return reinterpret_cast<uintptr_t>(current); 362 254 } 363 255 364 class DOMObjectGrouperVisitor : public DOMWrapperMap<void>::Visitor { 365 public: 366 DOMObjectGrouperVisitor() 367 { 368 } 369 370 void startMap() 371 { 372 m_grouper.shrink(0); 373 } 374 375 void endMap() 376 { 377 makeV8ObjectGroups(m_grouper); 256 class GrouperVisitor : public DOMWrapperMap<Node>::Visitor, public DOMWrapperMap<void>::Visitor { 257 public: 258 void visitDOMWrapper(DOMDataStore* store, Node* node, v8::Persistent<v8::Object> wrapper) 259 { 260 uintptr_t groupId = calculateGroupId(node); 261 if (!groupId) 262 return; 263 m_grouper.append(GrouperItem(groupId, wrapper)); 378 264 } 379 265 … … 381 267 { 382 268 WrapperTypeInfo* typeInfo = V8DOMWrapper::domWrapperType(wrapper); 383 // FIXME: extend WrapperTypeInfo with isStyle to simplify the check below or consider 384 // adding a virtual method to WrapperTypeInfo which would know how to group objects. 385 // FIXME: check if there are other StyleBase wrappers we should care of. 386 if (V8CSSStyleSheet::info.equals(typeInfo) 387 || V8CSSStyleDeclaration::info.equals(typeInfo) 388 || V8CSSCharsetRule::info.equals(typeInfo) 389 || V8CSSFontFaceRule::info.equals(typeInfo) 390 || V8CSSStyleRule::info.equals(typeInfo) 391 || V8CSSImportRule::info.equals(typeInfo) 392 || V8CSSMediaRule::info.equals(typeInfo)) { 393 StyleBase* styleBase = static_cast<StyleBase*>(object); 394 395 uintptr_t groupId = calculateGroupId(styleBase); 269 270 if (typeInfo->isSubclass(&V8StyleSheetList::info)) { 271 StyleSheetList* styleSheetList = static_cast<StyleSheetList*>(object); 272 uintptr_t groupId = reinterpret_cast<uintptr_t>(styleSheetList); 273 if (Document* document = styleSheetList->document()) 274 groupId = reinterpret_cast<uintptr_t>(document); 396 275 m_grouper.append(GrouperItem(groupId, wrapper)); 397 276 398 if (V8CSSStyleDeclaration::info.equals(typeInfo)) { 399 CSSStyleDeclaration* cssStyleDeclaration = static_cast<CSSStyleDeclaration*>(styleBase); 400 if (cssStyleDeclaration->isMutableStyleDeclaration()) { 401 CSSMutableStyleDeclaration* cssMutableStyleDeclaration = static_cast<CSSMutableStyleDeclaration*>(cssStyleDeclaration); 402 CSSMutableStyleDeclaration::const_iterator end = cssMutableStyleDeclaration->end(); 403 for (CSSMutableStyleDeclaration::const_iterator it = cssMutableStyleDeclaration->begin(); it != end; ++it) { 404 wrapper = store->domObjectMap().get(it->value()); 405 if (!wrapper.IsEmpty()) 406 m_grouper.append(GrouperItem(groupId, wrapper)); 407 } 277 } else if (typeInfo->isSubclass(&V8DOMImplementation::info)) { 278 DOMImplementation* domImplementation = static_cast<DOMImplementation*>(object); 279 uintptr_t groupId = reinterpret_cast<uintptr_t>(domImplementation); 280 if (Document* document = domImplementation->ownerDocument()) 281 groupId = reinterpret_cast<uintptr_t>(document); 282 m_grouper.append(GrouperItem(groupId, wrapper)); 283 284 } else if (typeInfo->isSubclass(&V8StyleSheet::info) || typeInfo->isSubclass(&V8CSSRule::info)) { 285 m_grouper.append(GrouperItem(calculateGroupId(static_cast<StyleBase*>(object)), wrapper)); 286 287 } else if (typeInfo->isSubclass(&V8CSSStyleDeclaration::info)) { 288 CSSStyleDeclaration* cssStyleDeclaration = static_cast<CSSStyleDeclaration*>(object); 289 290 uintptr_t groupId = calculateGroupId(cssStyleDeclaration); 291 m_grouper.append(GrouperItem(groupId, wrapper)); 292 293 } else if (typeInfo->isSubclass(&V8CSSRuleList::info)) { 294 CSSRuleList* cssRuleList = static_cast<CSSRuleList*>(object); 295 uintptr_t groupId = reinterpret_cast<uintptr_t>(cssRuleList); 296 StyleList* styleList = cssRuleList->styleList(); 297 if (styleList) 298 groupId = calculateGroupId(styleList); 299 m_grouper.append(GrouperItem(groupId, wrapper)); 300 } 301 } 302 303 void applyGrouping() 304 { 305 // Group by sorting by the group id. 306 std::sort(m_grouper.begin(), m_grouper.end()); 307 308 for (size_t i = 0; i < m_grouper.size(); ) { 309 // Seek to the next key (or the end of the list). 310 size_t nextKeyIndex = m_grouper.size(); 311 for (size_t j = i; j < m_grouper.size(); ++j) { 312 if (m_grouper[i].groupId() != m_grouper[j].groupId()) { 313 nextKeyIndex = j; 314 break; 408 315 } 409 316 } 410 } else if (V8StyleSheetList::info.equals(typeInfo)) { 411 addAllItems(store, static_cast<StyleSheetList*>(object), wrapper); 412 } else if (V8CSSRuleList::info.equals(typeInfo)) { 413 addAllItems(store, static_cast<CSSRuleList*>(object), wrapper); 317 318 ASSERT(nextKeyIndex > i); 319 320 // We only care about a group if it has more than one object. If it only 321 // has one object, it has nothing else that needs to be kept alive. 322 if (nextKeyIndex - i <= 1) { 323 i = nextKeyIndex; 324 continue; 325 } 326 327 Vector<v8::Persistent<v8::Value> > group; 328 group.reserveCapacity(nextKeyIndex - i); 329 for (; i < nextKeyIndex; ++i) { 330 v8::Persistent<v8::Value> wrapper = m_grouper[i].wrapper(); 331 if (!wrapper.IsEmpty()) 332 group.append(wrapper); 333 } 334 335 if (group.size() > 1) 336 v8::V8::AddObjectGroup(&group[0], group.size()); 337 338 ASSERT(i == nextKeyIndex); 414 339 } 415 340 } … … 417 342 private: 418 343 GrouperList m_grouper; 419 420 template <class C>421 void addAllItems(DOMDataStore* store, C* collection, v8::Persistent<v8::Object> wrapper)422 {423 uintptr_t groupId = reinterpret_cast<uintptr_t>(collection);424 m_grouper.append(GrouperItem(groupId, wrapper));425 for (unsigned i = 0; i < collection->length(); i++) {426 wrapper = store->domObjectMap().get(collection->item(i));427 if (!wrapper.IsEmpty())428 m_grouper.append(GrouperItem(groupId, wrapper));429 }430 }431 344 }; 432 345 … … 447 360 448 361 // Create object groups. 449 NodeGrouperVisitor nodeGrouperVisitor; 450 visitDOMNodesInCurrentThread(&nodeGrouperVisitor); 451 nodeGrouperVisitor.applyGrouping(); 452 453 DOMObjectGrouperVisitor domObjectGrouperVisitor; 454 visitDOMObjectsInCurrentThread(&domObjectGrouperVisitor); 362 GrouperVisitor grouperVisitor; 363 visitDOMNodesInCurrentThread(&grouperVisitor); 364 visitDOMObjectsInCurrentThread(&grouperVisitor); 365 grouperVisitor.applyGrouping(); 455 366 456 367 // Clean single element cache for string conversions. -
trunk/Source/WebCore/bindings/v8/WrapperTypeInfo.h
r57004 r81092 62 62 return this == that; 63 63 } 64 65 bool isSubclass(const WrapperTypeInfo* that) const 66 { 67 for (const WrapperTypeInfo* current = this; current; current = current->parentClass) { 68 if (current == that) 69 return true; 70 } 71 72 return false; 73 } 64 74 65 75 v8::Persistent<v8::FunctionTemplate> getTemplate() { return getTemplateFunction(); } … … 81 91 const DerefObjectFunction derefObjectFunction; 82 92 const ToActiveDOMObjectFunction toActiveDOMObjectFunction; 93 const WrapperTypeInfo* parentClass; 83 94 }; 84 95 } -
trunk/Source/WebCore/css/CSSMutableStyleDeclaration.cpp
r80963 r81092 499 499 } 500 500 501 bool CSSMutableStyleDeclaration::isInlineStyleDeclaration() 502 { 503 // FIXME: Ideally, this should be factored better and there 504 // should be a subclass of CSSMutableStyleDeclaration just 505 // for inline style declarations that handles this 506 return m_node && m_node->isStyledElement() && static_cast<StyledElement*>(m_node)->inlineStyleDecl() == this; 507 } 508 501 509 void CSSMutableStyleDeclaration::setNeedsStyleRecalc() 502 510 { 503 511 if (m_node) { 504 // FIXME: Ideally, this should be factored better and there 505 // should be a subclass of CSSMutableStyleDeclaration just 506 // for inline style declarations that handles this 507 bool isInlineStyleDeclaration = m_node->isStyledElement() && this == static_cast<StyledElement*>(m_node)->inlineStyleDecl(); 508 if (isInlineStyleDeclaration) { 512 if (isInlineStyleDeclaration()) { 509 513 m_node->setNeedsStyleRecalc(InlineStyleChange); 510 514 static_cast<StyledElement*>(m_node)->invalidateStyleAttribute(); -
trunk/Source/WebCore/css/CSSMutableStyleDeclaration.h
r80620 r81092 141 141 bool propertiesEqual(const CSSMutableStyleDeclaration* o) const { return m_properties == o->m_properties; } 142 142 143 bool isInlineStyleDeclaration(); 144 143 145 protected: 144 146 CSSMutableStyleDeclaration(CSSRule* parentRule); -
trunk/Source/WebCore/css/CSSRuleList.h
r50583 r81092 54 54 void append(CSSRule*); 55 55 56 StyleList* styleList() 57 { 58 return m_list.get(); 59 } 60 56 61 private: 57 62 CSSRuleList(); -
trunk/Source/WebCore/css/StyleSheetList.h
r65021 r81092 51 51 m_sheets.swap(sheets); 52 52 } 53 54 Document* document() 55 { 56 return m_doc; 57 } 53 58 54 59 private:
Note: See TracChangeset
for help on using the changeset viewer.