From 800db58216d1bc10cecba854d0242abdb54ef03a Mon Sep 17 00:00:00 2001 From: Wassim Chegham Date: Mon, 7 Mar 2016 21:11:33 +0100 Subject: [PATCH] feat(window): mocking window object --- custom_typings/server.d.ts | 6 + modules/universal/mock.js | 2 + .../universal/server/src/node/mock/window.ts | 182 ++++++++++++++++++ 3 files changed, 190 insertions(+) create mode 100644 modules/universal/mock.js create mode 100644 modules/universal/server/src/node/mock/window.ts diff --git a/custom_typings/server.d.ts b/custom_typings/server.d.ts index 439fc8138..0a8329580 100644 --- a/custom_typings/server.d.ts +++ b/custom_typings/server.d.ts @@ -4,3 +4,9 @@ declare module "xhr2" { nodejsSet(url: any): any; } } + +declare module NodeJS { + interface Global { + window: any | Window; + } +} diff --git a/modules/universal/mock.js b/modules/universal/mock.js new file mode 100644 index 000000000..ca7788c0d --- /dev/null +++ b/modules/universal/mock.js @@ -0,0 +1,2 @@ +var window = require('./dist/server/src/node/mock/window'); +global.window = window; diff --git a/modules/universal/server/src/node/mock/window.ts b/modules/universal/server/src/node/mock/window.ts new file mode 100644 index 000000000..c27bbc354 --- /dev/null +++ b/modules/universal/server/src/node/mock/window.ts @@ -0,0 +1,182 @@ +import {DOM} from 'angular2/src/platform/dom/dom_adapter'; +import {provide} from 'angular2/core'; + +// the overloaded "window" must extend node's "global" +// see: https://github.com/angular/angular/blob/master/modules/angular2/src/facade/lang.ts#L38 +var win = Object.create(global); + +/** + * Warn the developer about direct access to Window props + * @param {String} prop The property being accessed + */ +function beDefensive(prop){ + return (win).__defineGetter__(prop, () => { + console.warn(`[WARNING] Property/method "${prop}" should not be called directly. Use DomAdapter instead.`); + + // TODO(wassim): find a generic solution to proxify DomAdapter + // let doc = DOM.defaultDoc(); + // return DOM.querySelector(doc, ...args); + return prop; + }); +} + +let unforgeableAttributes = [ + "window", + "document", + "location", + "top" +].map(beDefensive); + +let replaceableAttributes = [ + "self", + "locationbar", + "menubar", + "personalbar", + "scrollbars", + "statusbar", + "toolbar", + "frames", + "parent", + "external", + "length", + + // CSSOM-View + "screen", + "scrollX", + "scrollY", + "pageXOffset", + "pageYOffset", + "innerWidth", + "innerHeight", + "screenX", + "screenY", + "outerWidth", + "outerHeight", + "devicePixelRatio", +].map(beDefensive); + +let methods = [ + "close", + "stop", + "focus", + "blur", + "open", + "alert", + "confirm", + "prompt", + "print", + "postMessage", + + // WindowBase64 + "btoa", + "atob", + + // WindowTimers + "setTimeout", + "clearTimeout", + "setInterval", + "clearInterval", + + // HTML Editing APIs + "getSelection", + + // CSSOM + "getComputedStyle", + + // CSSOM-View + "matchMedia", + "scroll", + "scrollTo", + "scrollBy" +].map(beDefensive); + +let readonlyAttributes = [ + "history", + "frameElement", + "navigator", + "applicationCache", + + // WindowSessionStorage + "sessionStorage", + + // WindowLocalStorage + "localStorage", +].map(beDefensive); + +let writableAttributes = [ + "name", + "status", + "opener", + "onabort", + "onafterprint", + "onbeforeprint", + "onbeforeunload", + "onblur", + "oncancel", + "oncanplay", + "oncanplaythrough", + "onchange", + "onclick", + "onclose", + "oncontextmenu", + "oncuechange", + "ondblclick", + "ondrag", + "ondragend", + "ondragenter", + "ondragleave", + "ondragover", + "ondragstart", + "ondrop", + "ondurationchange", + "onemptied", + "onended", + "onerror", + "onfocus", + "onhashchange", + "oninput", + "oninvalid", + "onkeydown", + "onkeypress", + "onkeyup", + "onload", + "onloadeddata", + "onloadedmetadata", + "onloadstart", + "onmessage", + "onmousedown", + "onmousemove", + "onmouseout", + "onmouseover", + "onmouseup", + "onmousewheel", + "onoffline", + "ononline", + "onpause", + "onplay", + "onplaying", + "onpagehide", + "onpageshow", + "onpopstate", + "onprogress", + "onratechange", + "onreset", + "onresize", + "onscroll", + "onseeked", + "onseeking", + "onselect", + "onshow", + "onstalled", + "onstorage", + "onsubmit", + "onsuspend", + "ontimeupdate", + "onunload", + "onvolumechange", + "onwaiting" +].map(beDefensive); + +export var window = win; +global.window = win; +GLOBAL.window = win;