<commit_before>/*
 * Copyright (C) 2010 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

WebInspector.AuditRules.IPAddressRegexp = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;

WebInspector.AuditRules.CacheableResponseCodes =
{
    200: true,
    203: true,
    206: true,
    300: true,
    301: true,
    410: true,

    304: true // Underlying request is cacheable
}

/**
 * @param {!Array.<!WebInspector.NetworkRequest>} requests
 * @param {?Array.<!WebInspector.resourceTypes>} types
 * @param {boolean} needFullResources
 * @return {!Object.<string, !Array.<!WebInspector.NetworkRequest|string>>}
 */
WebInspector.AuditRules.getDomainToResourcesMap = function(requests, types, needFullResources)
{
    var domainToResourcesMap = {};
    for (var i = 0, size = requests.length; i < size; ++i) {
        var request = requests[i];
        if (types && types.indexOf(request.resourceType()) === -1)
            continue;
        var parsedURL = request.url.asParsedURL();
        if (!parsedURL)
            continue;
        var domain = parsedURL.host;
        var domainResources = domainToResourcesMap[domain];
        if (domainResources === undefined) {
          domainResources = [];
          domainToResourcesMap[domain] = domainResources;
        }
        domainResources.push(needFullResources ? request : request.url);
    }
    return domainToResourcesMap;
}

/**
 * @constructor
 * @extends {WebInspector.AuditRule}
 */
WebInspector.AuditRules.GzipRule = function()
{
    WebInspector.AuditRule.call(this, "network-gzip", WebInspector.UIString("Enable gzip compression"));
}

WebInspector.AuditRules.GzipRule.prototype = {
    /**
     * @param {!WebInspector.Target} target
     * @param {!Array.<!WebInspector.NetworkRequest>} requests
     * @param {!WebInspector.AuditRuleResult} result
     * @param {function(?WebInspector.AuditRuleResult)} callback
     * @param {!WebInspector.Progress} progress
     */
    doRun: function(target, requests, result, callback, progress)
    {
        var totalSavings = 0;
        var compressedSize = 0;
        var candidateSize = 0;
        var summary = result.addChild("", true);
        for (var i = 0, length = requests.length; i < length; ++i) {
            var request = requests[i];
            if (request.cached() || request.statusCode === 304)
                continue; // Do not test cached resources.
            if (this._shouldCompress(request)) {
                var size = request.resourceSize;
                candidateSize += size;
                if (this._isCompressed(request)) {
                    compressedSize += size;
                    continue;
                }
                var savings = 2 * size / 3;
                totalSavings += savings;
                summary.addFormatted("%r could save ~%s", request.url, Number.bytesToString(savings));
                result.violationCount++;
            }
        }
        if (!totalSavings) {
            callback(null);
            return;
        }
        summary.value = WebInspector.UIString("Compressing the following resources with gzip could reduce their transfer size by about two thirds (~%s):", Number.bytesToString(totalSavings));
        callback(result);
    },

    /**
     * @param {!WebInspector.NetworkRequest} request
     */
    _isCompressed: function(request)
    {
        var encodingHeader = request.responseHeaderValue("Content-Encoding");
        if (!encodingHeader)
            return false;

        return /\b(?:gzip|deflate)\b/.test(encodingHeader);
    },

    /**
     * @param {!WebInspector.NetworkRequest} request
     */
    _shouldCompress: function(request)
    {
        return request.resourceType().isTextType() && request.parsedURL.host && request.resourceSize !== undefined && request.resourceSize > 150;
    },

    __proto__: WebInspector.AuditRule.prototype
}

/**
 * @constructor
 * @extends {WebInspector.AuditRule}
 */
WebInspector.AuditRules.CombineExternalResourcesRule = function(id, name, type, resourceTypeName, allowedPerDomain)
{
    WebInspector.AuditRule.call(this, id, name);
    this._type = type;
    this._resourceTypeName = resourceTypeName;
    this._allowedPerDomain = allowedPerDomain;
}

