Skip to content

Commit 4b158f1

Browse files
lib: add the Navigator object
Add the Navigator object with the Device Memory API. Refs: #39540 Refs: https://html.spec.whatwg.org/multipage/system-state.html#the-navigator-object Refs: https://w3c.github.io/device-memory Co-authored-by: Voltrex <mohammadkeyvanzade94@gmail.com>
1 parent 4350262 commit 4b158f1

17 files changed

Lines changed: 227 additions & 4 deletions

File tree

.eslintrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,5 +361,6 @@ module.exports = {
361361
btoa: 'readable',
362362
atob: 'readable',
363363
performance: 'readable',
364+
navigator: 'readable',
364365
},
365366
};

doc/api/globals.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,58 @@ The `MessagePort` class. See [`MessagePort`][] for more details.
295295

296296
This variable may appear to be global but is not. See [`module`][].
297297

298+
## `navigator`
299+
<!-- YAML
300+
added: REPLACEME
301+
-->
302+
303+
> Stability: 1 - Experimental
304+
305+
An implementation of the [Navigator API][]. Similar to [`window.navigator`][]
306+
in browsers.
307+
308+
### `navigator.deviceMemory`
309+
<!-- YAML
310+
added: REPLACEME
311+
-->
312+
313+
* {number}
314+
315+
The total amount of device memory in GiB, rounded to the nearest power of 2,
316+
between 0.25 and 8 GiB. Part of the [Device Memory API][].
317+
318+
```js
319+
console.log(`This device has ${navigator.deviceMemory} GiB of RAM`);
320+
```
321+
322+
### `navigator.hardwareConcurrency`
323+
<!-- YAML
324+
added: REPLACEME
325+
-->
326+
327+
* {integer}
328+
329+
The number of logical processors.
330+
331+
```js
332+
console.log(`This device has ${navigator.hardwareConcurrency} logical CPUs`);
333+
```
334+
335+
### `navigator.platform`
336+
<!-- YAML
337+
added: REPLACEME
338+
-->
339+
340+
* {string}
341+
342+
A string identifying the operating system platform on which the Node.js process
343+
is running. For example, it returns 'Linux' on Linux, 'Darwin' on macOS, and
344+
'Win32' on Windows.
345+
346+
```js
347+
console.log(`This process is running on ${navigator.platform}`);
348+
```
349+
298350
## `performance`
299351

300352
The [`perf_hooks.performance`][] object.
@@ -429,6 +481,8 @@ The object that acts as the namespace for all W3C
429481
[WebAssembly][webassembly-org] related functionality. See the
430482
[Mozilla Developer Network][webassembly-mdn] for usage and compatibility.
431483

484+
[Device Memory API]: https://w3c.github.io/device-memory/
485+
[Navigator API]: https://html.spec.whatwg.org/multipage/system-state.html#the-navigator-object
432486
[`AbortController`]: https://developer.mozilla.org/en-US/docs/Web/API/AbortController
433487
[`EventTarget` and `Event` API]: events.md#event-target-and-event-api
434488
[`MessageChannel`]: worker_threads.md#worker_threads_class_messagechannel
@@ -455,6 +509,7 @@ The object that acts as the namespace for all W3C
455509
[`setImmediate`]: timers.md#timers_setimmediate_callback_args
456510
[`setInterval`]: timers.md#timers_setinterval_callback_delay_args
457511
[`setTimeout`]: timers.md#timers_settimeout_callback_delay_args
512+
[`window.navigator`]: https://developer.mozilla.org/en-US/docs/Web/API/Window/navigator
458513
[buffer section]: buffer.md
459514
[built-in objects]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects
460515
[module system documentation]: modules.md

