Get rid of global GrEtagDecorator
* Replace the global GrEtagDecorator variable with named imports. * Update gr-app-global-var-init.js Change-Id: I66a3cb81801c1c41927271d99ac5f165629d74c4
This commit is contained in:
@@ -176,7 +176,6 @@ module.exports = {
|
||||
"GrChangeViewApi": "readonly",
|
||||
"GrCountStringFormatter": "readonly",
|
||||
"GrEmailSuggestionsProvider": "readonly",
|
||||
"GrEtagDecorator": "readonly",
|
||||
"GrEventHelper": "readonly",
|
||||
"GrGroupSuggestionsProvider": "readonly",
|
||||
"GrLinkTextParser": "readonly",
|
||||
|
||||
@@ -37,6 +37,7 @@ import {GrChangeReplyInterface} from './shared/gr-js-api-interface/gr-change-rep
|
||||
import {GrEditConstants} from './edit/gr-edit-constants.js';
|
||||
import {GrFileListConstants} from './change/gr-file-list-constants.js';
|
||||
import {GrDomHooksManager, GrDomHook} from './plugins/gr-dom-hooks/gr-dom-hooks.js';
|
||||
import {GrEtagDecorator} from './shared/gr-rest-api-interface/gr-etag-decorator.js';
|
||||
|
||||
export function initGlobalVariables() {
|
||||
window.GrDisplayNameUtils = GrDisplayNameUtils;
|
||||
@@ -55,4 +56,5 @@ export function initGlobalVariables() {
|
||||
window.GrFileListConstants = GrFileListConstants;
|
||||
window.GrDomHooksManager = GrDomHooksManager;
|
||||
window.GrDomHook = GrDomHook;
|
||||
window.GrEtagDecorator = GrEtagDecorator;
|
||||
}
|
||||
|
||||
@@ -24,92 +24,83 @@ $_documentContainer.innerHTML = `<dom-module id="gr-etag-decorator">
|
||||
|
||||
document.head.appendChild($_documentContainer.content);
|
||||
|
||||
(function(window) {
|
||||
'use strict';
|
||||
// Limit cache size because /change/detail responses may be large.
|
||||
const MAX_CACHE_SIZE = 30;
|
||||
|
||||
// Prevent redefinition.
|
||||
if (window.GrEtagDecorator) { return; }
|
||||
/** @constructor */
|
||||
export function GrEtagDecorator() {
|
||||
this._etags = new Map();
|
||||
this._payloadCache = new Map();
|
||||
}
|
||||
|
||||
// Limit cache size because /change/detail responses may be large.
|
||||
const MAX_CACHE_SIZE = 30;
|
||||
|
||||
/** @constructor */
|
||||
function GrEtagDecorator() {
|
||||
this._etags = new Map();
|
||||
this._payloadCache = new Map();
|
||||
/**
|
||||
* Get or upgrade fetch options to include an ETag in a request.
|
||||
*
|
||||
* @param {string} url The URL being fetched.
|
||||
* @param {!Object=} opt_options Optional options object in which to include
|
||||
* the ETag request header. If omitted, the result will be a fresh option
|
||||
* set.
|
||||
* @return {!Object}
|
||||
*/
|
||||
GrEtagDecorator.prototype.getOptions = function(url, opt_options) {
|
||||
const etag = this._etags.get(url);
|
||||
if (!etag) {
|
||||
return opt_options;
|
||||
}
|
||||
const options = Object.assign({}, opt_options);
|
||||
options.headers = options.headers || new Headers();
|
||||
options.headers.set('If-None-Match', this._etags.get(url));
|
||||
return options;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get or upgrade fetch options to include an ETag in a request.
|
||||
*
|
||||
* @param {string} url The URL being fetched.
|
||||
* @param {!Object=} opt_options Optional options object in which to include
|
||||
* the ETag request header. If omitted, the result will be a fresh option
|
||||
* set.
|
||||
* @return {!Object}
|
||||
*/
|
||||
GrEtagDecorator.prototype.getOptions = function(url, opt_options) {
|
||||
const etag = this._etags.get(url);
|
||||
if (!etag) {
|
||||
return opt_options;
|
||||
/**
|
||||
* Handle a response to a request with ETag headers, potentially incorporating
|
||||
* its result in the payload cache.
|
||||
*
|
||||
* @param {string} url The URL of the request.
|
||||
* @param {!Response} response The response object.
|
||||
* @param {string} payload The raw, unparsed JSON contained in the response
|
||||
* body. Note: because response.text() cannot be read twice, this must be
|
||||
* provided separately.
|
||||
*/
|
||||
GrEtagDecorator.prototype.collect = function(url, response, payload) {
|
||||
if (!response ||
|
||||
!response.ok ||
|
||||
response.status !== 200 ||
|
||||
response.status === 304) {
|
||||
// 304 Not Modified means etag is still valid.
|
||||
return;
|
||||
}
|
||||
this._payloadCache.set(url, payload);
|
||||
const etag = response.headers && response.headers.get('etag');
|
||||
if (!etag) {
|
||||
this._etags.delete(url);
|
||||
} else {
|
||||
this._etags.set(url, etag);
|
||||
this._truncateCache();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the cached payload for a given URL.
|
||||
*
|
||||
* @param {string} url
|
||||
* @return {string|undefined} Returns the unparsed JSON payload from the
|
||||
* cache.
|
||||
*/
|
||||
GrEtagDecorator.prototype.getCachedPayload = function(url) {
|
||||
return this._payloadCache.get(url);
|
||||
};
|
||||
|
||||
/**
|
||||
* Limit the cache size to MAX_CACHE_SIZE.
|
||||
*/
|
||||
GrEtagDecorator.prototype._truncateCache = function() {
|
||||
for (const url of this._etags.keys()) {
|
||||
if (this._etags.size <= MAX_CACHE_SIZE) {
|
||||
break;
|
||||
}
|
||||
const options = Object.assign({}, opt_options);
|
||||
options.headers = options.headers || new Headers();
|
||||
options.headers.set('If-None-Match', this._etags.get(url));
|
||||
return options;
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle a response to a request with ETag headers, potentially incorporating
|
||||
* its result in the payload cache.
|
||||
*
|
||||
* @param {string} url The URL of the request.
|
||||
* @param {!Response} response The response object.
|
||||
* @param {string} payload The raw, unparsed JSON contained in the response
|
||||
* body. Note: because response.text() cannot be read twice, this must be
|
||||
* provided separately.
|
||||
*/
|
||||
GrEtagDecorator.prototype.collect = function(url, response, payload) {
|
||||
if (!response ||
|
||||
!response.ok ||
|
||||
response.status !== 200 ||
|
||||
response.status === 304) {
|
||||
// 304 Not Modified means etag is still valid.
|
||||
return;
|
||||
}
|
||||
this._payloadCache.set(url, payload);
|
||||
const etag = response.headers && response.headers.get('etag');
|
||||
if (!etag) {
|
||||
this._etags.delete(url);
|
||||
} else {
|
||||
this._etags.set(url, etag);
|
||||
this._truncateCache();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the cached payload for a given URL.
|
||||
*
|
||||
* @param {string} url
|
||||
* @return {string|undefined} Returns the unparsed JSON payload from the
|
||||
* cache.
|
||||
*/
|
||||
GrEtagDecorator.prototype.getCachedPayload = function(url) {
|
||||
return this._payloadCache.get(url);
|
||||
};
|
||||
|
||||
/**
|
||||
* Limit the cache size to MAX_CACHE_SIZE.
|
||||
*/
|
||||
GrEtagDecorator.prototype._truncateCache = function() {
|
||||
for (const url of this._etags.keys()) {
|
||||
if (this._etags.size <= MAX_CACHE_SIZE) {
|
||||
break;
|
||||
}
|
||||
this._etags.delete(url);
|
||||
this._payloadCache.delete(url);
|
||||
}
|
||||
};
|
||||
|
||||
window.GrEtagDecorator = GrEtagDecorator;
|
||||
})(window);
|
||||
this._etags.delete(url);
|
||||
this._payloadCache.delete(url);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -25,7 +25,8 @@ limitations under the License.
|
||||
<script src="/components/wct-browser-legacy/browser.js"></script>
|
||||
<script type="module">
|
||||
import '../../../test/common-test-setup.js';
|
||||
import './gr-etag-decorator.js';
|
||||
import {GrEtagDecorator} from './gr-etag-decorator.js';
|
||||
|
||||
suite('gr-etag-decorator', () => {
|
||||
let etag;
|
||||
let sandbox;
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
*/
|
||||
import '../../../scripts/bundled-polymer.js';
|
||||
|
||||
import './gr-etag-decorator.js';
|
||||
import './gr-rest-apis/gr-rest-api-helper.js';
|
||||
import './gr-auth.js';
|
||||
import './gr-reviewer-updates-parser.js';
|
||||
@@ -36,6 +35,7 @@ import 'whatwg-fetch/fetch.js';
|
||||
import {PatchSetBehavior} from '../../../behaviors/gr-patch-set-behavior/gr-patch-set-behavior.js';
|
||||
import {PathListBehavior} from '../../../behaviors/gr-path-list-behavior/gr-path-list-behavior.js';
|
||||
import {RESTClientBehavior} from '../../../behaviors/rest-client-behavior/rest-client-behavior.js';
|
||||
import {GrEtagDecorator} from './gr-etag-decorator.js';
|
||||
|
||||
const DiffViewMode = {
|
||||
SIDE_BY_SIDE: 'SIDE_BY_SIDE',
|
||||
|
||||
Reference in New Issue
Block a user