Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Break out the meta object parts of winow.js and clean up the implemen…

…tation
  • Loading branch information...
commit a3d0845fb4d753baf580431b1421e9021194c6a8 1 parent 206f3ec
@Benvie Benvie authored
Showing with 252 additions and 221 deletions.
  1. +10 −7 lib/bridge.js
  2. +217 −0 lib/handlers.js
  3. +25 −214 lib/window.js
View
17 lib/bridge.js
@@ -1,4 +1,4 @@
-module.exports = function bridge(nativeWindow, handler, win){
+module.exports = function bridge(nativeWindow, win, unwrapEphemeral){
function isObject(o){
if (o == null) return o !== null && o !== undefined;
return typeof o === 'object' || typeof o === 'function';
@@ -363,12 +363,15 @@ module.exports = function bridge(nativeWindow, handler, win){
});
if (nativeWindow) {
- handler.__proto__ = Mirror.prototype;
- handler.id = [FOREIGN, 0];
- handler.id2 = [FOREIGN, 0, null];
- handler.id3 = [FOREIGN, 0, null, null];
- initForeign(handler.id, win);
- handler = null;
+ void function(){
+ var id = [FOREIGN, 0];
+ unwrapEphemeral(win).morph(Mirror.prototype, {
+ id: id,
+ id2: [FOREIGN, 0, null],
+ id3: [FOREIGN, 0, null, null]
+ });
+ initForeign(id, win);
+ }();
} else {
window.node = unwrap([FOREIGN, 0]);
}
View
217 lib/handlers.js
@@ -0,0 +1,217 @@
+var decorate = require('./utils').decorate;
+
+var _hasOwn = Object.prototype.hasOwnProperty,
+ _apply = Function.prototype.apply,
+ _bind = Function.prototype.bind;
+
+module.exports = {
+ Ephemeral: Ephemeral,
+ MirrorHandler: MirrorHandler,
+ ReferenceType: ReferenceType
+};
+
+
+var ephemerals = new WeakMap;
+
+function Ephemeral(target, data){
+ this.handler = new MirrorHandler(target);
+ Object.keys(Object(data)).forEach(function(key){
+ this[key] = data[key];
+ }, this);
+ var proxy = Proxy.create(this.handler, target.__proto__);
+ ephemerals.set(proxy, this);
+ return proxy;
+}
+
+Ephemeral.unwrap = function unwrap(target){
+ return ephemerals.get(target);
+};
+
+decorate(Ephemeral.prototype, [
+ function retarget(target){
+ this.handler.target = target;
+ },
+ function morph(handler, data){
+ this.handler.__proto__ = handler;
+ Object.keys(Object(data)).forEach(function(key){
+ this[key] = data[key];
+ }, this.handler);
+ },
+ function unmorph(){
+ this.handler.__proto__ = MirrorHandler.prototype;
+ }
+]);
+
+
+
+function MirrorHandler(target){
+ this.target = target;
+}
+
+decorate(MirrorHandler.prototype, [
+ function keys(){
+ return Object.keys(this.target);
+ },
+ function enumerate(){
+ var i=0, k=[];
+ for (k[i++] in this.target);
+ return k;
+ },
+ function getOwnPropertyNames(){
+ return Object.getOwnPropertyNames(this.target);
+ },
+ function get(rcvr, key){
+ return this.target[key];
+ },
+ function set(rcvr, key, value){
+ this.target[key] = value;
+ return true;
+ },
+ function has(key){
+ return key in this.target;
+ },
+ function hasOwn(key){
+ return _hasOwn.call(this.target, key);
+ },
+ function delet\u0065(key){
+ delete this.target[key];
+ return true;
+ },
+ function defineProperty(key, desc){
+ Object.defineProperty(this.target, key, desc);
+ return true;
+ },
+ function getOwnPropertyDescriptor(key){
+ var desc = Object.getOwnPropertyDescriptor(this.target, key);
+ desc && (desc.configurable = true);
+ return desc;
+ },
+ function apply(rcvr, args){
+ return _apply.call(this.target, rcvr, args);
+ },
+ function construct(args){
+ return new (_bind.apply(this.target, [null].concat(args)));
+ }
+]);
+
+
+
+var references = new WeakMap;
+
+function ReferenceType(keys, accessors){
+ this.accessors = Object.create(null);
+ this.refKeys = Object.create(null);
+
+ if (Array.isArray(keys)) {
+ this.names = keys;
+ keys.forEach(function(key){ this[key] = key }, this.refKeys);
+ } else {
+ this.names = Object.keys(keys);
+ this.names.forEach(function(key){ this[key] = keys[key] }, this.refKeys);
+ }
+
+ if (accessors) {
+ var accessorKeys = Object.keys(accessors);
+ this.names = this.names.concat(accessorKeys);
+ accessorKeys.forEach(function(key){
+ this[key] = Object.getOwnPropertyDescriptor(accessors, key);
+ }, this.accessors);
+ }
+
+ function ReferenceHandler(reference, target){
+ this.reference = reference;
+ this.target = target;
+ }
+
+ ReferenceHandler.prototype = this;
+
+ return function Reference(reference){
+ var proxy = Proxy.create(new ReferenceHandler(reference, this), Reference.prototype);
+ references.set(proxy, reference);
+ return proxy;
+ };
+}
+
+ReferenceType.unwrap = function unwrap(target){
+ return references.get(target);
+};
+
+
+decorate(ReferenceType.prototype, [
+ function keys(){
+ return this.names.concat(Object.keys(this.target));
+ },
+ function enumerate(){
+ var i = this.names.length, k = this.names.slice();
+ for (k[i++] in this.target);
+ return k;
+ },
+ function getOwnPropertyNames(){
+ return this.names.concat(Object.getOwnPropertyNames(this.target));
+ },
+ function get(rcvr, key){
+ if (key === '__proto__') {
+ return this.target.__proto__;
+ } else if (key in this.refKeys) {
+ return this.reference[this.refKeys[key]];
+ } else if (key in this.accessors) {
+ return this.accessors[key].get.call(this.reference);
+ } else {
+ return this.target[key];
+ }
+ },
+ function set(rcvr, key, value){
+ if (key in this.refKeys) {
+ this.reference[this.refKeys[key]] = value;
+ } else if (key in this.accessors) {
+ this.accessors[key].set.call(this.reference, value);
+ } else {
+ this.target[key] = value;
+ }
+ return true;
+ },
+ function has(key){
+ return key in this.refKeys || key in this.accessors || key in this.target;
+ },
+ function hasOwn(key){
+ return key in this.refKeys || key in this.accessors || _hasOwn.call(this.target, key);
+ },
+ function delet\u0065(key){
+ if (key in this.refKeys) {
+ delete this.reference[this.refKeys[key]];
+ } else {
+ delete this.target[key];
+ }
+ return true;
+ },
+ function defineProperty(key, desc){
+ if (key in this.refKeys) {
+ Object.defineProperty(this.reference, this.refKeys[key], desc);
+ } else if (key in this.accessors) {
+ this.accessors[key].set.call(this.reference, desc.value);
+ } else {
+ Object.defineProperty(this.target, key, desc);
+ }
+ return true;
+ },
+ function getOwnPropertyDescriptor(key){
+ if (key in this.refKeys) {
+ var desc = Object.getOwnPropertyDescriptor(this.reference, this.refKeys[key]);
+ } else if (key in this.accessors) {
+ return {
+ enumerable: true, configurable: true, writable: true,
+ value: this.accessors[key].get.call(this.reference)
+ };
+ } else {
+ var desc = Object.getOwnPropertyDescriptor(this.target, key);
+ }
+ desc && (desc.configurable = true);
+ return desc;
+ },
+ function apply(rcvr, args){
+ return _apply.call(this.reference, rcvr, args);
+ },
+ function construct(args){
+ return new (_bind.apply(this.reference, [null].concat(args)));
+ }
+]);
View
239 lib/window.js
@@ -1,25 +1,15 @@
var NativeWindow = require('./bindings').Window,
App = require('./bindings').App,
+ Ephemeral = require('./handlers').Ephemeral,
+ ReferenceType = require('./handlers').ReferenceType,
EventEmitter = process.EventEmitter,
screenHeight = App.prototype.screenHeight,
screenWidth = App.prototype.screenWidth,
decorate = require('./utils').decorate,
- bridge = require('./bridge'),
+ bridge = require('./bridge');
- _hasOwn = Object.prototype.hasOwnProperty,
- _slice = Array.prototype.slice,
- _apply = Function.prototype.apply,
- _bind = Function.prototype.bind,
-
- frames = new WeakMap,
- handlers = new WeakMap;
-
-
-function unwrap(o){
- return frames.get(o);
-}
module.exports = Window;
@@ -29,13 +19,12 @@ function Window(nativeWindow){
return new Window(nativeWindow);
var self = this,
- handler = new WindowHandler(nativeWindow, this),
- window = Proxy.create(handler, Window.prototype),
+ window = new Ephemeral(this, { window: nativeWindow }),
frame = this.frame = new Frame(nativeWindow);
nativeWindow.on('ready', function(){
nativeWindow.runInBrowser(bridge);
- bridge(nativeWindow, handler, window);
+ bridge(nativeWindow, window, Ephemeral.unwrap);
setTimeout(function(){
var windowProto = window.__proto__;
windowProto._events = self._events;
@@ -48,7 +37,7 @@ function Window(nativeWindow){
});
nativeWindow.on('context-released', function(){
- handler.__proto__ = WindowHandler.prototype;
+ Ephemeral.unwrap(window).unmorph();
});
return window;
@@ -63,186 +52,9 @@ Window.prototype = decorate(Object.create(EventEmitter.prototype), true, {
-function Reflector(target){
- this.target = target;
-}
-
-decorate(Reflector.prototype, [
- function keys(){
- return Object.keys(this.target);
- },
- function enumerate(){
- var i=0, k=[];
- for (k[i++] in this.target);
- return k;
- },
- function getOwnPropertyNames(){
- return Object.getOwnPropertyNames(this.target);
- },
- function get(rcvr, key){
- return this.target[key];
- },
- function set(rcvr, key, value){
- this.target[key] = value;
- return true;
- },
- function has(key){
- return key in this.target;
- },
- function hasOwn(key){
- return _hasOwn.call(this.target, key);
- },
- function delet\u0065(key){
- delete this.target[key];
- return true;
- },
- function defineProperty(key, desc){
- Object.defineProperty(this.target, key, desc);
- return true;
- },
- function getOwnPropertyDescriptor(key){
- var desc = Object.getOwnPropertyDescriptor(this.target, key);
- desc && (desc.configurable = true);
- return desc;
- },
- function apply(rcvr, args){
- return _apply.call(this.target, rcvr, args);
- },
- function construct(args){
- return new (_bind.apply(this.target, [null].concat(args)));
- }
-]);
-
-
-
-function WindowHandler(nativeWindow, target){
- this.window = nativeWindow;
- this.target = target;
-}
-
-WindowHandler.prototype = Object.create(Reflector.prototype);
-
-function RefType(properties, accessors){
- this.refs = Object.create(null);
- if (Array.isArray(properties)) {
- this.names = properties;
- properties.forEach(function(key){
- this[key] = key;
- }, this.refs);
- } else {
- this.names = Object.keys(properties);
- this.names.forEach(function(key){
- this[key] = properties[key];
- }, this.refs);
- }
-
- this.accessors = Object.create(null);
- if (accessors) {
- var accessorNames = Object.keys(accessors);
- this.names = this.names.concat(accessorNames);
- accessorNames.forEach(function(key){
- this[key] = Object.getOwnPropertyDescriptor(accessors, key);
- }, this.accessors);
- }
-
- function RefHandler(ref, target){
- this.ref = ref;
- this.target = target;
- }
-
- RefHandler.prototype = this;
+var props = ['left', 'top', 'width', 'height', 'title', 'topmost', 'showChrome', 'resizable', 'opacity', 'alpha','state'];
- return function Creator(ref){
- var handler = new RefHandler(ref, this);
- var proxy = Proxy.create(handler, Creator.prototype);
- handlers.set(proxy, handler);
- return proxy;
- };
-}
-
-
-decorate(RefType.prototype, [
- function keys(){
- return this.names.concat(Object.keys(this.target));
- },
- function enumerate(){
- var i = this.names.length, k = this.names.slice();
- for (k[i++] in this.target);
- return k;
- },
- function getOwnPropertyNames(){
- return this.names.concat(Object.getOwnPropertyNames(this.target));
- },
- function get(rcvr, key){
- if (key === '__proto__') {
- return this.target.__proto__;
- } else if (key in this.refs) {
- return this.ref[this.refs[key]];
- } else if (key in this.accessors) {
- return this.accessors[key].get.call(this.ref);
- } else {
- return this.target[key];
- }
- },
- function set(rcvr, key, value){
- if (key in this.refs) {
- this.ref[this.refs[key]] = value;
- } else if (key in this.accessors) {
- this.accessors[key].set.call(this.ref, value);
- } else {
- this.target[key] = value;
- }
- return true;
- },
- function has(key){
- return key in this.refs || key in this.accessors || key in this.target;
- },
- function hasOwn(key){
- return key in this.refs || key in this.accessors || _hasOwn.call(this.target, key);
- },
- function delet\u0065(key){
- if (key in this.refs) {
- delete this.ref[this.refs[key]];
- } else {
- delete this.target[key];
- }
- return true;
- },
- function defineProperty(key, desc){
- if (key in this.refs) {
- Object.defineProperty(this.ref, this.refs[key], desc);
- } else if (key in this.accessors) {
- this.accessors[key].set.call(this.ref, desc.value);
- } else {
- Object.defineProperty(this.target, key, desc);
- }
- return true;
- },
- function getOwnPropertyDescriptor(key){
- if (key in this.refs) {
- var desc = Object.getOwnPropertyDescriptor(this.ref, this.refs[key]);
- } else if (key in this.accessors) {
- return {
- enumerable: true, configurable: true, writable: true,
- value: this.accessors[key].get.call(this.ref)
- };
- } else {
- var desc = Object.getOwnPropertyDescriptor(this.target, key);
- }
- desc && (desc.configurable = true);
- return desc;
- },
- function apply(rcvr, args){
- return _apply.call(this.ref, rcvr, args);
- },
- function construct(args){
- return new (_bind.apply(this.ref, [null].concat(args)));
- }
-]);
-
-var props = ['left', 'top', 'width', 'height', 'title', 'topmost', 'showChrome', 'resizable', 'opacity', 'alpha', 'state'];
-
-var FrameImpl = new RefType(props, {
+var FrameRef = new ReferenceType(props, {
get right(){
return screenWidth() - this.left - this.width;
},
@@ -266,61 +78,60 @@ var FrameImpl = new RefType(props, {
});
function Frame(win){
- if (!(win instanceof NativeWindow))
+ if (!(win instanceof NativeWindow)) {
throw new TypeError('Invalid Constructor Invocation');
-
- var frame = new FrameImpl(win);
- frames.set(frame, win);
- return frame;
+ } else {
+ return new FrameRef(win);
+ }
}
-FrameImpl.prototype = Frame.prototype;
+FrameRef.prototype = Frame.prototype;
decorate(Frame.prototype, true, [
function center(){
- unwrap(this).move((screenHeight() - this.height) / 2, (screenWidth() - this.width) / 2);
+ ReferenceType.unwrap(this).move((screenHeight() - this.height) / 2, (screenWidth() - this.width) / 2);
return this;
},
function drag(){
- unwrap(this).drag();
+ ReferenceType.unwrap(this).drag();
return this;
},
function minimize(){
- unwrap(this).minimize();
+ ReferenceType.unwrap(this).minimize();
return this;
},
function maximize(){
- unwrap(this).maximize();
+ ReferenceType.unwrap(this).maximize();
return this;
},
function restore(){
- unwrap(this).restore();
+ ReferenceType.unwrap(this).restore();
return this;
},
function fullscreen(){
- unwrap(this).fullscreen();
+ ReferenceType.unwrap(this).fullscreen();
return this;
},
function show(){
- unwrap(this).show();
+ ReferenceType.unwrap(this).show();
return this;
},
function hide(){
- unwrap(this).hide();
+ ReferenceType.unwrap(this).hide();
return this;
},
function move(top, left, width, height){
- unwrap(this).move(top, left, width, height);
+ ReferenceType.unwrap(this).move(top, left, width, height);
return this;
},
function resize(width, height){
- unwrap(this).resize(width, height)
+ ReferenceType.unwrap(this).resize(width, height)
return this
},
function openDevTools(){
- unwrap(this).openDevTools();
+ ReferenceType.unwrap(this).openDevTools();
},
function closeDevTools(){
- unwrap(this).closeDevTools();
+ ReferenceType.unwrap(this).closeDevTools();
},
function toString(){
return '[object Frame]';
Please sign in to comment.
Something went wrong with that request. Please try again.