Upstream version 7.35.144.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / devtools / front_end / AuditRules.js
index 5a224d5..64d629d 100644 (file)
@@ -116,6 +116,9 @@ WebInspector.AuditRules.GzipRule.prototype = {
         callback(result);
     },
 
+    /**
+     * @param {!WebInspector.NetworkRequest} request
+     */
     _isCompressed: function(request)
     {
         var encodingHeader = request.responseHeaderValue("Content-Encoding");
@@ -125,6 +128,9 @@ WebInspector.AuditRules.GzipRule.prototype = {
         return /\b(?:gzip|deflate)\b/.test(encodingHeader);
     },
 
+    /**
+     * @param {!WebInspector.NetworkRequest} request
+     */
     _shouldCompress: function(request)
     {
         return request.type.isTextType() && request.parsedURL.host && request.resourceSize !== undefined && request.resourceSize > 150;
@@ -267,11 +273,15 @@ WebInspector.AuditRules.ParallelizeDownloadRule.prototype = {
      */
     doRun: function(requests, result, callback, progress)
     {
+        /**
+         * @param {string} a
+         * @param {string} b
+         */
         function hostSorter(a, b)
         {
             var aCount = domainToResourcesMap[a].length;
             var bCount = domainToResourcesMap[b].length;
-            return (aCount < bCount) ? 1 : (aCount == bCount) ? 0 : -1;
+            return (aCount < bCount) ? 1 : (aCount === bCount) ? 0 : -1;
         }
 
         var domainToResourcesMap = WebInspector.AuditRules.getDomainToResourcesMap(
@@ -348,15 +358,10 @@ WebInspector.AuditRules.UnusedCssRule.prototype = {
      */
     doRun: function(requests, result, callback, progress)
     {
-        var self = this;
-
         /**
-         * @param {!Array.<!WebInspector.CSSStyleSheet>} styleSheets
+         * @param {!Array.<!WebInspector.AuditRules.ParsedStyleSheet>} styleSheets
          */
         function evalCallback(styleSheets) {
-            if (progress.isCanceled())
-                return;
-
             if (!styleSheets.length)
                 return callback(null);
 
@@ -376,7 +381,7 @@ WebInspector.AuditRules.UnusedCssRule.prototype = {
             var foundSelectors = {};
 
             /**
-             * @param {!Array.<!WebInspector.CSSStyleSheet>} styleSheets
+             * @param {!Array.<!WebInspector.AuditRules.ParsedStyleSheet>} styleSheets
              */
             function selectorsCallback(styleSheets)
             {
@@ -404,7 +409,7 @@ WebInspector.AuditRules.UnusedCssRule.prototype = {
                         continue;
 
                     var resource = WebInspector.resourceForURL(styleSheet.sourceURL);
-                    var isInlineBlock = resource && resource.request && resource.request.type == WebInspector.resourceTypes.Document;
+                    var isInlineBlock = resource && resource.request && resource.request.type === WebInspector.resourceTypes.Document;
                     var url = !isInlineBlock ? WebInspector.AuditRuleResult.linkifyDisplayName(styleSheet.sourceURL) : WebInspector.UIString("Inline block #%d", ++inlineBlockOrdinal);
                     var pctUnused = Math.round(100 * unusedRules.length / styleSheet.rules.length);
                     if (!summary)
@@ -453,54 +458,97 @@ WebInspector.AuditRules.UnusedCssRule.prototype = {
                     if (progress.isCanceled())
                         return;
                     var effectiveSelector = selectors[i].replace(pseudoSelectorRegexp, "");
-                    WebInspector.domAgent.querySelector(document.id, effectiveSelector, queryCallback.bind(null, i === selectors.length - 1 ? selectorsCallback.bind(null, styleSheets) : null, selectors[i]));
+                    WebInspector.domModel.querySelector(document.id, effectiveSelector, queryCallback.bind(null, i === selectors.length - 1 ? selectorsCallback.bind(null, styleSheets) : null, selectors[i]));
                 }
             }
 
-            WebInspector.domAgent.requestDocument(documentLoaded.bind(null, selectors));
+            WebInspector.domModel.requestDocument(documentLoaded.bind(null, selectors));
         }
 
-        /**
-         * @param {!Array.<!WebInspector.CSSStyleSheet>} styleSheets
-         * @param {string} sourceURL
-         * @param {?function(!Array.<!WebInspector.CSSStyleSheet>)} continuation
-         * @param {?WebInspector.CSSStyleSheet} styleSheet
-         */
-        function styleSheetCallback(styleSheets, sourceURL, continuation, styleSheet)
-        {
-            if (progress.isCanceled())
-                return;
-
-            if (styleSheet) {
-                styleSheet.sourceURL = sourceURL;
-                styleSheets.push(styleSheet);
-            }
-            if (continuation)
-                continuation(styleSheets);
+        var styleSheetInfos = WebInspector.cssModel.allStyleSheets();
+        if (!styleSheetInfos || !styleSheetInfos.length) {
+            evalCallback([]);
+            return;
         }
+        var styleSheetProcessor = new WebInspector.AuditRules.StyleSheetProcessor(styleSheetInfos, progress, evalCallback);
+        styleSheetProcessor.run();
+    },
 
-        /**
-         * @param {?Protocol.Error} error
-         * @param {!Array.<!CSSAgent.CSSStyleSheetHeader>} styleSheetInfos
-         */
-        function allStylesCallback(error, styleSheetInfos)
-        {
-            if (progress.isCanceled())
-                return;
+    __proto__: WebInspector.AuditRule.prototype
+}
 
-            if (error || !styleSheetInfos || !styleSheetInfos.length)
-                return evalCallback([]);
-            var styleSheets = [];
-            for (var i = 0; i < styleSheetInfos.length; ++i) {
-                var info = styleSheetInfos[i];
-                WebInspector.CSSStyleSheet.createForId(info.styleSheetId, styleSheetCallback.bind(null, styleSheets, info.sourceURL, i == styleSheetInfos.length - 1 ? evalCallback : null));
-            }
+/**
+ * @typedef {!{sourceURL: string, rules: !Array.<!WebInspector.CSSParser.StyleRule>}}
+ */
+WebInspector.AuditRules.ParsedStyleSheet;
+
+/**
+ * @constructor
+ * @param {!Array.<!WebInspector.CSSStyleSheetHeader>} styleSheetHeaders
+ * @param {!WebInspector.Progress} progress
+ * @param {!function(!Array.<!WebInspector.AuditRules.ParsedStyleSheet>)} styleSheetsParsedCallback
+ */
+WebInspector.AuditRules.StyleSheetProcessor = function(styleSheetHeaders, progress, styleSheetsParsedCallback)
+{
+    this._styleSheetHeaders = styleSheetHeaders;
+    this._progress = progress;
+    this._styleSheets = [];
+    this._styleSheetsParsedCallback = styleSheetsParsedCallback;
+}
+
+WebInspector.AuditRules.StyleSheetProcessor.prototype = {
+    run: function()
+    {
+        this._parser = new WebInspector.CSSParser();
+        this._processNextStyleSheet();
+    },
+
+    _terminateWorker: function()
+    {
+        if (this._parser) {
+            this._parser.dispose();
+            delete this._parser;
         }
+    },
 
-        CSSAgent.getAllStyleSheets(allStylesCallback);
+    _finish: function()
+    {
+        this._terminateWorker();
+        this._styleSheetsParsedCallback(this._styleSheets);
     },
 
-    __proto__: WebInspector.AuditRule.prototype
+    _processNextStyleSheet: function()
+    {
+        if (!this._styleSheetHeaders.length) {
+            this._finish();
+            return;
+        }
+        this._currentStyleSheetHeader = this._styleSheetHeaders.shift();
+        this._parser.fetchAndParse(this._currentStyleSheetHeader, this._onStyleSheetParsed.bind(this));
+    },
+
+    /**
+     * @param {!Array.<!WebInspector.CSSParser.Rule>} rules
+     */
+    _onStyleSheetParsed: function(rules)
+    {
+        if (this._progress.isCanceled()) {
+            this._terminateWorker();
+            return;
+        }
+
+        var styleRules = [];
+        for (var i = 0; i < rules.length; ++i) {
+            var rule = rules[i];
+            if (rule.selectorText)
+                styleRules.push(rule);
+        }
+        this._styleSheets.push({
+            sourceURL: this._currentStyleSheetHeader.sourceURL,
+            rules: styleRules
+        });
+        this._processNextStyleSheet();
+    },
 }
 
 /**
@@ -638,7 +686,7 @@ WebInspector.AuditRules.CacheControlRule.prototype = {
         if (this.responseHeaderMatch(request, "Cache-Control", "public"))
             return true;
 
-        return request.url.indexOf("?") == -1 && !this.responseHeaderMatch(request, "Cache-Control", "private");
+        return request.url.indexOf("?") === -1 && !this.responseHeaderMatch(request, "Cache-Control", "private");
     },
 
     /**
@@ -837,7 +885,7 @@ WebInspector.AuditRules.ImageDimensionsRule.prototype = {
             if (progress.isCanceled())
                 return;
 
-            const node = WebInspector.domAgent.nodeForId(imageId);
+            const node = WebInspector.domModel.nodeForId(imageId);
             var src = node.getAttribute("src");
             if (!src.asParsedURL()) {
                 for (var frameOwnerCandidate = node; frameOwnerCandidate; frameOwnerCandidate = frameOwnerCandidate.parentNode) {
@@ -923,12 +971,12 @@ WebInspector.AuditRules.ImageDimensionsRule.prototype = {
         {
             if (progress.isCanceled())
                 return;
-            WebInspector.domAgent.querySelectorAll(root.id, "img[src]", getStyles);
+            WebInspector.domModel.querySelectorAll(root.id, "img[src]", getStyles);
         }
 
         if (progress.isCanceled())
             return;
-        WebInspector.domAgent.requestDocument(onDocumentAvailable);
+        WebInspector.domModel.requestDocument(onDocumentAvailable);
     },
 
     __proto__: WebInspector.AuditRule.prototype
@@ -993,7 +1041,7 @@ WebInspector.AuditRules.CssInHeadRule.prototype = {
                 var urlToViolationsArray = {};
                 var externalStylesheetHrefs = [];
                 for (var j = 0; j < externalStylesheetNodeIds.length; ++j) {
-                    var linkNode = WebInspector.domAgent.nodeForId(externalStylesheetNodeIds[j]);
+                    var linkNode = WebInspector.domModel.nodeForId(externalStylesheetNodeIds[j]);
                     var completeHref = WebInspector.ParsedURL.completeURL(linkNode.ownerDocument.baseURL, linkNode.getAttribute("href"));
                     externalStylesheetHrefs.push(completeHref || "<empty>");
                 }
@@ -1013,7 +1061,7 @@ WebInspector.AuditRules.CssInHeadRule.prototype = {
 
             if (!nodeIds)
                 return;
-            WebInspector.domAgent.querySelectorAll(root.id, "body link[rel~='stylesheet'][href]", externalStylesheetsReceived.bind(null, root, nodeIds));
+            WebInspector.domModel.querySelectorAll(root.id, "body link[rel~='stylesheet'][href]", externalStylesheetsReceived.bind(null, root, nodeIds));
         }
 
         function onDocumentAvailable(root)
@@ -1021,10 +1069,10 @@ WebInspector.AuditRules.CssInHeadRule.prototype = {
             if (progress.isCanceled())
                 return;
 
-            WebInspector.domAgent.querySelectorAll(root.id, "body style", inlineStylesReceived.bind(null, root));
+            WebInspector.domModel.querySelectorAll(root.id, "body style", inlineStylesReceived.bind(null, root));
         }
 
-        WebInspector.domAgent.requestDocument(onDocumentAvailable);
+        WebInspector.domModel.requestDocument(onDocumentAvailable);
     },
 
     __proto__: WebInspector.AuditRule.prototype
@@ -1089,7 +1137,7 @@ WebInspector.AuditRules.StylesScriptsOrderRule.prototype = {
             if (lateStyleIds.length || cssBeforeInlineCount) {
                 var lateStyleUrls = [];
                 for (var i = 0; i < lateStyleIds.length; ++i) {
-                    var lateStyleNode = WebInspector.domAgent.nodeForId(lateStyleIds[i]);
+                    var lateStyleNode = WebInspector.domModel.nodeForId(lateStyleIds[i]);
                     var completeHref = WebInspector.ParsedURL.completeURL(lateStyleNode.ownerDocument.baseURL, lateStyleNode.getAttribute("href"));
                     lateStyleUrls.push(completeHref || "<empty>");
                 }
@@ -1111,7 +1159,7 @@ WebInspector.AuditRules.StylesScriptsOrderRule.prototype = {
             if (!nodeIds)
                 return;
 
-            WebInspector.domAgent.querySelectorAll(root.id, "head link[rel~='stylesheet'][href] ~ script:not([src])", cssBeforeInlineReceived.bind(null, nodeIds));
+            WebInspector.domModel.querySelectorAll(root.id, "head link[rel~='stylesheet'][href] ~ script:not([src])", cssBeforeInlineReceived.bind(null, nodeIds));
         }
 
         /**
@@ -1122,10 +1170,10 @@ WebInspector.AuditRules.StylesScriptsOrderRule.prototype = {
             if (progress.isCanceled())
                 return;
 
-            WebInspector.domAgent.querySelectorAll(root.id, "head script[src] ~ link[rel~='stylesheet'][href]", lateStylesReceived.bind(null, root));
+            WebInspector.domModel.querySelectorAll(root.id, "head script[src] ~ link[rel~='stylesheet'][href]", lateStylesReceived.bind(null, root));
         }
 
-        WebInspector.domAgent.requestDocument(onDocumentAvailable);
+        WebInspector.domModel.requestDocument(onDocumentAvailable);
     },
 
     __proto__: WebInspector.AuditRule.prototype
@@ -1149,96 +1197,108 @@ WebInspector.AuditRules.CSSRuleBase.prototype = {
      */
     doRun: function(requests, result, callback, progress)
     {
-        CSSAgent.getAllStyleSheets(sheetsCallback.bind(this));
+        var headers = WebInspector.cssModel.allStyleSheets();
 
-        /**
-         * @param {?Protocol.Error} error
-         * @param {!Array.<!CSSAgent.CSSStyleSheetHeader>} headers
-         * @this {WebInspector.AuditRules.CSSRuleBase}
-         */
-        function sheetsCallback(error, headers)
-        {
-            if (error)
-                return callback(null);
-
-            if (!headers.length)
-                return callback(null);
-            for (var i = 0; i < headers.length; ++i) {
-                var header = headers[i];
-                if (header.disabled)
-                    continue; // Do not check disabled stylesheets.
-
-                this._visitStyleSheet(header.styleSheetId, i === headers.length - 1 ? finishedCallback : null, result, progress);
-            }
+        if (!headers.length) {
+            callback(null);
+            return;
         }
-
-        function finishedCallback()
-        {
-            callback(result);
+        var activeHeaders = []
+        for (var i = 0; i < headers.length; ++i) {
+            if (!headers[i].disabled)
+                activeHeaders.push(headers[i]);
         }
+
+        var styleSheetProcessor = new WebInspector.AuditRules.StyleSheetProcessor(activeHeaders, progress, this._styleSheetsLoaded.bind(this, result, callback, progress));
+        styleSheetProcessor.run();
     },
 
-    _visitStyleSheet: function(styleSheetId, callback, result, progress)
+    /**
+     * @param {!WebInspector.AuditRuleResult} result
+     * @param {function(!WebInspector.AuditRuleResult)} callback
+     * @param {!WebInspector.Progress} progress
+     * @param {!Array.<!WebInspector.AuditRules.ParsedStyleSheet>} styleSheets
+     */
+    _styleSheetsLoaded: function(result, callback, progress, styleSheets)
     {
-        WebInspector.CSSStyleSheet.createForId(styleSheetId, sheetCallback.bind(this));
-
-        /**
-         * @param {?WebInspector.CSSStyleSheet} styleSheet
-         * @this {WebInspector.AuditRules.CSSRuleBase}
-         */
-        function sheetCallback(styleSheet)
-        {
-            if (progress.isCanceled())
-                return;
-
-            if (!styleSheet) {
-                if (callback)
-                    callback();
-                return;
-            }
-
-            this.visitStyleSheet(styleSheet, result);
+        for (var i = 0; i < styleSheets.length; ++i)
+            this._visitStyleSheet(styleSheets[i], result);
+        callback(result);
+    },
 
-            for (var i = 0; i < styleSheet.rules.length; ++i)
-                this._visitRule(styleSheet, styleSheet.rules[i], result);
+    /**
+     * @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet
+     * @param {!WebInspector.AuditRuleResult} result
+     */
+    _visitStyleSheet: function(styleSheet, result)
+    {
+        this.visitStyleSheet(styleSheet, result);
 
-            this.didVisitStyleSheet(styleSheet, result);
+        for (var i = 0; i < styleSheet.rules.length; ++i)
+            this._visitRule(styleSheet, styleSheet.rules[i], result);
 
-            if (callback)
-                callback();
-        }
+        this.didVisitStyleSheet(styleSheet, result);
     },
 
+    /**
+     * @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet
+     * @param {!WebInspector.CSSParser.StyleRule} rule
+     * @param {!WebInspector.AuditRuleResult} result
+     */
     _visitRule: function(styleSheet, rule, result)
     {
         this.visitRule(styleSheet, rule, result);
-        var allProperties = rule.style.allProperties;
+        var allProperties = rule.properties;
         for (var i = 0; i < allProperties.length; ++i)
-            this.visitProperty(styleSheet, allProperties[i], result);
+            this.visitProperty(styleSheet, rule, allProperties[i], result);
         this.didVisitRule(styleSheet, rule, result);
     },
 
+    /**
+     * @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet
+     * @param {!WebInspector.AuditRuleResult} result
+     */
     visitStyleSheet: function(styleSheet, result)
     {
         // Subclasses can implement.
     },
 
+    /**
+     * @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet
+     * @param {!WebInspector.AuditRuleResult} result
+     */
     didVisitStyleSheet: function(styleSheet, result)
     {
         // Subclasses can implement.
     },
-    
+
+    /**
+     * @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet
+     * @param {!WebInspector.CSSParser.StyleRule} rule
+     * @param {!WebInspector.AuditRuleResult} result
+     */
     visitRule: function(styleSheet, rule, result)
     {
         // Subclasses can implement.
     },
 
+    /**
+     * @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet
+     * @param {!WebInspector.CSSParser.StyleRule} rule
+     * @param {!WebInspector.AuditRuleResult} result
+     */
     didVisitRule: function(styleSheet, rule, result)
     {
         // Subclasses can implement.
     },
-    
-    visitProperty: function(styleSheet, property, result)
+
+    /**
+     * @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet
+     * @param {!WebInspector.CSSParser.StyleRule} rule
+     * @param {!WebInspector.CSSParser.Property} property
+     * @param {!WebInspector.AuditRuleResult} result
+     */
+    visitProperty: function(styleSheet, rule, property, result)
     {
         // Subclasses can implement.
     },
@@ -1263,11 +1323,17 @@ WebInspector.AuditRules.VendorPrefixedCSSProperties.supportedProperties = [
 ].keySet();
 
 WebInspector.AuditRules.VendorPrefixedCSSProperties.prototype = {
+    /**
+     * @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet
+     */
     didVisitStyleSheet: function(styleSheet)
     {
         delete this._styleSheetResult;
     },
 
+    /**
+     * @param {!WebInspector.CSSParser.StyleRule} rule
+     */
     visitRule: function(rule)
     {
         this._mentionedProperties = {};
@@ -1279,26 +1345,25 @@ WebInspector.AuditRules.VendorPrefixedCSSProperties.prototype = {
         delete this._mentionedProperties;
     },
 
-    visitProperty: function(styleSheet, property, result)
+    /**
+     * @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet
+     * @param {!WebInspector.CSSParser.StyleRule} rule
+     * @param {!WebInspector.CSSParser.Property} property
+     * @param {!WebInspector.AuditRuleResult} result
+     */
+    visitProperty: function(styleSheet, rule, property, result)
     {
         if (!property.name.startsWith(this._webkitPrefix))
             return;
 
         var normalPropertyName = property.name.substring(this._webkitPrefix.length).toLowerCase(); // Start just after the "-webkit-" prefix.
         if (WebInspector.AuditRules.VendorPrefixedCSSProperties.supportedProperties[normalPropertyName] && !this._mentionedProperties[normalPropertyName]) {
-            var style = property.ownerStyle;
-            var liveProperty = style.getLiveProperty(normalPropertyName);
-            if (liveProperty && !liveProperty.styleBased)
-                return; // WebCore can provide normal versions of prefixed properties automatically, so be careful to skip only normal source-based properties.
-
-            var rule = style.parentRule;
             this._mentionedProperties[normalPropertyName] = true;
             if (!this._styleSheetResult)
-                this._styleSheetResult = result.addChild(rule.sourceURL ? WebInspector.linkifyResourceAsNode(rule.sourceURL) : WebInspector.UIString("<unknown>"));
+                this._styleSheetResult = result.addChild(styleSheet.sourceURL ? WebInspector.linkifyResourceAsNode(styleSheet.sourceURL) : WebInspector.UIString("<unknown>"));
             if (!this._ruleResult) {
-                var anchor = WebInspector.linkifyURLAsNode(rule.sourceURL, rule.selectorText);
-                anchor.preferredPanel = "resources";
-                anchor.lineNumber = rule.lineNumberInSource();
+                var anchor = WebInspector.linkifyURLAsNode(styleSheet.sourceURL, rule.selectorText);
+                anchor.lineNumber = rule.lineNumber;
                 this._ruleResult = this._styleSheetResult.addChild(anchor);
             }
             ++result.violationCount;
@@ -1423,7 +1488,7 @@ WebInspector.AuditRules.CookieSizeRule.prototype = {
                 null,
                 true);
         var matchingResourceData = {};
-        this.mapResourceCookies(domainToResourcesMap, allCookies, collectorCallback.bind(this));
+        this.mapResourceCookies(domainToResourcesMap, allCookies, collectorCallback);
 
         for (var requestDomain in cookiesPerResourceDomain) {
             var cookies = cookiesPerResourceDomain[requestDomain];