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

Side by Side Diff: Source/core/inspector/DOMPatchSupport.cpp

Issue 72363002: Rename es => exceptionState in other than bindings/ (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Retry Created 7 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 | Annotate | Revision Log
« no previous file with comments | « Source/core/inspector/DOMEditor.cpp ('k') | Source/core/inspector/InspectorCSSAgent.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2012 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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 OwnPtr<Digest> oldInfo = createDigest(m_document.documentElement(), 0); 106 OwnPtr<Digest> oldInfo = createDigest(m_document.documentElement(), 0);
107 OwnPtr<Digest> newInfo = createDigest(newDocument->documentElement(), &m_unu sedNodesMap); 107 OwnPtr<Digest> newInfo = createDigest(newDocument->documentElement(), &m_unu sedNodesMap);
108 108
109 if (!innerPatchNode(oldInfo.get(), newInfo.get(), IGNORE_EXCEPTION)) { 109 if (!innerPatchNode(oldInfo.get(), newInfo.get(), IGNORE_EXCEPTION)) {
110 // Fall back to rewrite. 110 // Fall back to rewrite.
111 m_document.write(markup); 111 m_document.write(markup);
112 m_document.close(); 112 m_document.close();
113 } 113 }
114 } 114 }
115 115
116 Node* DOMPatchSupport::patchNode(Node* node, const String& markup, ExceptionStat e& es) 116 Node* DOMPatchSupport::patchNode(Node* node, const String& markup, ExceptionStat e& exceptionState)
117 { 117 {
118 // Don't parse <html> as a fragment. 118 // Don't parse <html> as a fragment.
119 if (node->isDocumentNode() || (node->parentNode() && node->parentNode()->isD ocumentNode())) { 119 if (node->isDocumentNode() || (node->parentNode() && node->parentNode()->isD ocumentNode())) {
120 patchDocument(markup); 120 patchDocument(markup);
121 return 0; 121 return 0;
122 } 122 }
123 123
124 Node* previousSibling = node->previousSibling(); 124 Node* previousSibling = node->previousSibling();
125 // FIXME: This code should use one of createFragment* in markup.h 125 // FIXME: This code should use one of createFragment* in markup.h
126 RefPtr<DocumentFragment> fragment = DocumentFragment::create(m_document); 126 RefPtr<DocumentFragment> fragment = DocumentFragment::create(m_document);
(...skipping 16 matching lines...) Expand all
143 for (Node* child = fragment->firstChild(); child; child = child->nextSibling ()) { 143 for (Node* child = fragment->firstChild(); child; child = child->nextSibling ()) {
144 if (child->hasTagName(headTag) && !child->firstChild() && markupCopy.fin d("</head>") == kNotFound) 144 if (child->hasTagName(headTag) && !child->firstChild() && markupCopy.fin d("</head>") == kNotFound)
145 continue; // HTML5 parser inserts empty <head> tag whenever it parse s <body> 145 continue; // HTML5 parser inserts empty <head> tag whenever it parse s <body>
146 if (child->hasTagName(bodyTag) && !child->firstChild() && markupCopy.fin d("</body>") == kNotFound) 146 if (child->hasTagName(bodyTag) && !child->firstChild() && markupCopy.fin d("</body>") == kNotFound)
147 continue; // HTML5 parser inserts empty <body> tag whenever it parse s </head> 147 continue; // HTML5 parser inserts empty <body> tag whenever it parse s </head>
148 newList.append(createDigest(child, &m_unusedNodesMap)); 148 newList.append(createDigest(child, &m_unusedNodesMap));
149 } 149 }
150 for (Node* child = node->nextSibling(); child; child = child->nextSibling()) 150 for (Node* child = node->nextSibling(); child; child = child->nextSibling())
151 newList.append(createDigest(child, 0)); 151 newList.append(createDigest(child, 0));
152 152
153 if (!innerPatchChildren(parentNode, oldList, newList, es)) { 153 if (!innerPatchChildren(parentNode, oldList, newList, exceptionState)) {
154 // Fall back to total replace. 154 // Fall back to total replace.
155 if (!m_domEditor->replaceChild(parentNode, fragment.release(), node, es) ) 155 if (!m_domEditor->replaceChild(parentNode, fragment.release(), node, exc eptionState))
156 return 0; 156 return 0;
157 } 157 }
158 return previousSibling ? previousSibling->nextSibling() : parentNode->firstC hild(); 158 return previousSibling ? previousSibling->nextSibling() : parentNode->firstC hild();
159 } 159 }
160 160
161 bool DOMPatchSupport::innerPatchNode(Digest* oldDigest, Digest* newDigest, Excep tionState& es) 161 bool DOMPatchSupport::innerPatchNode(Digest* oldDigest, Digest* newDigest, Excep tionState& exceptionState)
162 { 162 {
163 if (oldDigest->m_sha1 == newDigest->m_sha1) 163 if (oldDigest->m_sha1 == newDigest->m_sha1)
164 return true; 164 return true;
165 165
166 Node* oldNode = oldDigest->m_node; 166 Node* oldNode = oldDigest->m_node;
167 Node* newNode = newDigest->m_node; 167 Node* newNode = newDigest->m_node;
168 168
169 if (newNode->nodeType() != oldNode->nodeType() || newNode->nodeName() != old Node->nodeName()) 169 if (newNode->nodeType() != oldNode->nodeType() || newNode->nodeName() != old Node->nodeName())
170 return m_domEditor->replaceChild(oldNode->parentNode(), newNode, oldNode , es); 170 return m_domEditor->replaceChild(oldNode->parentNode(), newNode, oldNode , exceptionState);
171 171
172 if (oldNode->nodeValue() != newNode->nodeValue()) { 172 if (oldNode->nodeValue() != newNode->nodeValue()) {
173 if (!m_domEditor->setNodeValue(oldNode, newNode->nodeValue(), es)) 173 if (!m_domEditor->setNodeValue(oldNode, newNode->nodeValue(), exceptionS tate))
174 return false; 174 return false;
175 } 175 }
176 176
177 if (oldNode->nodeType() != Node::ELEMENT_NODE) 177 if (oldNode->nodeType() != Node::ELEMENT_NODE)
178 return true; 178 return true;
179 179
180 // Patch attributes 180 // Patch attributes
181 Element* oldElement = toElement(oldNode); 181 Element* oldElement = toElement(oldNode);
182 Element* newElement = toElement(newNode); 182 Element* newElement = toElement(newNode);
183 if (oldDigest->m_attrsSHA1 != newDigest->m_attrsSHA1) { 183 if (oldDigest->m_attrsSHA1 != newDigest->m_attrsSHA1) {
184 // FIXME: Create a function in Element for removing all properties. Take in account whether did/willModifyAttribute are important. 184 // FIXME: Create a function in Element for removing all properties. Take in account whether did/willModifyAttribute are important.
185 if (oldElement->hasAttributesWithoutUpdate()) { 185 if (oldElement->hasAttributesWithoutUpdate()) {
186 while (oldElement->attributeCount()) { 186 while (oldElement->attributeCount()) {
187 const Attribute* attribute = oldElement->attributeItem(0); 187 const Attribute* attribute = oldElement->attributeItem(0);
188 if (!m_domEditor->removeAttribute(oldElement, attribute->localNa me(), es)) 188 if (!m_domEditor->removeAttribute(oldElement, attribute->localNa me(), exceptionState))
189 return false; 189 return false;
190 } 190 }
191 } 191 }
192 192
193 // FIXME: Create a function in Element for copying properties. cloneData FromElement() is close but not enough for this case. 193 // FIXME: Create a function in Element for copying properties. cloneData FromElement() is close but not enough for this case.
194 if (newElement->hasAttributesWithoutUpdate()) { 194 if (newElement->hasAttributesWithoutUpdate()) {
195 size_t numAttrs = newElement->attributeCount(); 195 size_t numAttrs = newElement->attributeCount();
196 for (size_t i = 0; i < numAttrs; ++i) { 196 for (size_t i = 0; i < numAttrs; ++i) {
197 const Attribute* attribute = newElement->attributeItem(i); 197 const Attribute* attribute = newElement->attributeItem(i);
198 if (!m_domEditor->setAttribute(oldElement, attribute->name().loc alName(), attribute->value(), es)) 198 if (!m_domEditor->setAttribute(oldElement, attribute->name().loc alName(), attribute->value(), exceptionState))
199 return false; 199 return false;
200 } 200 }
201 } 201 }
202 } 202 }
203 203
204 bool result = innerPatchChildren(oldElement, oldDigest->m_children, newDiges t->m_children, es); 204 bool result = innerPatchChildren(oldElement, oldDigest->m_children, newDiges t->m_children, exceptionState);
205 m_unusedNodesMap.remove(newDigest->m_sha1); 205 m_unusedNodesMap.remove(newDigest->m_sha1);
206 return result; 206 return result;
207 } 207 }
208 208
209 pair<DOMPatchSupport::ResultMap, DOMPatchSupport::ResultMap> 209 pair<DOMPatchSupport::ResultMap, DOMPatchSupport::ResultMap>
210 DOMPatchSupport::diff(const Vector<OwnPtr<Digest> >& oldList, const Vector<OwnPt r<Digest> >& newList) 210 DOMPatchSupport::diff(const Vector<OwnPtr<Digest> >& oldList, const Vector<OwnPt r<Digest> >& newList)
211 { 211 {
212 ResultMap newMap(newList.size()); 212 ResultMap newMap(newList.size());
213 ResultMap oldMap(oldList.size()); 213 ResultMap oldMap(oldList.size());
214 214
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 } 287 }
288 288
289 #ifdef DEBUG_DOM_PATCH_SUPPORT 289 #ifdef DEBUG_DOM_PATCH_SUPPORT
290 dumpMap(oldMap, "OLD"); 290 dumpMap(oldMap, "OLD");
291 dumpMap(newMap, "NEW"); 291 dumpMap(newMap, "NEW");
292 #endif 292 #endif
293 293
294 return make_pair(oldMap, newMap); 294 return make_pair(oldMap, newMap);
295 } 295 }
296 296
297 bool DOMPatchSupport::innerPatchChildren(ContainerNode* parentNode, const Vector <OwnPtr<Digest> >& oldList, const Vector<OwnPtr<Digest> >& newList, ExceptionSta te& es) 297 bool DOMPatchSupport::innerPatchChildren(ContainerNode* parentNode, const Vector <OwnPtr<Digest> >& oldList, const Vector<OwnPtr<Digest> >& newList, ExceptionSta te& exceptionState)
298 { 298 {
299 pair<ResultMap, ResultMap> resultMaps = diff(oldList, newList); 299 pair<ResultMap, ResultMap> resultMaps = diff(oldList, newList);
300 ResultMap& oldMap = resultMaps.first; 300 ResultMap& oldMap = resultMaps.first;
301 ResultMap& newMap = resultMaps.second; 301 ResultMap& newMap = resultMaps.second;
302 302
303 Digest* oldHead = 0; 303 Digest* oldHead = 0;
304 Digest* oldBody = 0; 304 Digest* oldBody = 0;
305 305
306 // 1. First strip everything except for the nodes that retain. Collect pendi ng merges. 306 // 1. First strip everything except for the nodes that retain. Collect pendi ng merges.
307 HashMap<Digest*, Digest*> merges; 307 HashMap<Digest*, Digest*> merges;
(...skipping 17 matching lines...) Expand all
325 continue; 325 continue;
326 } 326 }
327 327
328 // Check if this change is between stable nodes. If it is, consider it a s "modified". 328 // Check if this change is between stable nodes. If it is, consider it a s "modified".
329 if (!m_unusedNodesMap.contains(oldList[i]->m_sha1) && (!i || oldMap[i - 1].first) && (i == oldMap.size() - 1 || oldMap[i + 1].first)) { 329 if (!m_unusedNodesMap.contains(oldList[i]->m_sha1) && (!i || oldMap[i - 1].first) && (i == oldMap.size() - 1 || oldMap[i + 1].first)) {
330 size_t anchorCandidate = i ? oldMap[i - 1].second + 1 : 0; 330 size_t anchorCandidate = i ? oldMap[i - 1].second + 1 : 0;
331 size_t anchorAfter = (i == oldMap.size() - 1) ? anchorCandidate + 1 : oldMap[i + 1].second; 331 size_t anchorAfter = (i == oldMap.size() - 1) ? anchorCandidate + 1 : oldMap[i + 1].second;
332 if (anchorAfter - anchorCandidate == 1 && anchorCandidate < newList. size()) 332 if (anchorAfter - anchorCandidate == 1 && anchorCandidate < newList. size())
333 merges.set(newList[anchorCandidate].get(), oldList[i].get()); 333 merges.set(newList[anchorCandidate].get(), oldList[i].get());
334 else { 334 else {
335 if (!removeChildAndMoveToNew(oldList[i].get(), es)) 335 if (!removeChildAndMoveToNew(oldList[i].get(), exceptionState))
336 return false; 336 return false;
337 } 337 }
338 } else { 338 } else {
339 if (!removeChildAndMoveToNew(oldList[i].get(), es)) 339 if (!removeChildAndMoveToNew(oldList[i].get(), exceptionState))
340 return false; 340 return false;
341 } 341 }
342 } 342 }
343 343
344 // Mark retained nodes as used, do not reuse node more than once. 344 // Mark retained nodes as used, do not reuse node more than once.
345 HashSet<size_t, WTF::IntHash<size_t>, WTF::UnsignedWithZeroKeyHashTraits<siz e_t> > usedOldOrdinals; 345 HashSet<size_t, WTF::IntHash<size_t>, WTF::UnsignedWithZeroKeyHashTraits<siz e_t> > usedOldOrdinals;
346 for (size_t i = 0; i < newList.size(); ++i) { 346 for (size_t i = 0; i < newList.size(); ++i) {
347 if (!newMap[i].first) 347 if (!newMap[i].first)
348 continue; 348 continue;
349 size_t oldOrdinal = newMap[i].second; 349 size_t oldOrdinal = newMap[i].second;
(...skipping 12 matching lines...) Expand all
362 for (size_t i = 0; i < newList.size(); ++i) { 362 for (size_t i = 0; i < newList.size(); ++i) {
363 if (oldHead && newList[i]->m_node->hasTagName(headTag)) 363 if (oldHead && newList[i]->m_node->hasTagName(headTag))
364 merges.set(newList[i].get(), oldHead); 364 merges.set(newList[i].get(), oldHead);
365 if (oldBody && newList[i]->m_node->hasTagName(bodyTag)) 365 if (oldBody && newList[i]->m_node->hasTagName(bodyTag))
366 merges.set(newList[i].get(), oldBody); 366 merges.set(newList[i].get(), oldBody);
367 } 367 }
368 } 368 }
369 369
370 // 2. Patch nodes marked for merge. 370 // 2. Patch nodes marked for merge.
371 for (HashMap<Digest*, Digest*>::iterator it = merges.begin(); it != merges.e nd(); ++it) { 371 for (HashMap<Digest*, Digest*>::iterator it = merges.begin(); it != merges.e nd(); ++it) {
372 if (!innerPatchNode(it->value, it->key, es)) 372 if (!innerPatchNode(it->value, it->key, exceptionState))
373 return false; 373 return false;
374 } 374 }
375 375
376 // 3. Insert missing nodes. 376 // 3. Insert missing nodes.
377 for (size_t i = 0; i < newMap.size(); ++i) { 377 for (size_t i = 0; i < newMap.size(); ++i) {
378 if (newMap[i].first || merges.contains(newList[i].get())) 378 if (newMap[i].first || merges.contains(newList[i].get()))
379 continue; 379 continue;
380 if (!insertBeforeAndMarkAsUsed(parentNode, newList[i].get(), parentNode- >childNode(i), es)) 380 if (!insertBeforeAndMarkAsUsed(parentNode, newList[i].get(), parentNode- >childNode(i), exceptionState))
381 return false; 381 return false;
382 } 382 }
383 383
384 // 4. Then put all nodes that retained into their slots (sort by new index). 384 // 4. Then put all nodes that retained into their slots (sort by new index).
385 for (size_t i = 0; i < oldMap.size(); ++i) { 385 for (size_t i = 0; i < oldMap.size(); ++i) {
386 if (!oldMap[i].first) 386 if (!oldMap[i].first)
387 continue; 387 continue;
388 RefPtr<Node> node = oldMap[i].first->m_node; 388 RefPtr<Node> node = oldMap[i].first->m_node;
389 Node* anchorNode = parentNode->childNode(oldMap[i].second); 389 Node* anchorNode = parentNode->childNode(oldMap[i].second);
390 if (node.get() == anchorNode) 390 if (node.get() == anchorNode)
391 continue; 391 continue;
392 if (node->hasTagName(bodyTag) || node->hasTagName(headTag)) 392 if (node->hasTagName(bodyTag) || node->hasTagName(headTag))
393 continue; // Never move head or body, move the rest of the nodes aro und them. 393 continue; // Never move head or body, move the rest of the nodes aro und them.
394 394
395 if (!m_domEditor->insertBefore(parentNode, node.release(), anchorNode, e s)) 395 if (!m_domEditor->insertBefore(parentNode, node.release(), anchorNode, e xceptionState))
396 return false; 396 return false;
397 } 397 }
398 return true; 398 return true;
399 } 399 }
400 400
401 static void addStringToSHA1(SHA1& sha1, const String& string) 401 static void addStringToSHA1(SHA1& sha1, const String& string)
402 { 402 {
403 CString cString = string.utf8(); 403 CString cString = string.utf8();
404 sha1.addBytes(reinterpret_cast<const uint8_t*>(cString.data()), cString.leng th()); 404 sha1.addBytes(reinterpret_cast<const uint8_t*>(cString.data()), cString.leng th());
405 } 405 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 } 441 }
442 442
443 Vector<uint8_t, 20> hash; 443 Vector<uint8_t, 20> hash;
444 sha1.computeHash(hash); 444 sha1.computeHash(hash);
445 digest->m_sha1 = base64Encode(reinterpret_cast<const char*>(hash.data()), 10 ); 445 digest->m_sha1 = base64Encode(reinterpret_cast<const char*>(hash.data()), 10 );
446 if (unusedNodesMap) 446 if (unusedNodesMap)
447 unusedNodesMap->add(digest->m_sha1, digest); 447 unusedNodesMap->add(digest->m_sha1, digest);
448 return adoptPtr(digest); 448 return adoptPtr(digest);
449 } 449 }
450 450
451 bool DOMPatchSupport::insertBeforeAndMarkAsUsed(ContainerNode* parentNode, Diges t* digest, Node* anchor, ExceptionState& es) 451 bool DOMPatchSupport::insertBeforeAndMarkAsUsed(ContainerNode* parentNode, Diges t* digest, Node* anchor, ExceptionState& exceptionState)
452 { 452 {
453 bool result = m_domEditor->insertBefore(parentNode, digest->m_node, anchor, es); 453 bool result = m_domEditor->insertBefore(parentNode, digest->m_node, anchor, exceptionState);
454 markNodeAsUsed(digest); 454 markNodeAsUsed(digest);
455 return result; 455 return result;
456 } 456 }
457 457
458 bool DOMPatchSupport::removeChildAndMoveToNew(Digest* oldDigest, ExceptionState& es) 458 bool DOMPatchSupport::removeChildAndMoveToNew(Digest* oldDigest, ExceptionState& exceptionState)
459 { 459 {
460 RefPtr<Node> oldNode = oldDigest->m_node; 460 RefPtr<Node> oldNode = oldDigest->m_node;
461 if (!m_domEditor->removeChild(oldNode->parentNode(), oldNode.get(), es)) 461 if (!m_domEditor->removeChild(oldNode->parentNode(), oldNode.get(), exceptio nState))
462 return false; 462 return false;
463 463
464 // Diff works within levels. In order not to lose the node identity when use r 464 // Diff works within levels. In order not to lose the node identity when use r
465 // prepends his HTML with "<div>" (i.e. all nodes are shifted to the next ne sted level), 465 // prepends his HTML with "<div>" (i.e. all nodes are shifted to the next ne sted level),
466 // prior to dropping the original node on the floor, check whether new DOM h as a digest 466 // prior to dropping the original node on the floor, check whether new DOM h as a digest
467 // with matching sha1. If it does, replace it with the original DOM chunk. C hances are 467 // with matching sha1. If it does, replace it with the original DOM chunk. C hances are
468 // high that it will get merged back into the original DOM during the furthe r patching. 468 // high that it will get merged back into the original DOM during the furthe r patching.
469 UnusedNodesMap::iterator it = m_unusedNodesMap.find(oldDigest->m_sha1); 469 UnusedNodesMap::iterator it = m_unusedNodesMap.find(oldDigest->m_sha1);
470 if (it != m_unusedNodesMap.end()) { 470 if (it != m_unusedNodesMap.end()) {
471 Digest* newDigest = it->value; 471 Digest* newDigest = it->value;
472 Node* newNode = newDigest->m_node; 472 Node* newNode = newDigest->m_node;
473 if (!m_domEditor->replaceChild(newNode->parentNode(), oldNode, newNode, es)) 473 if (!m_domEditor->replaceChild(newNode->parentNode(), oldNode, newNode, exceptionState))
474 return false; 474 return false;
475 newDigest->m_node = oldNode.get(); 475 newDigest->m_node = oldNode.get();
476 markNodeAsUsed(newDigest); 476 markNodeAsUsed(newDigest);
477 return true; 477 return true;
478 } 478 }
479 479
480 for (size_t i = 0; i < oldDigest->m_children.size(); ++i) { 480 for (size_t i = 0; i < oldDigest->m_children.size(); ++i) {
481 if (!removeChildAndMoveToNew(oldDigest->m_children[i].get(), es)) 481 if (!removeChildAndMoveToNew(oldDigest->m_children[i].get(), exceptionSt ate))
482 return false; 482 return false;
483 } 483 }
484 return true; 484 return true;
485 } 485 }
486 486
487 void DOMPatchSupport::markNodeAsUsed(Digest* digest) 487 void DOMPatchSupport::markNodeAsUsed(Digest* digest)
488 { 488 {
489 Deque<Digest*> queue; 489 Deque<Digest*> queue;
490 queue.append(digest); 490 queue.append(digest);
491 while (!queue.isEmpty()) { 491 while (!queue.isEmpty()) {
(...skipping 15 matching lines...) Expand all
507 void DOMPatchSupport::dumpMap(const ResultMap& map, const String& name) 507 void DOMPatchSupport::dumpMap(const ResultMap& map, const String& name)
508 { 508 {
509 fprintf(stderr, "\n\n"); 509 fprintf(stderr, "\n\n");
510 for (size_t i = 0; i < map.size(); ++i) 510 for (size_t i = 0; i < map.size(); ++i)
511 fprintf(stderr, "%s[%lu]: %s (%p) - [%lu]\n", name.utf8().data(), i, map [i].first ? nodeName(map[i].first->m_node).utf8().data() : "", map[i].first, map [i].second); 511 fprintf(stderr, "%s[%lu]: %s (%p) - [%lu]\n", name.utf8().data(), i, map [i].first ? nodeName(map[i].first->m_node).utf8().data() : "", map[i].first, map [i].second);
512 } 512 }
513 #endif 513 #endif
514 514
515 } // namespace WebCore 515 } // namespace WebCore
516 516
OLDNEW
« no previous file with comments | « Source/core/inspector/DOMEditor.cpp ('k') | Source/core/inspector/InspectorCSSAgent.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698