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

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

Issue 1211813002: DevTools: allow injecting CSS rules without breaking styles sidebar. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 6 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
« no previous file with comments | « Source/core/inspector/InspectorStyleSheet.h ('k') | no next file » | 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) 2010, Google Inc. All rights reserved. 2 * Copyright (C) 2010, 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 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 11 matching lines...) Expand all
22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */ 23 */
24 24
25 #include "config.h" 25 #include "config.h"
26 #include "core/inspector/InspectorStyleSheet.h" 26 #include "core/inspector/InspectorStyleSheet.h"
27 27
28 #include "bindings/core/v8/ExceptionState.h" 28 #include "bindings/core/v8/ExceptionState.h"
29 #include "bindings/core/v8/ExceptionStatePlaceholder.h" 29 #include "bindings/core/v8/ExceptionStatePlaceholder.h"
30 #include "bindings/core/v8/ScriptRegexp.h" 30 #include "bindings/core/v8/ScriptRegexp.h"
31 #include "core/CSSPropertyNames.h" 31 #include "core/CSSPropertyNames.h"
32 #include "core/css/CSSImportRule.h"
32 #include "core/css/CSSKeyframesRule.h" 33 #include "core/css/CSSKeyframesRule.h"
33 #include "core/css/CSSMediaRule.h" 34 #include "core/css/CSSMediaRule.h"
34 #include "core/css/CSSRuleList.h" 35 #include "core/css/CSSRuleList.h"
35 #include "core/css/CSSStyleRule.h" 36 #include "core/css/CSSStyleRule.h"
36 #include "core/css/CSSStyleSheet.h" 37 #include "core/css/CSSStyleSheet.h"
37 #include "core/css/CSSSupportsRule.h" 38 #include "core/css/CSSSupportsRule.h"
38 #include "core/css/StylePropertySet.h" 39 #include "core/css/StylePropertySet.h"
39 #include "core/css/StyleRule.h" 40 #include "core/css/StyleRule.h"
40 #include "core/css/StyleSheetContents.h" 41 #include "core/css/StyleSheetContents.h"
41 #include "core/css/parser/CSSParser.h" 42 #include "core/css/parser/CSSParser.h"
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 } 329 }
329 330
330 void StyleSheetHandler::endMediaQuery() 331 void StyleSheetHandler::endMediaQuery()
331 { 332 {
332 m_currentMediaQueryData.clear(); 333 m_currentMediaQueryData.clear();
333 } 334 }
334 335
335 bool verifyRuleText(Document* document, const String& ruleText) 336 bool verifyRuleText(Document* document, const String& ruleText)
336 { 337 {
337 DEFINE_STATIC_LOCAL(String, bogusPropertyName, ("-webkit-boguz-propertee")); 338 DEFINE_STATIC_LOCAL(String, bogusPropertyName, ("-webkit-boguz-propertee"));
339 RefPtrWillBeRawPtr<StyleSheetContents> styleSheet = StyleSheetContents::crea te(strictCSSParserContext());
338 RuleSourceDataList sourceData; 340 RuleSourceDataList sourceData;
339 String text = ruleText + " div { " + bogusPropertyName + ": none; }"; 341 String text = ruleText + " div { " + bogusPropertyName + ": none; }";
340 StyleSheetHandler handler(text, document, &sourceData); 342 StyleSheetHandler handler(text, document, &sourceData);
341 CSSParser::parseSheetForInspector(parserContextForDocument(document), text, handler); 343 CSSParser::parseSheetForInspector(parserContextForDocument(document), styleS heet.get(), text, handler);
342 unsigned ruleCount = sourceData.size(); 344 unsigned ruleCount = sourceData.size();
343 345
344 // Exactly two rules should be parsed. 346 // Exactly two rules should be parsed.
345 if (ruleCount != 2) 347 if (ruleCount != 2)
346 return false; 348 return false;
347 349
348 // Added rule must be style rule. 350 // Added rule must be style rule.
349 if (!sourceData.at(0)->styleSourceData) 351 if (!sourceData.at(0)->styleSourceData)
350 return false; 352 return false;
351 353
(...skipping 12 matching lines...) Expand all
364 } 366 }
365 367
366 bool verifyStyleText(Document* document, const String& text) 368 bool verifyStyleText(Document* document, const String& text)
367 { 369 {
368 return verifyRuleText(document, "div {" + text + "}"); 370 return verifyRuleText(document, "div {" + text + "}");
369 } 371 }
370 372
371 bool verifySelectorText(Document* document, const String& selectorText) 373 bool verifySelectorText(Document* document, const String& selectorText)
372 { 374 {
373 DEFINE_STATIC_LOCAL(String, bogusPropertyName, ("-webkit-boguz-propertee")); 375 DEFINE_STATIC_LOCAL(String, bogusPropertyName, ("-webkit-boguz-propertee"));
376 RefPtrWillBeRawPtr<StyleSheetContents> styleSheet = StyleSheetContents::crea te(strictCSSParserContext());
374 RuleSourceDataList sourceData; 377 RuleSourceDataList sourceData;
375 String text = selectorText + " { " + bogusPropertyName + ": none; }"; 378 String text = selectorText + " { " + bogusPropertyName + ": none; }";
376 StyleSheetHandler handler(text, document, &sourceData); 379 StyleSheetHandler handler(text, document, &sourceData);
377 CSSParser::parseSheetForInspector(parserContextForDocument(document), text, handler); 380 CSSParser::parseSheetForInspector(parserContextForDocument(document), styleS heet.get(), text, handler);
378 381
379 // Exactly one rule should be parsed. 382 // Exactly one rule should be parsed.
380 unsigned ruleCount = sourceData.size(); 383 unsigned ruleCount = sourceData.size();
381 if (ruleCount != 1 || sourceData.at(0)->type != StyleRule::Style) 384 if (ruleCount != 1 || sourceData.at(0)->type != StyleRule::Style)
382 return false; 385 return false;
383 386
384 // Exactly one property should be in style rule. 387 // Exactly one property should be in style rule.
385 WillBeHeapVector<CSSPropertySourceData>& propertyData = sourceData.at(0)->st yleSourceData->propertyData; 388 WillBeHeapVector<CSSPropertySourceData>& propertyData = sourceData.at(0)->st yleSourceData->propertyData;
386 unsigned propertyCount = propertyData.size(); 389 unsigned propertyCount = propertyData.size();
387 if (propertyCount != 1) 390 if (propertyCount != 1)
388 return false; 391 return false;
389 392
390 // Check for the property name. 393 // Check for the property name.
391 if (propertyData.at(0).name != bogusPropertyName) 394 if (propertyData.at(0).name != bogusPropertyName)
392 return false; 395 return false;
393 396
394 return true; 397 return true;
395 } 398 }
396 399
397 bool verifyMediaText(Document* document, const String& mediaText) 400 bool verifyMediaText(Document* document, const String& mediaText)
398 { 401 {
399 DEFINE_STATIC_LOCAL(String, bogusPropertyName, ("-webkit-boguz-propertee")); 402 DEFINE_STATIC_LOCAL(String, bogusPropertyName, ("-webkit-boguz-propertee"));
403 RefPtrWillBeRawPtr<StyleSheetContents> styleSheet = StyleSheetContents::crea te(strictCSSParserContext());
400 RuleSourceDataList sourceData; 404 RuleSourceDataList sourceData;
401 String text = "@media " + mediaText + " { div { " + bogusPropertyName + ": n one; } }"; 405 String text = "@media " + mediaText + " { div { " + bogusPropertyName + ": n one; } }";
402 StyleSheetHandler handler(text, document, &sourceData); 406 StyleSheetHandler handler(text, document, &sourceData);
403 CSSParser::parseSheetForInspector(parserContextForDocument(document), text, handler); 407 CSSParser::parseSheetForInspector(parserContextForDocument(document), styleS heet.get(), text, handler);
404 408
405 // Exactly one media rule should be parsed. 409 // Exactly one media rule should be parsed.
406 unsigned ruleCount = sourceData.size(); 410 unsigned ruleCount = sourceData.size();
407 if (ruleCount != 1 || sourceData.at(0)->type != StyleRule::Media) 411 if (ruleCount != 1 || sourceData.at(0)->type != StyleRule::Media)
408 return false; 412 return false;
409 413
410 // Media rule should have exactly one style rule child. 414 // Media rule should have exactly one style rule child.
411 RuleSourceDataList& childSourceData = sourceData.at(0)->childRules; 415 RuleSourceDataList& childSourceData = sourceData.at(0)->childRules;
412 ruleCount = childSourceData.size(); 416 ruleCount = childSourceData.size();
413 if (ruleCount != 1 || !childSourceData.at(0)->styleSourceData) 417 if (ruleCount != 1 || !childSourceData.at(0)->styleSourceData)
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
490 case CSSRule::SUPPORTS_RULE: 494 case CSSRule::SUPPORTS_RULE:
491 result->append(rule); 495 result->append(rule);
492 collectFlatRules(asCSSRuleList(rule), result); 496 collectFlatRules(asCSSRuleList(rule), result);
493 break; 497 break;
494 default: 498 default:
495 break; 499 break;
496 } 500 }
497 } 501 }
498 } 502 }
499 503
504 typedef HashMap<unsigned, unsigned, WTF::IntHash<unsigned>, WTF::UnsignedWithZer oKeyHashTraits<unsigned>> IndexMap;
505
506 void diff(const Vector<String>& listA, const Vector<String>& listB, IndexMap* aT oB, IndexMap* bToA)
507 {
508 // Cut of common prefix.
509 size_t startOffset = 0;
510 while (startOffset < listA.size() && startOffset < listB.size()) {
511 if (listA.at(startOffset) != listB.at(startOffset))
512 break;
513 aToB->set(startOffset, startOffset);
514 bToA->set(startOffset, startOffset);
515 ++startOffset;
516 }
517
518 // Cut of common suffix.
519 size_t endOffset = 0;
520 while (endOffset < listA.size() - startOffset && endOffset < listB.size() - startOffset) {
521 size_t indexA = listA.size() - endOffset - 1;
522 size_t indexB = listB.size() - endOffset - 1;
523 if (listA.at(indexA) != listB.at(indexB))
524 break;
525 aToB->set(indexA, indexB);
526 bToA->set(indexB, indexA);
527 ++endOffset;
528 }
529
530 int n = listA.size() - startOffset - endOffset;
531 int m = listB.size() - startOffset - endOffset;
532
533 // If we mapped either of arrays, we have no more work to do.
534 if (n == 0 || m == 0)
535 return;
536
537 int** diff = new int*[n];
538 int** backtrack = new int*[n];
539 for (int i = 0; i < n; ++i) {
540 diff[i] = new int[m];
541 backtrack[i] = new int[m];
542 }
543
544 // Compute longest common subsequence of two cssom models.
545 for (int i = 0; i < n; ++i) {
546 for (int j = 0; j < m; ++j) {
547 int max = 0;
548 int track = 0;
549
550 if (i > 0 && diff[i - 1][j] > max) {
551 max = diff[i - 1][j];
552 track = 1;
553 }
554
555 if (j > 0 && diff[i][j - 1] > max) {
556 max = diff[i][j - 1];
557 track = 2;
558 }
559
560 if (listA.at(i + startOffset) == listB.at(j + startOffset)) {
561 int value = i > 0 && j > 0 ? diff[i - 1][j - 1] + 1 : 1;
562 if (value > max) {
563 max = value;
564 track = 3;
565 }
566 }
567
568 diff[i][j] = max;
569 backtrack[i][j] = track;
570 }
571 }
572
573 // Backtrack and add missing mapping.
574 int i = n - 1, j = m - 1;
575 while (i >= 0 && j >= 0 && backtrack[i][j]) {
576 switch (backtrack[i][j]) {
577 case 1:
578 i -= 1;
579 break;
580 case 2:
581 j -= 1;
582 break;
583 case 3:
584 aToB->set(i + startOffset, j + startOffset);
585 bToA->set(j + startOffset, i + startOffset);
586 i -= 1;
587 j -= 1;
588 break;
589 default:
590 ASSERT_NOT_REACHED();
591 }
592 }
593
594 for (int i = 0; i < n; ++i) {
595 delete [] diff[i];
596 delete [] backtrack[i];
597 }
598 delete [] diff;
599 delete [] backtrack;
600 }
601
500 } // namespace 602 } // namespace
501 603
502 namespace blink { 604 namespace blink {
503 605
504 enum MediaListSource { 606 enum MediaListSource {
505 MediaListSourceLinkedSheet, 607 MediaListSourceLinkedSheet,
506 MediaListSourceInlineSheet, 608 MediaListSourceInlineSheet,
507 MediaListSourceMediaRule, 609 MediaListSourceMediaRule,
508 MediaListSourceImportRule 610 MediaListSourceImportRule
509 }; 611 };
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
759 , m_pageStyleSheet(pageStyleSheet) 861 , m_pageStyleSheet(pageStyleSheet)
760 , m_origin(origin) 862 , m_origin(origin)
761 , m_documentURL(documentURL) 863 , m_documentURL(documentURL)
762 { 864 {
763 String text; 865 String text;
764 bool success = inlineStyleSheetText(&text); 866 bool success = inlineStyleSheetText(&text);
765 if (!success) 867 if (!success)
766 success = resourceStyleSheetText(&text); 868 success = resourceStyleSheetText(&text);
767 if (success) 869 if (success)
768 innerSetText(text, false); 870 innerSetText(text, false);
769 collectFlatRules(); 871 mapSourceDataToCSSOM();
770 } 872 }
771 873
772 InspectorStyleSheet::~InspectorStyleSheet() 874 InspectorStyleSheet::~InspectorStyleSheet()
773 { 875 {
774 } 876 }
775 877
776 DEFINE_TRACE(InspectorStyleSheet) 878 DEFINE_TRACE(InspectorStyleSheet)
777 { 879 {
778 visitor->trace(m_cssAgent); 880 visitor->trace(m_cssAgent);
779 visitor->trace(m_resourceAgent); 881 visitor->trace(m_resourceAgent);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
812 { 914 {
813 CSSStyleSheet::RuleMutationScope mutationScope(m_pageStyleSheet.get()); 915 CSSStyleSheet::RuleMutationScope mutationScope(m_pageStyleSheet.get());
814 m_pageStyleSheet->contents()->parseString(text); 916 m_pageStyleSheet->contents()->parseString(text);
815 } 917 }
816 918
817 if (listener()) 919 if (listener())
818 listener()->didReparseStyleSheet(); 920 listener()->didReparseStyleSheet();
819 onStyleSheetTextChanged(); 921 onStyleSheetTextChanged();
820 m_pageStyleSheet->ownerDocument()->styleResolverChanged(FullStyleUpdate); 922 m_pageStyleSheet->ownerDocument()->styleResolverChanged(FullStyleUpdate);
821 923
822 collectFlatRules(); 924 mapSourceDataToCSSOM();
823 return true; 925 return true;
824 } 926 }
825 927
826 RefPtrWillBeRawPtr<CSSStyleRule> InspectorStyleSheet::setRuleSelector(const Sour ceRange& range, const String& text, SourceRange* newRange, String* oldText, Exce ptionState& exceptionState) 928 RefPtrWillBeRawPtr<CSSStyleRule> InspectorStyleSheet::setRuleSelector(const Sour ceRange& range, const String& text, SourceRange* newRange, String* oldText, Exce ptionState& exceptionState)
827 { 929 {
828 if (!verifySelectorText(m_pageStyleSheet->ownerDocument(), text)) { 930 if (!verifySelectorText(m_pageStyleSheet->ownerDocument(), text)) {
829 exceptionState.throwDOMException(SyntaxError, "Selector or media text is not valid."); 931 exceptionState.throwDOMException(SyntaxError, "Selector or media text is not valid.");
830 return nullptr; 932 return nullptr;
831 } 933 }
832 934
833 RefPtrWillBeRawPtr<CSSRuleSourceData> sourceData = findRuleByHeaderRange(ran ge); 935 RefPtrWillBeRawPtr<CSSRuleSourceData> sourceData = findRuleByHeaderRange(ran ge);
834 if (!sourceData || !sourceData->styleSourceData) { 936 if (!sourceData || !sourceData->styleSourceData) {
835 exceptionState.throwDOMException(NotFoundError, "Source range didn't mat ch existing source range"); 937 exceptionState.throwDOMException(NotFoundError, "Source range didn't mat ch existing source range");
836 return nullptr; 938 return nullptr;
837 } 939 }
838 940
839 RefPtrWillBeRawPtr<CSSRule> rule = ruleForSourceData(sourceData.get()); 941 RefPtrWillBeRawPtr<CSSRule> rule = ruleForSourceData(sourceData);
840 if (!rule || !rule->parentStyleSheet() || rule->type() != CSSRule::STYLE_RUL E) { 942 if (!rule || !rule->parentStyleSheet() || rule->type() != CSSRule::STYLE_RUL E) {
841 exceptionState.throwDOMException(NotFoundError, "Source range didn't mat ch existing style source range"); 943 exceptionState.throwDOMException(NotFoundError, "Source range didn't mat ch existing style source range");
842 return nullptr; 944 return nullptr;
843 } 945 }
844 946
845 RefPtrWillBeRawPtr<CSSStyleRule> styleRule = InspectorCSSAgent::asCSSStyleRu le(rule.get()); 947 RefPtrWillBeRawPtr<CSSStyleRule> styleRule = InspectorCSSAgent::asCSSStyleRu le(rule.get());
846 styleRule->setSelectorText(text); 948 styleRule->setSelectorText(text);
847 949
848 replaceText(sourceData->ruleHeaderRange, text, newRange, oldText); 950 if (!replaceText(sourceData->ruleHeaderRange, text, newRange, oldText))
951 mapSourceDataToCSSOM();
849 onStyleSheetTextChanged(); 952 onStyleSheetTextChanged();
850 953
851 return styleRule; 954 return styleRule;
852 } 955 }
853 956
854 RefPtrWillBeRawPtr<CSSStyleRule> InspectorStyleSheet::setStyleText(const SourceR ange& range, const String& text, SourceRange* newRange, String* oldText, Excepti onState& exceptionState) 957 RefPtrWillBeRawPtr<CSSStyleRule> InspectorStyleSheet::setStyleText(const SourceR ange& range, const String& text, SourceRange* newRange, String* oldText, Excepti onState& exceptionState)
855 { 958 {
856 if (!verifyStyleText(m_pageStyleSheet->ownerDocument(), text)) { 959 if (!verifyStyleText(m_pageStyleSheet->ownerDocument(), text)) {
857 exceptionState.throwDOMException(SyntaxError, "Style text is not valid." ); 960 exceptionState.throwDOMException(SyntaxError, "Style text is not valid." );
858 return nullptr; 961 return nullptr;
859 } 962 }
860 963
861 RefPtrWillBeRawPtr<CSSRuleSourceData> sourceData = findRuleByBodyRange(range ); 964 RefPtrWillBeRawPtr<CSSRuleSourceData> sourceData = findRuleByBodyRange(range );
862 if (!sourceData || !sourceData->styleSourceData) { 965 if (!sourceData || !sourceData->styleSourceData) {
863 exceptionState.throwDOMException(NotFoundError, "Source range didn't mat ch existing style source range"); 966 exceptionState.throwDOMException(NotFoundError, "Source range didn't mat ch existing style source range");
864 return nullptr; 967 return nullptr;
865 } 968 }
866 969
867 RefPtrWillBeRawPtr<CSSRule> rule = ruleForSourceData(sourceData.get()); 970 RefPtrWillBeRawPtr<CSSRule> rule = ruleForSourceData(sourceData);
868 if (!rule || !rule->parentStyleSheet() || rule->type() != CSSRule::STYLE_RUL E) { 971 if (!rule || !rule->parentStyleSheet() || rule->type() != CSSRule::STYLE_RUL E) {
869 exceptionState.throwDOMException(NotFoundError, "Source range didn't mat ch existing style source range"); 972 exceptionState.throwDOMException(NotFoundError, "Source range didn't mat ch existing style source range");
870 return nullptr; 973 return nullptr;
871 } 974 }
872 975
873 RefPtrWillBeRawPtr<CSSStyleRule> styleRule = InspectorCSSAgent::asCSSStyleRu le(rule.get()); 976 RefPtrWillBeRawPtr<CSSStyleRule> styleRule = InspectorCSSAgent::asCSSStyleRu le(rule.get());
874 styleRule->style()->setCSSText(text, exceptionState); 977 styleRule->style()->setCSSText(text, exceptionState);
875 978
876 replaceText(sourceData->ruleBodyRange, text, newRange, oldText); 979 if (!replaceText(sourceData->ruleBodyRange, text, newRange, oldText))
980 mapSourceDataToCSSOM();
877 onStyleSheetTextChanged(); 981 onStyleSheetTextChanged();
878 982
879 return styleRule; 983 return styleRule;
880 } 984 }
881 985
882 RefPtrWillBeRawPtr<CSSMediaRule> InspectorStyleSheet::setMediaRuleText(const Sou rceRange& range, const String& text, SourceRange* newRange, String* oldText, Exc eptionState& exceptionState) 986 RefPtrWillBeRawPtr<CSSMediaRule> InspectorStyleSheet::setMediaRuleText(const Sou rceRange& range, const String& text, SourceRange* newRange, String* oldText, Exc eptionState& exceptionState)
883 { 987 {
884 if (!verifyMediaText(m_pageStyleSheet->ownerDocument(), text)) { 988 if (!verifyMediaText(m_pageStyleSheet->ownerDocument(), text)) {
885 exceptionState.throwDOMException(SyntaxError, "Selector or media text is not valid."); 989 exceptionState.throwDOMException(SyntaxError, "Selector or media text is not valid.");
886 return nullptr; 990 return nullptr;
887 } 991 }
888 992
889 RefPtrWillBeRawPtr<CSSRuleSourceData> sourceData = findRuleByHeaderRange(ran ge); 993 RefPtrWillBeRawPtr<CSSRuleSourceData> sourceData = findRuleByHeaderRange(ran ge);
890 if (!sourceData || !sourceData->mediaSourceData) { 994 if (!sourceData || !sourceData->mediaSourceData) {
891 exceptionState.throwDOMException(NotFoundError, "Source range didn't mat ch existing source range"); 995 exceptionState.throwDOMException(NotFoundError, "Source range didn't mat ch existing source range");
892 return nullptr; 996 return nullptr;
893 } 997 }
894 998
895 RefPtrWillBeRawPtr<CSSRule> rule = ruleForSourceData(sourceData.get()); 999 RefPtrWillBeRawPtr<CSSRule> rule = ruleForSourceData(sourceData);
896 if (!rule || !rule->parentStyleSheet() || rule->type() != CSSRule::MEDIA_RUL E) { 1000 if (!rule || !rule->parentStyleSheet() || rule->type() != CSSRule::MEDIA_RUL E) {
897 exceptionState.throwDOMException(NotFoundError, "Source range didn't mat ch existing style source range"); 1001 exceptionState.throwDOMException(NotFoundError, "Source range didn't mat ch existing style source range");
898 return nullptr; 1002 return nullptr;
899 } 1003 }
900 1004
901 RefPtrWillBeRawPtr<CSSMediaRule> mediaRule = InspectorCSSAgent::asCSSMediaR ule(rule.get()); 1005 RefPtrWillBeRawPtr<CSSMediaRule> mediaRule = InspectorCSSAgent::asCSSMediaR ule(rule.get());
902 mediaRule->media()->setMediaText(text); 1006 mediaRule->media()->setMediaText(text);
903 1007
904 replaceText(sourceData->ruleHeaderRange, text, newRange, oldText); 1008 if (!replaceText(sourceData->ruleHeaderRange, text, newRange, oldText))
1009 mapSourceDataToCSSOM();
1010
905 onStyleSheetTextChanged(); 1011 onStyleSheetTextChanged();
906 1012
907 return mediaRule; 1013 return mediaRule;
908 } 1014 }
909 1015
910 RefPtrWillBeRawPtr<CSSRuleSourceData> InspectorStyleSheet::ruleAfterSourceRange( const SourceRange& sourceRange) 1016 RefPtrWillBeRawPtr<CSSRuleSourceData> InspectorStyleSheet::ruleAfterSourceRange( const SourceRange& sourceRange)
911 { 1017 {
912 ASSERT(m_sourceData); 1018 ASSERT(m_sourceData);
913 unsigned index = 0; 1019 unsigned index = 0;
914 for (; index < m_sourceData->size(); ++index) { 1020 for (; index < m_sourceData->size(); ++index) {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
970 exceptionState.throwDOMException(NotFoundError, "Cannot insert rule inside rule selector."); 1076 exceptionState.throwDOMException(NotFoundError, "Cannot insert rule inside rule selector.");
971 return nullptr; 1077 return nullptr;
972 } 1078 }
973 if (sourceRange.start < ruleSourceData->ruleBodyRange.start || ruleSourc eData->ruleBodyRange.end < sourceRange.start) 1079 if (sourceRange.start < ruleSourceData->ruleBodyRange.start || ruleSourc eData->ruleBodyRange.end < sourceRange.start)
974 continue; 1080 continue;
975 if (!containingRuleSourceData || containingRuleSourceData->ruleBodyRange .length() > ruleSourceData->ruleBodyRange.length()) 1081 if (!containingRuleSourceData || containingRuleSourceData->ruleBodyRange .length() > ruleSourceData->ruleBodyRange.length())
976 containingRuleSourceData = ruleSourceData; 1082 containingRuleSourceData = ruleSourceData;
977 } 1083 }
978 1084
979 RefPtrWillBeRawPtr<CSSRuleSourceData> insertBefore = ruleAfterSourceRange(so urceRange); 1085 RefPtrWillBeRawPtr<CSSRuleSourceData> insertBefore = ruleAfterSourceRange(so urceRange);
980 RefPtrWillBeRawPtr<CSSRule> insertBeforeRule = ruleForSourceData(insertBefor e.get()); 1086 RefPtrWillBeRawPtr<CSSRule> insertBeforeRule = ruleForSourceData(insertBefor e);
981 1087
982 if (!containingRuleSourceData) 1088 if (!containingRuleSourceData)
983 return insertCSSOMRuleInStyleSheet(insertBeforeRule.get(), ruleText, exc eptionState); 1089 return insertCSSOMRuleInStyleSheet(insertBeforeRule.get(), ruleText, exc eptionState);
984 1090
985 RefPtrWillBeRawPtr<CSSRule> rule = ruleForSourceData(containingRuleSourceDat a.get()); 1091 RefPtrWillBeRawPtr<CSSRule> rule = ruleForSourceData(containingRuleSourceDat a);
986 if (!rule || rule->type() != CSSRule::MEDIA_RULE) { 1092 if (!rule || rule->type() != CSSRule::MEDIA_RULE) {
987 exceptionState.throwDOMException(NotFoundError, "Cannot insert rule in n on-media rule."); 1093 exceptionState.throwDOMException(NotFoundError, "Cannot insert rule in n on-media rule.");
988 return nullptr; 1094 return nullptr;
989 } 1095 }
990 1096
991 return insertCSSOMRuleInMediaRule(toCSSMediaRule(rule.get()), insertBeforeRu le.get(), ruleText, exceptionState); 1097 return insertCSSOMRuleInMediaRule(toCSSMediaRule(rule.get()), insertBeforeRu le.get(), ruleText, exceptionState);
992 } 1098 }
993 1099
994 RefPtrWillBeRawPtr<CSSStyleRule> InspectorStyleSheet::addRule(const String& rule Text, const SourceRange& location, SourceRange* addedRange, ExceptionState& exce ptionState) 1100 RefPtrWillBeRawPtr<CSSStyleRule> InspectorStyleSheet::addRule(const String& rule Text, const SourceRange& location, SourceRange* addedRange, ExceptionState& exce ptionState)
995 { 1101 {
(...skipping 10 matching lines...) Expand all
1006 if (!m_sourceData) { 1112 if (!m_sourceData) {
1007 exceptionState.throwDOMException(NotFoundError, "Style is read-only."); 1113 exceptionState.throwDOMException(NotFoundError, "Style is read-only.");
1008 return nullptr; 1114 return nullptr;
1009 } 1115 }
1010 1116
1011 RefPtrWillBeRawPtr<CSSStyleRule> styleRule = insertCSSOMRuleBySourceRange(lo cation, ruleText, exceptionState); 1117 RefPtrWillBeRawPtr<CSSStyleRule> styleRule = insertCSSOMRuleBySourceRange(lo cation, ruleText, exceptionState);
1012 if (exceptionState.hadException()) 1118 if (exceptionState.hadException())
1013 return nullptr; 1119 return nullptr;
1014 1120
1015 replaceText(location, ruleText, addedRange, nullptr); 1121 replaceText(location, ruleText, addedRange, nullptr);
1016 collectFlatRules(); 1122 mapSourceDataToCSSOM();
1017 1123
1018 onStyleSheetTextChanged(); 1124 onStyleSheetTextChanged();
1019 return styleRule; 1125 return styleRule;
1020 } 1126 }
1021 1127
1022 bool InspectorStyleSheet::deleteRule(const SourceRange& range, ExceptionState& e xceptionState) 1128 bool InspectorStyleSheet::deleteRule(const SourceRange& range, ExceptionState& e xceptionState)
1023 { 1129 {
1024 if (!m_sourceData) { 1130 if (!m_sourceData) {
1025 exceptionState.throwDOMException(NotFoundError, "Style is read-only."); 1131 exceptionState.throwDOMException(NotFoundError, "Style is read-only.");
1026 return false; 1132 return false;
1027 } 1133 }
1028 1134
1029 // Find index of CSSRule that entirely belongs to the range. 1135 // Find index of CSSRule that entirely belongs to the range.
1030 RefPtrWillBeRawPtr<CSSRuleSourceData> foundData = nullptr; 1136 RefPtrWillBeRawPtr<CSSRuleSourceData> foundData = nullptr;
1031 1137
1032 for (size_t i = 0; i < m_sourceData->size(); ++i) { 1138 for (size_t i = 0; i < m_sourceData->size(); ++i) {
1033 RefPtrWillBeRawPtr<CSSRuleSourceData> ruleSourceData = m_sourceData->at( i); 1139 RefPtrWillBeRawPtr<CSSRuleSourceData> ruleSourceData = m_sourceData->at( i);
1034 unsigned ruleStart = ruleSourceData->ruleHeaderRange.start; 1140 unsigned ruleStart = ruleSourceData->ruleHeaderRange.start;
1035 unsigned ruleEnd = ruleSourceData->ruleBodyRange.end + 1; 1141 unsigned ruleEnd = ruleSourceData->ruleBodyRange.end + 1;
1036 bool startBelongs = ruleStart >= range.start && ruleStart < range.end; 1142 bool startBelongs = ruleStart >= range.start && ruleStart < range.end;
1037 bool endBelongs = ruleEnd > range.start && ruleEnd <= range.end; 1143 bool endBelongs = ruleEnd > range.start && ruleEnd <= range.end;
1038 1144
1039 if (startBelongs != endBelongs) 1145 if (startBelongs != endBelongs)
1040 break; 1146 break;
1041 if (!startBelongs) 1147 if (!startBelongs)
1042 continue; 1148 continue;
1043 if (!foundData || foundData->ruleBodyRange.length() > ruleSourceData->ru leBodyRange.length()) 1149 if (!foundData || foundData->ruleBodyRange.length() > ruleSourceData->ru leBodyRange.length())
1044 foundData = ruleSourceData; 1150 foundData = ruleSourceData;
1045 } 1151 }
1046 RefPtrWillBeRawPtr<CSSRule> rule = ruleForSourceData(foundData.get()); 1152 RefPtrWillBeRawPtr<CSSRule> rule = ruleForSourceData(foundData);
1047 if (!rule) { 1153 if (!rule) {
1048 exceptionState.throwDOMException(NotFoundError, "No style rule could be found in given range."); 1154 exceptionState.throwDOMException(NotFoundError, "No style rule could be found in given range.");
1049 return false; 1155 return false;
1050 } 1156 }
1051 CSSStyleSheet* styleSheet = rule->parentStyleSheet(); 1157 CSSStyleSheet* styleSheet = rule->parentStyleSheet();
1052 if (!styleSheet) { 1158 if (!styleSheet) {
1053 exceptionState.throwDOMException(NotFoundError, "No parent stylesheet co uld be found."); 1159 exceptionState.throwDOMException(NotFoundError, "No parent stylesheet co uld be found.");
1054 return false; 1160 return false;
1055 } 1161 }
1056 CSSRule* parentRule = rule->parentRule(); 1162 CSSRule* parentRule = rule->parentRule();
(...skipping 14 matching lines...) Expand all
1071 ++index; 1177 ++index;
1072 ASSERT(index < styleSheet->length()); 1178 ASSERT(index < styleSheet->length());
1073 styleSheet->deleteRule(index, exceptionState); 1179 styleSheet->deleteRule(index, exceptionState);
1074 } 1180 }
1075 // |rule| MAY NOT be addressed after this line! 1181 // |rule| MAY NOT be addressed after this line!
1076 1182
1077 if (exceptionState.hadException()) 1183 if (exceptionState.hadException())
1078 return false; 1184 return false;
1079 1185
1080 replaceText(range, "", nullptr, nullptr); 1186 replaceText(range, "", nullptr, nullptr);
1081 collectFlatRules(); 1187 mapSourceDataToCSSOM();
1082 1188
1083 onStyleSheetTextChanged(); 1189 onStyleSheetTextChanged();
1084 return true; 1190 return true;
1085 } 1191 }
1086 1192
1087 void InspectorStyleSheet::replaceText(const SourceRange& range, const String& te xt, SourceRange* newRange, String* oldText) 1193 bool InspectorStyleSheet::replaceText(const SourceRange& range, const String& te xt, SourceRange* newRange, String* oldText)
1088 { 1194 {
1089 String sheetText = m_text; 1195 String sheetText = m_text;
1090 if (oldText) 1196 if (oldText)
1091 *oldText = sheetText.substring(range.start, range.length()); 1197 *oldText = sheetText.substring(range.start, range.length());
1092 sheetText.replace(range.start, range.length(), text); 1198 sheetText.replace(range.start, range.length(), text);
1093 if (newRange) 1199 if (newRange)
1094 *newRange = SourceRange(range.start, range.start + text.length()); 1200 *newRange = SourceRange(range.start, range.start + text.length());
1095 innerSetText(sheetText, true); 1201 return innerSetText(sheetText, true);
1096 } 1202 }
1097 1203
1098 void InspectorStyleSheet::innerSetText(const String& text, bool markAsLocallyMod ified) 1204 bool InspectorStyleSheet::innerSetText(const String& text, bool markAsLocallyMod ified)
1099 { 1205 {
1206 unsigned sizeBefore = m_sourceData ? m_sourceData->size() : 0;
1207
1100 OwnPtrWillBeRawPtr<RuleSourceDataList> ruleTree = adoptPtrWillBeNoop(new Rul eSourceDataList()); 1208 OwnPtrWillBeRawPtr<RuleSourceDataList> ruleTree = adoptPtrWillBeNoop(new Rul eSourceDataList());
1209 RefPtrWillBeRawPtr<StyleSheetContents> styleSheet = StyleSheetContents::crea te(m_pageStyleSheet->contents()->parserContext());
1101 StyleSheetHandler handler(text, m_pageStyleSheet->ownerDocument(), ruleTree. get()); 1210 StyleSheetHandler handler(text, m_pageStyleSheet->ownerDocument(), ruleTree. get());
1102 CSSParser::parseSheetForInspector(parserContextForDocument(m_pageStyleSheet- >ownerDocument()), text, handler); 1211 CSSParser::parseSheetForInspector(m_pageStyleSheet->contents()->parserContex t(), styleSheet.get(), text, handler);
1212 if (toCSSImportRule(m_pageStyleSheet->ownerRule()))
1213 m_sourceDataSheet = CSSStyleSheet::create(styleSheet, toCSSImportRule(m_ pageStyleSheet->ownerRule()));
1214 else
1215 m_sourceDataSheet = CSSStyleSheet::create(styleSheet, m_pageStyleSheet-> ownerNode());
1103 m_sourceData = adoptPtrWillBeNoop(new RuleSourceDataList()); 1216 m_sourceData = adoptPtrWillBeNoop(new RuleSourceDataList());
1104 flattenSourceData(ruleTree.get(), m_sourceData.get()); 1217 flattenSourceData(ruleTree.get(), m_sourceData.get());
1105 m_text = text; 1218 m_text = text;
1106 1219
1107 if (markAsLocallyModified) { 1220 if (markAsLocallyModified) {
1108 Element* element = ownerStyleElement(); 1221 Element* element = ownerStyleElement();
1109 if (element) 1222 if (element)
1110 m_cssAgent->addEditedStyleElement(DOMNodeIds::idForNode(element), te xt); 1223 m_cssAgent->addEditedStyleElement(DOMNodeIds::idForNode(element), te xt);
1111 else 1224 else
1112 m_cssAgent->addEditedStyleSheet(finalURL(), text); 1225 m_cssAgent->addEditedStyleSheet(finalURL(), text);
1113 } 1226 }
1227 return sizeBefore == m_sourceData->size();
1114 } 1228 }
1115 1229
1116 PassRefPtr<TypeBuilder::CSS::CSSStyleSheetHeader> InspectorStyleSheet::buildObje ctForStyleSheetInfo() 1230 PassRefPtr<TypeBuilder::CSS::CSSStyleSheetHeader> InspectorStyleSheet::buildObje ctForStyleSheetInfo()
1117 { 1231 {
1118 CSSStyleSheet* styleSheet = pageStyleSheet(); 1232 CSSStyleSheet* styleSheet = pageStyleSheet();
1119 if (!styleSheet) 1233 if (!styleSheet)
1120 return nullptr; 1234 return nullptr;
1121 1235
1122 Document* document = styleSheet->ownerDocument(); 1236 Document* document = styleSheet->ownerDocument();
1123 LocalFrame* frame = document ? document->frame() : nullptr; 1237 LocalFrame* frame = document ? document->frame() : nullptr;
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
1351 1465
1352 for (size_t i = 0; i < m_sourceData->size(); ++i) { 1466 for (size_t i = 0; i < m_sourceData->size(); ++i) {
1353 RefPtrWillBeRawPtr<CSSRuleSourceData> ruleSourceData = m_sourceData->at( i); 1467 RefPtrWillBeRawPtr<CSSRuleSourceData> ruleSourceData = m_sourceData->at( i);
1354 if (ruleSourceData->ruleBodyRange.start == sourceRange.start && ruleSour ceData->ruleBodyRange.end == sourceRange.end) { 1468 if (ruleSourceData->ruleBodyRange.start == sourceRange.start && ruleSour ceData->ruleBodyRange.end == sourceRange.end) {
1355 return ruleSourceData; 1469 return ruleSourceData;
1356 } 1470 }
1357 } 1471 }
1358 return nullptr; 1472 return nullptr;
1359 } 1473 }
1360 1474
1361 RefPtrWillBeRawPtr<CSSRule> InspectorStyleSheet::ruleForSourceData(CSSRuleSource Data* sourceData) 1475 RefPtrWillBeRawPtr<CSSRule> InspectorStyleSheet::ruleForSourceData(RefPtrWillBeR awPtr<CSSRuleSourceData> sourceData)
1362 { 1476 {
1363 if (!m_sourceData || !sourceData) 1477 if (!m_sourceData || !sourceData)
1364 return nullptr; 1478 return nullptr;
1365 for (size_t i = 0; i < m_sourceData->size(); ++i) { 1479 size_t index = m_sourceData->find(sourceData.get());
1366 if (m_sourceData->at(i).get() == sourceData) 1480 if (index == kNotFound)
1367 return i < m_flatRules.size() ? m_flatRules.at(i) : nullptr; 1481 return nullptr;
1368 } 1482 IndexMap::iterator it = m_sourceDataToRule.find(index);
1369 return nullptr; 1483 if (it == m_sourceDataToRule.end())
1484 return nullptr;
1485 ASSERT(it->value < m_flatRules.size());
1486 return m_flatRules.at(it->value);
lushnikov 2015/06/25 15:44:12 i think you want to re-calc the mapping if you don
1370 } 1487 }
1371 1488
1372 RefPtrWillBeRawPtr<CSSRuleSourceData> InspectorStyleSheet::sourceDataForRule(CSS Rule* rule) 1489 RefPtrWillBeRawPtr<CSSRuleSourceData> InspectorStyleSheet::sourceDataForRule(Ref PtrWillBeRawPtr<CSSRule> rule)
1373 { 1490 {
1374 if (!m_sourceData || !rule) 1491 if (!m_sourceData || !rule)
1375 return nullptr; 1492 return nullptr;
1376 1493 size_t index = m_flatRules.find(rule.get());
1377 size_t index = m_flatRules.find(rule); 1494 if (index == kNotFound)
1378 return index < m_sourceData->size() ? m_sourceData->at(index) : nullptr; 1495 return nullptr;
1496 IndexMap::iterator it = m_ruleToSourceData.find(index);
1497 if (it == m_ruleToSourceData.end())
1498 return nullptr;
1499 ASSERT(it->value < m_sourceData->size());
1500 return m_sourceData->at(it->value);
lushnikov 2015/06/25 15:44:12 ditto
1379 } 1501 }
1380 1502
1381 void InspectorStyleSheet::collectFlatRules() 1503 void InspectorStyleSheet::mapSourceDataToCSSOM()
1382 { 1504 {
1505 m_ruleToSourceData.clear();
1506 m_sourceDataToRule.clear();
1507
1383 m_flatRules.clear(); 1508 m_flatRules.clear();
1384 ::collectFlatRules(m_pageStyleSheet.get(), &m_flatRules); 1509 CSSRuleVector& cssomRules = m_flatRules;
1510 collectFlatRules(m_pageStyleSheet.get(), &cssomRules);
1511
1512 if (!m_sourceData)
1513 return;
1514
1515 CSSRuleVector parsedRules;
1516 collectFlatRules(m_sourceDataSheet.get(), &parsedRules);
1517
1518 Vector<String> cssomRulesText = Vector<String>();
1519 Vector<String> parsedRulesText = Vector<String>();
1520 for (size_t i = 0; i < cssomRules.size(); ++i)
1521 cssomRulesText.append(cssomRules.at(i)->cssText());
1522 for (size_t j = 0; j < parsedRules.size(); ++j)
1523 parsedRulesText.append(parsedRules.at(j)->cssText());
1524
1525 diff(cssomRulesText, parsedRulesText, &m_ruleToSourceData, &m_sourceDataToRu le);
1385 } 1526 }
1386 1527
1387 const CSSRuleVector& InspectorStyleSheet::flatRules() 1528 const CSSRuleVector& InspectorStyleSheet::flatRules()
1388 { 1529 {
1389 return m_flatRules; 1530 return m_flatRules;
1390 } 1531 }
1391 1532
1392 bool InspectorStyleSheet::resourceStyleSheetText(String* result) 1533 bool InspectorStyleSheet::resourceStyleSheetText(String* result)
1393 { 1534 {
1394 if (m_origin == TypeBuilder::CSS::StyleSheetOrigin::Injected || m_origin == TypeBuilder::CSS::StyleSheetOrigin::User_agent) 1535 if (m_origin == TypeBuilder::CSS::StyleSheetOrigin::Injected || m_origin == TypeBuilder::CSS::StyleSheetOrigin::User_agent)
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1499 } 1640 }
1500 1641
1501 DEFINE_TRACE(InspectorStyleSheetForInlineStyle) 1642 DEFINE_TRACE(InspectorStyleSheetForInlineStyle)
1502 { 1643 {
1503 visitor->trace(m_element); 1644 visitor->trace(m_element);
1504 visitor->trace(m_inspectorStyle); 1645 visitor->trace(m_inspectorStyle);
1505 InspectorStyleSheetBase::trace(visitor); 1646 InspectorStyleSheetBase::trace(visitor);
1506 } 1647 }
1507 1648
1508 } // namespace blink 1649 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/inspector/InspectorStyleSheet.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698