Skip to content

Commit

Permalink
feat(mutation): notify change intersection (#15)
Browse files Browse the repository at this point in the history
* chore: remove redundant code
* refactor: clean up mutation polyfill
* feat: add MutationObserver to global
* refactor: remove casts
* feat(mutation): add better change notification.
* feat: remove redundent dispose.
* refactor: clean up mutation-observer methods
* fix: debounce change events
* closes #14
  • Loading branch information
MeirionHughes authored Oct 2, 2016
1 parent e577862 commit 12266c7
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 108 deletions.
18 changes: 1 addition & 17 deletions spec/mutation-observer.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { buildPal } from '../src/nodejs-pal-builder';
import { disposeObservers } from '../src/polyfills/mutation-observer';

describe("MutationObserver", () => {
let pal, observer, dom, document;
Expand Down Expand Up @@ -262,20 +261,5 @@ describe("MutationObserver", () => {

expect(records.length).toBe(1);
expect(records[0].oldValue).toBe('Foo');
});

it("can dispose observers via global disposeObservers method", function () {
var pal = buildPal();
var dom = pal.dom;
var document = pal.global.window.document;
var div = document.createElement('div');

dom.createMutationObserver((changes) => { }).observe(div, {
attributes: true,
characterData: true,
childList: true
});

disposeObservers(); // without this test-runner will never end.
});
});
});
1 change: 1 addition & 0 deletions src/global.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export interface IGlobal extends Window {
MutationObserver: typeof MutationObserver;
Element: typeof Element;
SVGElement: typeof SVGElement;
XMLHttpRequest: typeof XMLHttpRequest;
Expand Down
10 changes: 1 addition & 9 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { initializePAL } from 'aurelia-pal';
import { buildPal } from './nodejs-pal-builder';
import { disposeObservers } from './polyfills/mutation-observer';

let isInitialized = false;

Expand Down Expand Up @@ -68,11 +67,4 @@ export function initialize(): void {
}
});
});
}

/**
* Terminate any long-life timers
*/
export function terminate() {
disposeObservers();
}
}
4 changes: 2 additions & 2 deletions src/nodejs-dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ export class NodeJsDom implements IDom {

constructor(public global: IGlobal) {

this.Element = (<any>global).Element;
this.SVGElement = (<any>global).SVGElement;
this.Element = global.Element;
this.SVGElement = global.SVGElement;
}

Element: typeof Element;
Expand Down
79 changes: 68 additions & 11 deletions src/nodejs-pal-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,80 @@ import { NodeJsPlatform } from './nodejs-platform';
import { NodeJsFeature } from './nodejs-feature';
import { NodeJsDom } from './nodejs-dom';
import { jsdom } from 'jsdom';
import { MutationObserver } from './polyfills/mutation-observer';
import { MutationNotifier } from './polyfills/mutation-observer';

let _patchedjsdom = false;

export function buildPal(): { global: IGlobal, platform: IPlatform, dom: IDom, feature: IFeature } {
var _global: IGlobal = <IGlobal>jsdom(undefined, {}).defaultView;
var global: IGlobal = <IGlobal>jsdom(undefined, {}).defaultView;

if (!_patchedjsdom) {
patchNotifyChange(global);
_patchedjsdom = true;
}

ensurePerformance(_global.window);
ensureMutationObserver(_global.window);
ensurePerformance(global.window);
ensureMutationObserver(global.window);

var _platform = new NodeJsPlatform(_global);
var _dom = new NodeJsDom(_global);
var _feature = new NodeJsFeature(_global);
var platform = new NodeJsPlatform(global);
var dom = new NodeJsDom(global);
var feature = new NodeJsFeature(global);

return {
global: _global,
platform: _platform,
dom: _dom,
feature: _feature
global: global,
platform: platform,
dom: dom,
feature: feature
};
}

let intersectSetter = function (proto, propertyName: string, intersect: Function) {

This comment has been minimized.

Copy link
@atsu85

atsu85 Oct 9, 2016

typo? "intersect" vs "intercept"?

This comment has been minimized.

Copy link
@MeirionHughes

MeirionHughes Oct 9, 2016

Author Contributor

intercept is probably what I was after yes.

let old = Object.getOwnPropertyDescriptor(proto, propertyName);
let oldSet = old.set;
let newSet = function set(V) {
oldSet.call(this, V);
intersect(this);
};
Object.defineProperty(proto, propertyName, {
set: newSet,
get: old.get,
configurable: old.configurable,
enumerable: old.enumerable
});
};

let intersectMethod = function (proto, methodName: string, intersect: Function) {

This comment has been minimized.

Copy link
@atsu85

atsu85 Oct 9, 2016

typo?

let orig = proto[methodName];
proto[methodName] = function (...args) {
var ret = orig.apply(this, args);
intersect(this);
return ret;
};
};

function patchNotifyChange(window: Window) {
let notifyInstance = MutationNotifier.getInstance();
let notify = function (node: Node) { notifyInstance.notifyChanged(node); };

let node_proto = (<any>window)._core.Node.prototype;

intersectMethod(node_proto, "appendChild", notify);
intersectMethod(node_proto, "insertBefore", notify);
intersectMethod(node_proto, "removeChild", notify);
intersectMethod(node_proto, "replaceChild", notify);
intersectSetter(node_proto, "nodeValue", notify);
intersectSetter(node_proto, "textContent", notify);

let element_proto = (<any>window)._core.Element.prototype;

intersectMethod(element_proto, "setAttribute", notify);
intersectMethod(element_proto, "removeAttribute", notify);
intersectMethod(element_proto, "removeAttributeNode", notify);
intersectMethod(element_proto, "removeAttributeNS", notify);
}


function ensurePerformance(window) {
if (window.performance === undefined) {
window.performance = {};
Expand All @@ -45,5 +100,7 @@ function ensurePerformance(window) {
}

function ensureMutationObserver(window) {
require('./polyfills/mutation-observer').polyfill(window);
if (!window.MutationObserver) {
window.MutationObserver = MutationObserver;
}
}
Loading

0 comments on commit 12266c7

Please sign in to comment.