Skip to content
This repository was archived by the owner on Jan 19, 2018. It is now read-only.

Bind to content #11

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
195 changes: 146 additions & 49 deletions binding/jetpack.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,54 +13,62 @@ return Deferred;

const Deferred = D();

const {Cc,Ci,components} = require("chrome");
var {setTimeout,clearTimeout} = require("timer");

Deferred.postie = function (constructor, opts) {
Deferred.postie = function (target, opts) {
opts = opts || {};
var ret;
var id = 0;
var cb = {};
var mm = [];
var onMessage = opts.onMessage;
var contentScript = opts.contentScript;

opts.onMessage = function (message) {
if (message.init) {
for (var i = 0, it; it = mm[i]; i++) {
ret.postMessage(it);
}
mm = null;
return;
} else {
var c = cb[message.id];
if (c) {
c(message.value, message.error);
var messageListener = function (message) {
if (message.init) {
for (var i = 0, it; it = mm[i]; i++) {
ret.postMessage(it);
}
mm = null;
return;
} else {
var c = cb[message.id];
if (c) {
c(message.value, message.error);
return;
}
}
}
onMessage.apply(this, arguments);
};
onMessage.apply(this, arguments);
};

opts.contentScriptWhen = "ready";
opts.contentScript = [
'Deferred = ' + D.toSource() + '();Deferred.define(this);',
(function () {
on('message', function (message) {
next(function () {
return eval(message.code);
}).
next(function (v) {
postMessage({ id : message.id, value : v });
}).
error(function (e) {
postMessage({ id : message.id, error : e });
if (typeof target == 'function') { // it maybe a constructor.
opts.onMessage = messageListener;
opts.contentScriptWhen = "ready";
opts.contentScript = [
'Deferred = ' + D.toSource() + '();Deferred.define(this);',
(function () {
on('message', function (message) {
next(function () {
return eval(message.code);
}).
next(function (v) {
postMessage({ id : message.id, value : v });
}).
error(function (e) {
postMessage({ id : message.id, error : e });
});
});
});
postMessage({ id : -1, init : true });
}).toSource() + '()'
];

ret = constructor(opts);
postMessage({ id : -1, init : true });
}).toSource() + '()'
];

ret = target(opts);
}
else { // it maybe a worker.
if (target.on)
target.on('message', messageListener);
ret = target;
}

ret.post = function (args, code) {
var deferred = new Deferred();
Expand All @@ -85,23 +93,112 @@ Deferred.postie = function (constructor, opts) {
return deferred;
};

ret.bind = function (selector, event, callback) {
return ret.post(selector, event, function (selector, event) {
var deferred = new Deferred();
var nodes = document.querySelectorAll(selector);
for (var i = 0, it; it = nodes[i]; i++) {
it.addEventListener(event, function (e) {
deferred.call(e);
}, false);
}
return deferred;
}).
next(callback);
};

if (contentScript) ret.post(contentScript).error(function (e) { console.log(e) });

return ret;
};

exports.Deferred = Deferred;

function clone(source) {
var cloned = {};
for (var i in source) { cloned[i] = source[i]; }
return cloned;
}

exports.__defineGetter__('PageMod', function() {
delete this.PageMod;
var PageMod = require('page-mod').PageMod;
return this.PageMod = function(options) {
options = clone(options || {});

var deferred = new Deferred();

options.onAttach = function(worker) {
deferred.call(Deferred.postie(worker));
};

var instance = Deferred.postie(PageMod, options);

deferred.destroy = function() {
instance.destroy.apply(null, arguments);
};

deferred.__defineGetter__('include', function() {
return instance.include;
});

return deferred
.next(function(worker) {
if (options.onAttach)
options.onAttach(worker);
return worker;
});
};
});

exports.__defineGetter__('Page', function() {
delete this.Page;
var Page = require('page-worker').Page;
return this.Page = function(options) {
return Deferred.postie(Page, options);
};
});

exports.__defineGetter__('Panel', function() {
delete this.Panel;
var Panel = require('panel').Panel;
return this.Panel = function(options) {
return Deferred.postie(Panel, options);
};
});

exports.__defineGetter__('Request', function() {
delete this.Request;
var Request = require('request').Request;
return this.Request = function(options) {
options = clone(options || {});

var deferred;

options.onComplete = function(response) {
deferred.call(response);
};

var instance = Request(options);

var originalGet = instance.get;
instance.get = function() {
deferred = new Deferred();
originalGet.apply(instance, arguments);
return deferred
.next(function(response) {
if (options.onComplete)
options.onComplete(response);
return response;
});
};

var originalPost = instance.post;
instance.post = function() {
deferred = new Deferred();
originalPost.apply(instance, arguments);
return deferred
.next(function(response) {
if (options.onComplete)
options.onComplete(response);
return response;
});
};

return instance;
};
});

exports.__defineGetter__('Widget', function() {
delete this.Widget;
var Widget = require('widget').Widget;
return this.Widget = function(options) {
return Deferred.postie(Widget, options);
};
});