lib/internal/bootstrap/node.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,14 @@ if (!config.noBrowserGlobals) {
241241

242242
defineOperation(globalThis, 'queueMicrotask', queueMicrotask);
243243

244+
// https://html.spec.whatwg.org/multipage/system-state.html#the-navigator-object
245+
ObjectDefineProperty(globalThis, 'navigator', {
246+
enumerable: true,
247+
configurable: true,
248+
writable: false,
249+
value: require('internal/navigator'),
250+
});
251+
244252
// https://www.w3.org/TR/hr-time-2/#the-performance-attribute
245253
defineReplacableAttribute(globalThis, 'performance',
246254
require('perf_hooks').performance);

lib/internal/navigator.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
'use strict';
2+
3+
const {
4+
ObjectDefineProperties,
5+
ObjectSetPrototypeOf,
6+
MathClz32,
7+
} = primordials;
8+
9+
const {
10+
codes: {
11+
ERR_ILLEGAL_CONSTRUCTOR,
12+
}
13+
} = require('internal/errors');
14+
15+
const {
16+
getCPUs,
17+
getOSInformation,
18+
getTotalMem,
19+
} = internalBinding('os');
20+
21+
class Navigator {
22+
constructor() {
23+
throw new ERR_ILLEGAL_CONSTRUCTOR();
24+
}
25+
}
26+
27+
class InternalNavigator {}
28+
InternalNavigator.prototype.constructor = Navigator.prototype.constructor;
29+
ObjectSetPrototypeOf(InternalNavigator.prototype, Navigator.prototype);
30+
31+
function getDeviceMemory() {
32+
const mem = getTotalMem() / 1024 / 1024;
33+
if (mem <= 0.25 * 1024) return 0.25;
34+
if (mem >= 8 * 1024) return 8;
35+
const lowerBound = 1 << 31 - MathClz32(mem - 1);
36+
const upperBound = lowerBound * 2;
37+
return mem - lowerBound <= upperBound - mem ?
38+
lowerBound / 1024 :
39+
upperBound / 1024;
40+
}
41+
42+
function getPlatform() {
43+
if (process.platform === 'win32') return 'Win32';
44+
if (process.platform === 'android') return 'Android';
45+
return getOSInformation()[0];
46+
}
47+
48+
const cpuData = getCPUs();
49+
ObjectDefineProperties(Navigator.prototype, {
50+
deviceMemory: {
51+
configurable: true,
52+
enumerable: true,
53+
value: getDeviceMemory(),
54+
},
55+
hardwareConcurrency: {
56+
configurable: true,
57+
enumerable: true,
58+
value: cpuData ? cpuData.length / 7 : 1,
59+
},
60+
platform: {
61+
configurable: true,
62+
enumerable: true,
63+
value: getPlatform(),
64+
},
65+
});
66+
67+
module.exports = new InternalNavigator();

test/common/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,9 @@ if (global.AbortController)
282282
if (global.gc) {
283283
knownGlobals.push(global.gc);
284284
}
285-
285+
if (global.navigator) {
286+
knownGlobals.push(global.navigator);
287+
}
286288
if (global.performance) {
287289
knownGlobals.push(global.performance);
288290
}

test/fixtures/wpt/LICENSE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# The 3-Clause BSD License
22

3-
Copyright 2019 web-platform-tests contributors
3+
Copyright © web-platform-tests contributors
44

55
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
66

test/fixtures/wpt/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,15 @@ Last update:
1212

1313
- common: https://github.com/web-platform-tests/wpt/tree/bb97a68974/common
1414
- console: https://github.com/web-platform-tests/wpt/tree/3b1f72e99a/console
15+
- device-memory: https://github.com/web-platform-tests/wpt/tree/c0cdd63f19/device-memory
1516
- dom/abort: https://github.com/web-platform-tests/wpt/tree/1728d198c9/dom/abort
1617
- encoding: https://github.com/web-platform-tests/wpt/tree/35f70910d3/encoding
1718
- FileAPI: https://github.com/web-platform-tests/wpt/tree/3b279420d4/FileAPI
1819
- hr-time: https://github.com/web-platform-tests/wpt/tree/9910784394/hr-time
1920
- html/webappapis/atob: https://github.com/web-platform-tests/wpt/tree/f267e1dca6/html/webappapis/atob
2021
- html/webappapis/microtask-queuing: https://github.com/web-platform-tests/wpt/tree/2c5c3c4c27/html/webappapis/microtask-queuing
2122
- html/webappapis/timers: https://github.com/web-platform-tests/wpt/tree/5873f2d8f1/html/webappapis/timers
22-
- interfaces: https://github.com/web-platform-tests/wpt/tree/80a4176623/interfaces
23+
- interfaces: https://github.com/web-platform-tests/wpt/tree/fc086c82d5/interfaces
2324
- performance-timeline: https://github.com/web-platform-tests/wpt/tree/17ebc3aea0/performance-timeline
2425
- resources: https://github.com/web-platform-tests/wpt/tree/972ca5b669/resources
2526
- streams: https://github.com/web-platform-tests/wpt/tree/8f60d94439/streams
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
spec: https://w3c.github.io/device-memory/
2+
suggested_reviewers:
3+
- npm1
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
test(function() {
2+
assert_equals(typeof navigator.deviceMemory, "number",
3+
"navigator.deviceMemory returns a number");
4+
assert_true(navigator.deviceMemory >= 0,
5+
"navigator.deviceMemory returns a positive value");
6+
assert_true([0.25, 0.5, 1, 2, 4, 8].includes(navigator.deviceMemory),
7+
"navigator.deviceMemory returns a power of 2 between 0.25 and 8");
8+
}, "navigator.deviceMemory is a positive number, a power of 2, between 0.25 and 8");
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// META: script=/resources/WebIDLParser.js
2+
// META: script=/resources/idlharness.js
3+
// META: timeout=long
4+
5+
// https://w3c.github.io/device-memory/
6+
7+
"use strict";
8+
9+
idl_test(
10+
['device-memory'],
11+
['html'],
12+
async idl_array => {
13+
if (self.GLOBAL.isWorker()) {
14+
idl_array.add_objects({ WorkerNavigator: ['navigator'] });
15+
} else {
16+
idl_array.add_objects({ Navigator: ['navigator'] });
17+
}
18+
}
19+
);

0 commit comments

Comments
 (0)