WebInspector.AuditRules.CombineExternalResourcesRule.prototype = {
    /**
     * @param {!WebInspector.Target} target
     * @param {!Array.<!WebInspector.NetworkRequest>} requests
     * @param {!WebInspector.AuditRuleResult} result
     * @param {function(?WebInspector.AuditRuleResult)} callback
     * @param {!WebInspector.Progress} progress<commit_msg>DevTools: add JsDocs to CombineExternalResourcesRule constructor<commit_after>/*
 * Copyright (C) 2010 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

WebInspector.AuditRules.IPAddressRegexp = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;

WebInspector.AuditRules.CacheableResponseCodes =
{
    200: true,
    203: true,
    206: true,
    300: true,
    301: true,
    410: true,

    304: true // Underlying request is cacheable
}

/**
 * @param {!Array.<!WebInspector.NetworkRequest>} requests
 * @param {?Array.<!WebInspector.resourceTypes>} types
 * @param {boolean} needFullResources
 * @return {!Object.<string, !Array.<!WebInspector.NetworkRequest|string>>}
 */
WebInspector.AuditRules.getDomainToResourcesMap = function(requests, types, needFullResources)
{
    var domainToResourcesMap = {};
    for (var i = 0, size = requests.length; i < size; ++i) {
        var request = requests[i];
        if (types && types.indexOf(request.resourceType()) === -1)
            continue;
        var parsedURL = request.url.asParsedURL();
        if (!parsedURL)
            continue;
        var domain = parsedURL.host;
        var domainResources = domainToResourcesMap[domain];
        if (domainResources === undefined) {
          domainResources = [];
          domainToResourcesMap[domain] = domainResources;
        }
        domainResources.push(needFullResources ? request : request.url);
    }
    return domainToResourcesMap;
}

/**
 * @constructor
 * @extends {WebInspector.AuditRule}
 */
WebInspector.AuditRules.GzipRule = function()
{
    WebInspector.AuditRule.call(this, "network-gzip", WebInspector.UIString("Enable gzip compression"));
}

WebInspector.AuditRules.GzipRule.prototype = {
    /**
     * @param {!WebInspector.Target} target
     * @param {!Array.<!WebInspector.NetworkRequest>} requests
     * @param {!WebInspector.AuditRuleResult} result
     * @param {function(?WebInspector.AuditRuleResult)} callback
     * @param {!WebInspector.Progress} progress
     */
    doRun: function(target, requests, result, callback, progress)
    {
        var totalSavings = 0;
        var compressedSize = 0;
        var candidateSize = 0;
        var summary = result.addChild("", true);
        for (var i = 0, length = requests.length; i < length; ++i) {
            var request = requests[i];
            if (request.cached() || request.statusCode === 304)
                continue; // Do not test cached resources.
            if (this._shouldCompress(request)) {
                var size = request.resourceSize;
                candidateSize += size;
                if (this._isCompressed(request)) {
                    compressedSize += size;
                    continue;
                }
                var savings = 2 * size / 3;
                totalSavings += savings;
                summary.addFormatted("%r could save ~%s", request.url, Number.bytesToString(savings));
                result.violationCount++;
            }
        }
        if (!totalSavings) {
            callback(null);
            return;
        }
        summary.value = WebInspector.UIString("Compressing the following resources with gzip could reduce their transfer size by about two thirds (~%s):", Number.bytesToString(totalSavings));
        callback(result);
    },

    /**
     * @param {!WebInspector.NetworkRequest} request
     */
    _isCompressed: function(request)
    {
        var encodingHeader = request.responseHeaderValue("Content-Encoding");
        if (!encodingHeader)
            return false;

        return /\b(?:gzip|deflate)\b/.test(encodingHeader);
    },

    /**
     * @param {!WebInspector.NetworkRequest} request
     */
    _shouldCompress: function(request)
    {
        return request.resourceType().isTextType() && request.parsedURL.host && request.resourceSize !== undefined && request.resourceSize > 150;
    },

    __proto__: WebInspector.AuditRule.prototype
}

/**
 * @constructor
 * @extends {WebInspector.AuditRule}
 * @param {string} id
 * @param {string} name
 * @param {!WebInspector.ResourceType} type
 * @param {string} resourceTypeName
 * @param {boolean} allowedPerDomain
 */
WebInspector.AuditRules.CombineExternalResourcesRule = function(id, name, type, resourceTypeName, allowedPerDomain)
{
    WebInspector.AuditRule.call(this, id, name);
    this._type = type;
    this._resourceTypeName = resourceTypeName;
    this._allowedPerDomain = allowedPerDomain;
}

WebInspector.AuditRules.CombineExternalResourcesRule.prototype = {
    /**
     * @param {!WebInspector.Target} target
     * @param {!Array.<!WebInspector.NetworkRequest>} requests
     * @param {!WebInspector.AuditRuleResult} result
     * @param {function(?WebInspector.AuditRuleResult)} callback
     * @param {!WebInspector.Progress} progress
{'fraction_non_alphanumeric': 0.10570360740981476, 'fraction_numerical': 0.007637309067273318, 'mean_word_length': 3.046351084812623, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4033972', 'n_tokens_mistral': 3505, 'n_tokens_neox': 3299, 'n_words': 975}