diff --git a/closure/closure-type-checking.js b/closure/closure-type-checking.js index 53e700d34db1..7a4b5f43b3ad 100755 --- a/closure/closure-type-checking.js +++ b/closure/closure-type-checking.js @@ -21,22 +21,26 @@ const closureCompiler = require('google-closure-compiler').gulp(); const gulp = require('gulp'); const gutil = require('gulp-util'); const replace = require('gulp-replace'); -const devtoolsRequire = - 'const DevtoolsTimelineModel = require(\'../lib/traces/devtools-timeline-model\');'; /* eslint-disable camelcase */ gulp.task('js-compile', function() { return gulp.src([ 'closure/typedefs/*.js', 'closure/third_party/*.js', - 'audits/**/*.js', - 'lib/icons.js', - 'aggregators/**/*.js' + 'src/audits/**/*.js', + 'src/lib/icons.js', + 'src/aggregators/**/*.js' ]) // TODO: hack to remove `require`s that Closure currently can't resolve. - .pipe(replace(devtoolsRequire, '')) .pipe(replace('require(\'../../lib/web-inspector\').Color.parse;', 'WebInspector.Color.parse;')) + .pipe(replace('require(\'../../lib/traces/tracing-processor\');', '/** @type {?} */ (null);')) + .pipe(replace('require(\'speedline\');', 'function(arg) {};')) + .pipe(replace('require(\'../../../formatters/formatter\');', '{};')) + + // Replace any non-local import (e.g. not starting with .) with a dummy type. These are likely + // the built-in Node modules. But not always, so TODO(samthor): Fix this. + .pipe(replace(/require\(\'[^\.].*?\'\)/g, '/** @type {*} */ ({})')) .pipe(closureCompiler({ compilation_level: 'SIMPLE', diff --git a/closure/third_party/node.js b/closure/third_party/node.js new file mode 100644 index 000000000000..20fe7018b45d --- /dev/null +++ b/closure/third_party/node.js @@ -0,0 +1,27 @@ +/** + * @license + * Copyright 2016 Google Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @externs + */ + +/** @type {string} */ +var __dirname = ''; + +/** @type {!Object} */ +var global = {}; + diff --git a/closure/typedefs/Aggregation.js b/closure/typedefs/Aggregation.js index f495b2d125e1..3f05cf7a5dc3 100644 --- a/closure/typedefs/Aggregation.js +++ b/closure/typedefs/Aggregation.js @@ -74,6 +74,15 @@ AggregationCriterion.prototype.value; /** @type {number} */ AggregationCriterion.prototype.weight; +/** @type {boolean|undefined} */ +AggregationCriterion.prototype.comingSoon; + +/** @type {string|undefined} */ +AggregationCriterion.prototype.category; + +/** @type {string|undefined} */ +AggregationCriterion.prototype.description; + /** * @typedef {!Object} */ diff --git a/closure/typedefs/Artifacts.js b/closure/typedefs/Artifacts.js index 1ac21c8a7120..5eae05e1a267 100644 --- a/closure/typedefs/Artifacts.js +++ b/closure/typedefs/Artifacts.js @@ -56,5 +56,14 @@ Artifacts.prototype.viewport; /** @type {number} */ Artifacts.prototype.responseCode; +/** @type {number} */ +Artifacts.prototype.offlineResponseCode; + +/** @type {{value: boolean, debugString: (string|undefined)}} */ +Artifacts.prototype.redirectsHTTP; + /** @type {!Accessibility} */ Artifacts.prototype.accessibility; + +/** @type {!Object} */ +Artifacts.prototype.criticalRequestChains; diff --git a/closure/typedefs/AuditResult.js b/closure/typedefs/AuditResult.js index 9c07e4f2defa..be295d6e6b25 100644 --- a/closure/typedefs/AuditResult.js +++ b/closure/typedefs/AuditResult.js @@ -38,16 +38,20 @@ AuditResultInput.prototype.debugString; /** @type {(boolean|number|string|undefined|null)} */ AuditResultInput.prototype.optimalValue; +/** @type {(AuditExtendedInfo|undefined|null)} */ +AuditResultInput.prototype.extendedInfo; + + /** * @struct * @record */ function AuditExtendedInfo() {} -/** @type {!string} */ +/** @type {string} */ AuditExtendedInfo.prototype.formatter; -/** @type {!Object} */ +/** @type {Object|undefined} */ AuditExtendedInfo.prototype.value; /** @@ -71,11 +75,14 @@ AuditResult.prototype.optimalValue; /** @type {(AuditExtendedInfo|undefined|null)} */ AuditResult.prototype.extendedInfo; -/** @type {string} */ +/** @type {(string|undefined)} */ AuditResult.prototype.name; -/** @type {string} */ +/** @type {(string|undefined)} */ AuditResult.prototype.category; -/** @type {string} */ +/** @type {(string|undefined)} */ AuditResult.prototype.description; + +/** @type {(boolean|undefined)} */ +AuditResult.prototype.contributesToScore; diff --git a/package.json b/package.json index 526d268bc382..5651b3d56009 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "devDependencies": { "eslint": "^2.4.0", "eslint-config-google": "^0.4.0", - "google-closure-compiler": "^20160315.0.0", + "google-closure-compiler": "^20160517.0.0", "gulp": "^3.9.1", "gulp-replace": "^0.5.4", "gulp-util": "^3.0.7", diff --git a/src/aggregators/aggregate.js b/src/aggregators/aggregate.js index 92a65f8a1da9..eb965c97ecb9 100644 --- a/src/aggregators/aggregate.js +++ b/src/aggregators/aggregate.js @@ -82,7 +82,7 @@ class Aggregate { */ static _filterResultsByAuditNames(results, expected) { const expectedNames = Object.keys(expected); - return results.filter(r => expectedNames.indexOf(r.name) !== -1); + return results.filter(r => expectedNames.indexOf(/** @type {string} */ (r.name)) !== -1); } /** @@ -206,7 +206,7 @@ class Aggregate { // TODO(paullewis): Remove once coming soon audits have landed. if (expected[e].comingSoon) { subItems.push({ - value: String.raw`¯\_(ツ)_/¯`, + value: '¯\\_(ツ)_/¯', // TODO(samthor): Patch going to Closure, String.raw is badly typed name: 'coming-soon', category: expected[e].category, description: expected[e].description, diff --git a/src/aggregators/is-performant/index.js b/src/aggregators/is-performant/index.js index 4870fef7aa8c..d1074ccd0d09 100644 --- a/src/aggregators/is-performant/index.js +++ b/src/aggregators/is-performant/index.js @@ -26,7 +26,7 @@ const firstMeaningfulPaint = require('../../audits/performance/first-meaningful- const speedIndexMetric = require('../../audits/performance/speed-index-metric').name; // TODO: https://github.com/GoogleChrome/lighthouse/issues/336 -/** @type {string} */ +// /** @type {string} */ // const inputReadinessMetric = require('../../audits/performance/input-readiness-metric').name; class IsPerformant extends Aggregate { diff --git a/src/audits/performance/critical-request-chains.js b/src/audits/performance/critical-request-chains.js index 282e759bee92..7c8a3a4ffc77 100644 --- a/src/audits/performance/critical-request-chains.js +++ b/src/audits/performance/critical-request-chains.js @@ -63,7 +63,7 @@ class CriticalRequestChains extends Audit { */ static audit(artifacts) { let chainCount = 0; - function walk(node, depth, startTime) { + function walk(node, depth) { const children = Object.keys(node); // Since a leaf node indicates the end of a chain, we can inspect the number @@ -74,7 +74,7 @@ class CriticalRequestChains extends Audit { children.forEach(id => { const child = node[id]; - walk(child.children, depth + 1, startTime); + walk(child.children, depth + 1); }, ''); } diff --git a/src/audits/performance/first-meaningful-paint.js b/src/audits/performance/first-meaningful-paint.js index 79a6a59ef8a2..80fb98789c20 100644 --- a/src/audits/performance/first-meaningful-paint.js +++ b/src/audits/performance/first-meaningful-paint.js @@ -68,7 +68,7 @@ class FirstMeaningfulPaint extends Audit { * @see https://github.com/GoogleChrome/lighthouse/issues/26 * @see https://docs.google.com/document/d/1BR94tJdZLsin5poeet0XoTW60M0SjvOJQttKT-JK8HI/view * @param {!Artifacts} artifacts The artifacts from the gather phase. - * @return {!AuditResult} The score from the audit, ranging from 0-100. + * @return {!Promise} The score from the audit, ranging from 0-100. */ static audit(artifacts) { return new Promise((resolve, reject) => { @@ -241,8 +241,9 @@ module.exports = FirstMeaningfulPaint; /** * Math.max, but with NaN values removed + * @param {...number} _ */ -function max() { +function max(_) { const args = [...arguments].filter(val => !isNaN(val)); return Math.max.apply(Math, args); } diff --git a/src/audits/performance/speed-index-metric.js b/src/audits/performance/speed-index-metric.js index 4b24b7d6b17d..4f510b6643a7 100644 --- a/src/audits/performance/speed-index-metric.js +++ b/src/audits/performance/speed-index-metric.js @@ -68,7 +68,7 @@ class SpeedIndexMetric extends Audit { * Audits the page to give a score for the Speed Index. * @see https://github.com/GoogleChrome/lighthouse/issues/197 * @param {!Artifacts} artifacts The artifacts from the gather phase. - * @return {!AuditResult} The score from the audit, ranging from 0-100. + * @return {!Promise} The score from the audit, ranging from 0-100. */ static audit(artifacts) { return Promise.resolve(artifacts.traceContents).then(trace => {