Skip to content

Commit b9e41a2

Browse files
authored
♻️ Define helper for hash params and drop barely-used getMode().log (ampproject#35628)
* Add getHashParams helper * Add win param * Update mode.js to use helper * Add tests * Update callsites * Remove getMode().log uses * Remove log from ModeDef type * Lint fixes * Fix tests * Split up isModeDevelopment
1 parent 0e66e28 commit b9e41a2

9 files changed

Lines changed: 87 additions & 52 deletions

File tree

extensions/amp-a4a/0.1/amp-a4a.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ import {
4242
createSecureFrame,
4343
isAttributionReportingSupported,
4444
} from './secure-frame';
45-
import {dev, devAssert, user, userAssert} from '../../../src/log';
45+
import {dev, devAssert, logHashParam, user, userAssert} from '../../../src/log';
4646
import {dict} from '#core/types/object';
4747
import {duplicateErrorIfNecessary} from '#core/error';
4848
import {
@@ -1323,7 +1323,7 @@ export class AmpA4A extends AMP.BaseElement {
13231323
// Additional arguments.
13241324
assignAdUrlToError(/** @type {!Error} */ (error), this.adUrl_);
13251325

1326-
if (getMode().development || getMode().localDev || getMode().log) {
1326+
if (getMode().development || getMode().localDev || logHashParam()) {
13271327
user().error(TAG, error);
13281328
} else {
13291329
user().warn(TAG, error);

src/core/types/string/url.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,15 @@ export function parseQueryString(queryString) {
5757
}
5858
return params;
5959
}
60+
61+
/**
62+
* Parses the query # params.
63+
* @param {!Window=} opt_win
64+
* @return {!JsonObject}
65+
*/
66+
export function getHashParams(opt_win) {
67+
const {location} = opt_win || self;
68+
// location.originalHash is set by the viewer when it removes the fragment
69+
// from the URL.
70+
return parseQueryString(location['originalHash'] || location.hash);
71+
}

src/log.js

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import {
3030
import * as mode from '#core/mode';
3131
import {isArray, isString} from '#core/types';
3232
import {once} from '#core/types/function';
33+
import {getHashParams} from '#core/types/string/url';
3334

3435
import {urls} from './config';
3536
import {getMode} from './mode';
@@ -108,6 +109,13 @@ const externalMessagesSimpleTableUrl = () =>
108109
const messageArgToEncodedComponent = (arg) =>
109110
encodeURIComponent(String(elementStringOrPassThru(arg)));
110111

112+
/**
113+
* @param {!Window=} opt_win
114+
* @return {number}
115+
*/
116+
export const logHashParam = (opt_win) =>
117+
parseInt(getHashParams(opt_win)['log'], 10);
118+
111119
/**
112120
* Logging class. Use of sentinel string instead of a boolean to check user/dev
113121
* errors because errors could be rethrown by some native code as a new error,
@@ -176,17 +184,18 @@ export class Log {
176184
* @private
177185
*/
178186
defaultLevel_() {
187+
const {win} = this;
179188
// No console - can't enable logging.
180189
if (
181-
!this.win.console?.log ||
190+
!win.console?.log ||
182191
// Logging has been explicitly disabled.
183-
getMode().log == 0
192+
logHashParam(win) == 0
184193
) {
185194
return LogLevel.OFF;
186195
}
187196

188197
// Logging is enabled for tests directly.
189-
if (getMode().test && this.win.ENABLE_LOG) {
198+
if (getMode().test && win.ENABLE_LOG) {
190199
return LogLevel.FINE;
191200
}
192201

@@ -199,12 +208,13 @@ export class Log {
199208
}
200209

201210
/**
211+
* @param {!Window=} opt_win provided for testing
202212
* @return {!LogLevel}
203213
* @private
204214
*/
205-
defaultLevelWithFunc_() {
215+
defaultLevelWithFunc_(opt_win) {
206216
// Delegate to the specific resolver.
207-
return this.levelFunc_(getMode().log, getMode().development);
217+
return this.levelFunc_(logHashParam(opt_win), getMode().development);
208218
}
209219

210220
/**

src/mode-object.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ export function getModeObject(opt_win) {
2828
development: getMode(opt_win).development,
2929
esm: IS_ESM,
3030
test: getMode(opt_win).test,
31-
log: getMode(opt_win).log,
3231
rtvVersion: getMode(opt_win).rtvVersion,
3332
};
3433
}

src/mode.js

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,13 @@
1515
*/
1616

1717
import * as coreMode from '#core/mode';
18-
import {parseQueryString} from '#core/types/string/url';
18+
import {getHashParams} from '#core/types/string/url';
1919

2020
/**
2121
* @typedef {{
2222
* localDev: boolean,
2323
* development: boolean,
2424
* test: boolean,
25-
* log: (string|undefined),
2625
* rtvVersion: string,
2726
* runtime: (null|string|undefined),
2827
* a4aId: (null|string|undefined),
@@ -57,24 +56,19 @@ export function getMode(opt_win) {
5756
* @return {!ModeDef}
5857
*/
5958
function getMode_(win) {
60-
const hashQuery = parseQueryString(
61-
// location.originalHash is set by the viewer when it removes the fragment
62-
// from the URL.
63-
win.location['originalHash'] || win.location.hash
64-
);
59+
const hashParams = getHashParams(win);
6560

6661
// The `minified`, `test` and `localDev` properties are replaced
6762
// as boolean literals when we run `amp dist` without the `--fortesting`
6863
// flags. This improved DCE on the production file we deploy as the code
6964
// paths for localhost/testing/development are eliminated.
7065
return {
7166
localDev: coreMode.isLocalDev(win),
72-
development: isModeDevelopment(win),
67+
development: isModeDevelopment(win, hashParams),
7368
esm: IS_ESM,
7469
// amp-geo override
75-
geoOverride: hashQuery['amp-geo'],
70+
geoOverride: hashParams['amp-geo'],
7671
test: coreMode.isTest(win),
77-
log: parseInt(hashQuery['log'], 10),
7872
rtvVersion: getRtvVersion(win),
7973
};
8074
}
@@ -104,17 +98,13 @@ function getRtvVersion(win) {
10498
* bypassed via #validate=0.
10599
* Note that AMP_DEV_MODE flag is used for testing purposes.
106100
* @param {!Window} win
101+
* @param {!JsonObject=} opt_hashParams
107102
* @return {boolean}
108103
*/
109-
export function isModeDevelopment(win) {
110-
const hashQuery = parseQueryString(
111-
win.location['originalHash'] || win.location.hash
112-
);
113-
return !!(
114-
['1', 'actions', 'amp', 'amp4ads', 'amp4email'].includes(
115-
hashQuery['development']
116-
) || win.AMP_DEV_MODE
117-
);
104+
export function isModeDevelopment(win, opt_hashParams) {
105+
const devModes = ['1', 'actions', 'amp', 'amp4ads', 'amp4email'];
106+
const devParam = opt_hashParams || getHashParams(win);
107+
return devModes.includes(devParam['development']) || !!win.AMP_DEV_MODE;
118108
}
119109

120110
/**

src/service/url-replacements-impl.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
import * as mode from '#core/mode';
1818
import {hasOwn} from '#core/types/object';
19-
import {parseQueryString} from '#core/types/string/url';
19+
import {getHashParams, parseQueryString} from '#core/types/string/url';
2020
import {WindowInterface} from '#core/window/interface';
2121

2222
import {Services} from '#service';
@@ -751,8 +751,7 @@ export class GlobalVariableSource extends VariableSource {
751751
'param is required'
752752
);
753753
userAssert(typeof param == 'string', 'param should be a string');
754-
const hash = this.ampdoc.win.location['originalHash'];
755-
const params = parseQueryString(hash);
754+
const params = getHashParams(this.ampdoc.win);
756755
return params[param] === undefined ? defaultValue : params[param];
757756
}
758757

src/validator-integration.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
import {parseQueryString} from '#core/types/string/url';
17+
import {getHashParams} from '#core/types/string/url';
1818

1919
import {urls} from './config';
2020
import {loadPromise} from './event-helper';
@@ -34,11 +34,9 @@ export function maybeValidate(win) {
3434
return;
3535
}
3636
let validator = false;
37-
if (isModeDevelopment(win)) {
38-
const hash = parseQueryString(
39-
win.location['originalHash'] || win.location.hash
40-
);
41-
validator = hash['validate'] !== '0';
37+
const params = getHashParams(win);
38+
if (isModeDevelopment(win, params)) {
39+
validator = params['validate'] !== '0';
4240
}
4341

4442
if (validator) {

test/unit/core/types/string/test-url.js

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
import {parseQueryString} from '#core/types/string/url';
17+
import {getHashParams, parseQueryString} from '#core/types/string/url';
1818

1919
describes.sandboxed('type helpers - strings - urls', {}, () => {
2020
describe('parseQueryString', () => {
@@ -68,4 +68,31 @@ describes.sandboxed('type helpers - strings - urls', {}, () => {
6868
});
6969
});
7070
});
71+
72+
describe('getHashParams', () => {
73+
it('parses the `originalHash`', () => {
74+
const params = getHashParams({
75+
location: {
76+
originalHash: '#development=1&original',
77+
hash: '#development=1&missingOriginal',
78+
},
79+
});
80+
81+
expect(params).to.deep.equal({
82+
'development': '1',
83+
'original': '',
84+
});
85+
});
86+
87+
it('parses the hash if `originalHash` is unset', () => {
88+
const params = getHashParams({
89+
location: {hash: '#development=1&missingOriginal'},
90+
});
91+
92+
expect(params).to.deep.equal({
93+
'development': '1',
94+
'missingOriginal': '',
95+
});
96+
});
97+
});
7198
});

test/unit/test-log.js

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ describes.sandboxed('Logging', {}, (env) => {
8383
});
8484

8585
it('should be disabled with hash param log=0', () => {
86-
mode.log = '0';
86+
win.location.hash = '#log=0';
8787
expect(new Log(win, RETURNS_FINE).level_).to.equal(LogLevel.OFF);
8888
});
8989

@@ -235,19 +235,19 @@ describes.sandboxed('Logging', {}, (env) => {
235235
});
236236

237237
it('should be enabled with log=1', () => {
238-
mode.log = '1';
239-
expect(user().defaultLevelWithFunc_()).to.equal(LogLevel.FINE);
238+
win.location.hash = '#log=1';
239+
expect(user().defaultLevelWithFunc_(win)).to.equal(LogLevel.FINE);
240240
});
241241

242242
it('should be enabled with log>1', () => {
243-
mode.log = '2';
244-
expect(user().defaultLevelWithFunc_()).to.equal(LogLevel.FINE);
243+
win.location.hash = '#log=2';
244+
expect(user().defaultLevelWithFunc_(win)).to.equal(LogLevel.FINE);
245245

246-
mode.log = '3';
247-
expect(user().defaultLevelWithFunc_()).to.equal(LogLevel.FINE);
246+
win.location.hash = '#log=3';
247+
expect(user().defaultLevelWithFunc_(win)).to.equal(LogLevel.FINE);
248248

249-
mode.log = '4';
250-
expect(user().defaultLevelWithFunc_()).to.equal(LogLevel.FINE);
249+
win.location.hash = '#log=4';
250+
expect(user().defaultLevelWithFunc_(win)).to.equal(LogLevel.FINE);
251251
});
252252

253253
it('should be configured with USER suffix', () => {
@@ -266,18 +266,18 @@ describes.sandboxed('Logging', {}, (env) => {
266266
});
267267

268268
it('should NOT be enabled with log=1', () => {
269-
mode.log = 1;
270-
expect(dev().defaultLevelWithFunc_()).to.equal(LogLevel.OFF);
269+
win.location.hash = '#log=1';
270+
expect(dev().defaultLevelWithFunc_(win)).to.equal(LogLevel.OFF);
271271
});
272272

273273
it('should be enabled as INFO with log=2', () => {
274-
mode.log = 2;
275-
expect(dev().defaultLevelWithFunc_()).to.equal(LogLevel.INFO);
274+
win.location.hash = '#log=2';
275+
expect(dev().defaultLevelWithFunc_(win)).to.equal(LogLevel.INFO);
276276
});
277277

278278
it('should be enabled as FINE with log=3', () => {
279-
mode.log = 3;
280-
expect(dev().defaultLevelWithFunc_()).to.equal(LogLevel.FINE);
279+
win.location.hash = '#log=3';
280+
expect(dev().defaultLevelWithFunc_(win)).to.equal(LogLevel.FINE);
281281
});
282282

283283
it('should be configured with no suffix', () => {

0 commit comments

Comments
 (0)