Skip to content

Commit 3708cab

Browse files
BrokenSourceCodeBrokenSourceCode
authored andcommitted
Allow numbers for the domDelay argument
1 parent 6c267c1 commit 3708cab

File tree

4 files changed

+205
-182
lines changed

4 files changed

+205
-182
lines changed

README.md

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,23 @@ $ npm install observable-slim --save
2929

3030
## Usage
3131

32-
3332
### Create an observer
3433

35-
The `create` method is the starting point for using Observable Slim. It is invoked to create a new ES6 Proxy whose changes we can observe. The `create` method accepts three parameters:
34+
The `create` method is the starting point for using Observable Slim. It is invoked to create a new ES6 `Proxy` whose changes we can observe. The `create` method accepts three parameters:
3635

37-
1. `target` - Object, required, plain JavaScript object that we want to observe for changes.
38-
2. `domDelay` - Boolean, required, if true, then Observable Slim will batch up observed changes to `target` on a 10ms delay (via `setTimeout`). If false, then `observer` will be immediately invoked after each individual change made to `target`. It is helpful to set `domDelay` to `true` when your `observer` function makes DOM manipulations (fewer DOM redraws means better performance).
39-
3. `observer` - Function, optional, will be invoked when a change is made to the proxy of `target`. When invoked, the `observer` function is passed a single argument -- an array detailing each change that has been made (see below).
36+
1. `target` (`object`, *required*): plain object that we want to observe for changes.
37+
2. `domDelay` (`boolean|number`, *required*): if `true`, then the observed changes to `target` will be batched up on a 10ms delay (via `setTimeout()`). If `false`, then the `observer` function will be immediately invoked after each individual change made to `target`. It is helpful to set `domDelay` to `true` when your `observer` function makes DOM manipulations (fewer DOM redraws means better performance). If a number greater than zero, then it defines the DOM delay in milliseconds.
38+
3. `observer` (`function(ObservableSlimChange[])`, *optional*): function that will be invoked when a change is made to the proxy of `target`. When invoked, this function is passed a single argument: an array of `ObservableSlimChange` detailing each change that has been made. The `ObservableSlimChange` object structure is like below:
39+
- `type` (`"add"|"update"|"delete"`, *required*): change type.
40+
- `property` (`string`, *required*): property name.
41+
- `currentPath` (`string`, *required*): property path with the dot notation (e.g. `foo.0.bar`).
42+
- `jsonPointer` (`string`, *required*): property path with the JSON pointer syntax (e.g. `/foo/0/bar`). See [](https://datatracker.ietf.org/doc/html/rfc6901).
43+
- `target` (`object`, *required*): target object.
44+
- `proxy` (`Proxy`, *required*): proxy of the target object.
45+
- `newValue` (`*`, *required*): new value of the property.
46+
- `previousValue` (`*`, *optional*): previous value of the property.
4047

41-
The `create` method will return a standard ES6 Proxy.
48+
The `create` method will return a standard ES6 `Proxy`.
4249

4350
```javascript
4451
var test = {};
@@ -226,9 +233,9 @@ console.log(p.test.deeper.__getPath); // logs "test.deeper"
226233

227234
## Requirements
228235

229-
For full functionality, Observable Slim requires [ES6 Proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy).
236+
For full functionality, Observable Slim requires [ES6 `Proxy`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy).
230237

231-
As of August 2017, ES6 Proxy is supported by Chrome 49+, Edge 12+, Firefox 18+, Opera 36+ and Safari 10+. Internet Explorer does not support ES6 Proxy.
238+
As of August 2017, ES6 `Proxy` is supported by Chrome 49+, Edge 12+, Firefox 18+, Opera 36+ and Safari 10+. Internet Explorer does not support ES6 `Proxy`.
232239

233240
### ES5 Proxy polyfill (IE11 support) ###
234241

@@ -238,7 +245,7 @@ The forked version of the Proxy polyfill (contained within this repo) differs fr
238245

239246
#### Limitations ####
240247

241-
Because the Proxy polyfill does not (and will never) fully emulate native ES6 Proxy, there are certain use cases that will not work when using Observable Slim with the Proxy polyfill:
248+
Because the Proxy polyfill does not (and will never) fully emulate native ES6 `Proxy`, there are certain use cases that will not work when using Observable Slim with the Proxy polyfill:
242249

243250
1. Object properties must be known at creation time. New properties cannot be added later.
244251
2. Modifications to `.length` cannot be observed.

observable-slim.js

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -34,22 +34,23 @@ var ObservableSlim = (function() {
3434
}, obj || self)
3535
};
3636

37-
/* Function: _create
38-
Private internal function that is invoked to create a new ES6 Proxy whose changes we can observe through
39-
the Observable.observe() method.
40-
41-
Parameters:
42-
target - required, plain JavaScript object that we want to observe for changes.
43-
domDelay - batch up changes on a 10ms delay so a series of changes can be processed in one DOM update.
44-
originalObservable - object, the original observable created by the user, exists for recursion purposes,
45-
allows one observable to observe change on any nested/child objects.
46-
originalPath - array of objects, each object having the properties 'target' and 'property' -- target referring to the observed object itself
47-
and property referring to the name of that object in the nested structure. the path of the property in relation to the target
48-
on the original observable, exists for recursion purposes, allows one observable to observe change on any nested/child objects.
49-
50-
Returns:
51-
An ES6 Proxy object.
52-
*/
37+
/**
38+
* Create a new ES6 `Proxy` whose changes we can observe through the `observe()` method.
39+
* @param {object} target Plain object that we want to observe for changes.
40+
* @param {boolean|number} domDelay If `true`, then the observed changes to `target` will be batched up on a 10ms delay (via `setTimeout()`).
41+
* If `false`, then the `observer` function will be immediately invoked after each individual change made to `target`. It is helpful to set
42+
* `domDelay` to `true` when your `observer` function makes DOM manipulations (fewer DOM redraws means better performance). If a number greater
43+
* than zero, then it defines the DOM delay in milliseconds.
44+
* @param {function(ObservableSlimChange[])} [observer] Function that will be invoked when a change is made to the proxy of `target`.
45+
* When invoked, this function is passed a single argument: an array of `ObservableSlimChange` detailing each change that has been made.
46+
* @param {object} originalObservable The original observable created by the user, exists for recursion purposes, allows one observable to observe
47+
* change on any nested/child objects.
48+
* @param {{target: object, property: string}[]} originalPath Array of objects, each object having the properties `target` and `property`:
49+
* `target` is referring to the observed object itself and `property` referring to the name of that object in the nested structure.
50+
* The path of the property in relation to the target on the original observable, exists for recursion purposes, allows one observable to observe
51+
* change on any nested/child objects.
52+
* @returns {ProxyConstructor} Proxy of the target object.
53+
*/
5354
var _create = function(target, domDelay, originalObservable, originalPath) {
5455

5556
var observable = originalObservable || null;
@@ -70,17 +71,14 @@ var ObservableSlim = (function() {
7071

7172
var changes = [];
7273

73-
/* Function: _getPath
74-
Returns a string of the nested path (in relation to the top-level observed object)
75-
of the property being modified or deleted.
76-
Parameters:
77-
target - the object whose property is being modified or deleted.
78-
property - the string name of the property
79-
jsonPointer - optional, set to true if the string path should be formatted as a JSON pointer.
80-
81-
Returns:
82-
String of the nested path (e.g., hello.testing.1.bar or, if JSON pointer, /hello/testing/1/bar
83-
*/
74+
/**
75+
* Returns a string of the nested path (in relation to the top-level observed object) of the property being modified or deleted.
76+
* @param {object} target Plain object that we want to observe for changes.
77+
* @param {string} property Property name.
78+
* @param {boolean} [jsonPointer] Set to `true` if the string path should be formatted as a JSON pointer rather than with the dot notation
79+
* (`false` as default).
80+
* @returns {string} Nested path (e.g., `hello.testing.1.bar` or, if JSON pointer, `/hello/testing/1/bar`).
81+
*/
8482
var _getPath = function(target, property, jsonPointer) {
8583

8684
var fullPath = "";
@@ -116,9 +114,11 @@ var ObservableSlim = (function() {
116114
// if the observable is paused, then we don't want to execute any of the observer functions
117115
if (observable.paused === true) return;
118116

117+
var domDelayIsNumber = typeof domDelay === 'number';
118+
119119
// execute observer functions on a 10ms setTimeout, this prevents the observer functions from being executed
120120
// separately on every change -- this is necessary because the observer functions will often trigger UI updates
121-
if (domDelay === true) {
121+
if (domDelayIsNumber || domDelay === true) {
122122
setTimeout(function() {
123123
if (numChanges === changes.length) {
124124

@@ -131,7 +131,7 @@ var ObservableSlim = (function() {
131131
for (var i = 0; i < observable.observers.length; i++) observable.observers[i](changesCopy);
132132

133133
}
134-
},10);
134+
}, (domDelayIsNumber && domDelay > 0) ? domDelay : 10);
135135
} else {
136136

137137
// we create a copy of changes before passing it to the observer functions because even if the observer function
@@ -542,9 +542,10 @@ var ObservableSlim = (function() {
542542
/**
543543
* Create a new ES6 `Proxy` whose changes we can observe through the `observe()` method.
544544
* @param {object} target Plain object that we want to observe for changes.
545-
* @param {boolean} domDelay If `true`, then the observed changes to `target` will be batched up on a 10ms delay (via `setTimeout()`).
545+
* @param {boolean|number} domDelay If `true`, then the observed changes to `target` will be batched up on a 10ms delay (via `setTimeout()`).
546546
* If `false`, then the `observer` function will be immediately invoked after each individual change made to `target`. It is helpful to set
547-
* `domDelay` to `true` when your `observer` function makes DOM manipulations (fewer DOM redraws means better performance).
547+
* `domDelay` to `true` when your `observer` function makes DOM manipulations (fewer DOM redraws means better performance). If a number greater
548+
* than zero, then it defines the DOM delay in milliseconds.
548549
* @param {function(ObservableSlimChange[])} [observer] Function that will be invoked when a change is made to the proxy of `target`.
549550
* When invoked, this function is passed a single argument: an array of `ObservableSlimChange` detailing each change that has been made.
550551
* @returns {ProxyConstructor} Proxy of the target object.

0 commit comments

Comments
 (0)