summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorportix <none@none>2013-03-19 01:05:10 +0100
committerportix <none@none>2013-03-19 01:05:10 +0100
commit34a5c436db3271c72f91cf0f028c934d6474c902 (patch)
tree184218d2dcb9adaddd52f857fb386f3b5f944825
parentf98991177a2c21acfe737d9180ce6e18fa924ffa (diff)
downloaddwb-34a5c436db3271c72f91cf0f028c934d6474c902.zip
New Signal api
-rw-r--r--extensions/perdomainsettings4
-rw-r--r--extensions/requestpolicy31
-rw-r--r--extensions/unique_tabs28
-rw-r--r--extensions/userscripts8
-rw-r--r--scripts/lib/dwb.js20
-rw-r--r--scripts/lib/signals.js653
-rw-r--r--src/scripts.c58
7 files changed, 548 insertions, 254 deletions
diff --git a/extensions/perdomainsettings b/extensions/perdomainsettings
index df2645ca..a6fcc7fd 100644
--- a/extensions/perdomainsettings
+++ b/extensions/perdomainsettings
@@ -243,12 +243,12 @@ var perdomainsettings = {
exports.uris = uris = config.uris || defaultConfig.uris;
uris && getDefaultValue(uris);
- signals.connect("navigation", onNavigation.debug(script));
+ Signal.connect("navigation", onNavigation.debug(script));
return true;
},
end : function ()
{
- signals.disconnect(onNavigation);
+ Signal.disconnect(onNavigation);
}
};
return perdomainsettings;
diff --git a/extensions/requestpolicy b/extensions/requestpolicy
index 9af23275..6ceee7a3 100644
--- a/extensions/requestpolicy
+++ b/extensions/requestpolicy
@@ -109,12 +109,6 @@ var defaultConfig = {
};
var config = {};
-var sigs = {
- resource : -1,
- navigation : -1,
- loadFinished : -1
-};
-
var persistentList = null;
var tmpList = {};
@@ -412,23 +406,6 @@ function loadFinishedCB(wv)
io.notify("RP: blocked " + blocked + " requests");
}
-function connect()
-{
- sigs.resource = signals.connect("resource", resourceCB);
- sigs.navigation = signals.connect("navigation", navigationCB);
- if (config.notify)
- sigs.loadFinished = signals.connect("loadFinished", loadFinishedCB);
-}
-function disconnect()
-{
- sigs.forEach(function (key, value) {
- if (value != -1)
- {
- signals.disconnect(value);
- sigs[key] = -1;
- }
- });
-}//}}}
var requestpolicy = {
defaultConfig : defaultConfig,
init : function(c)
@@ -448,7 +425,10 @@ var requestpolicy = {
}
}
persistentList = persistentList || {};
- connect();
+ Signal.connect("resource", resourceCB);
+ Signal.connect("navigation", navigationCB);
+ if (config.notify)
+ Signal.connect("loadFinished", loadFinishedCB);
bind(config.shortcut, showMenu, "requestpolicy");
bind(config.unblockCurrent, unblockCurrent, "requestpolicyUnblockCurrent");
bind(config.unblockAll, unblockAll, "requestpolicyUnblockAll");
@@ -457,6 +437,9 @@ var requestpolicy = {
end : function ()
{
disconnect();
+ Signal.disconnect(resourceCB);
+ Signal.disconnect(navigationCB);
+ Signal.disconnect(loadFinishedCB);
unbind("requestpolicy");
unbind("requestpolicyUnblockCurrent");
unbind("requestpolicyUnblockAll");
diff --git a/extensions/unique_tabs b/extensions/unique_tabs
index 3496a1c3..535e72f0 100644
--- a/extensions/unique_tabs
+++ b/extensions/unique_tabs
@@ -44,7 +44,7 @@ commandToggleAutoFocus : "ut_toggle_autofocus",
//>DEFAULT_CONFIG
};
-var signalId = -1;
+var signal;
var removeDuplicates = function()
{
@@ -73,28 +73,17 @@ var onNavigation = function(wv, frame, request)
}
return false;
};
-var connectAutoFocus = function()
-{
- signalId = signals.connect("navigation", onNavigation);
-};
-var disconnectAutoFocus = function()
-{
- if (signalId != -1)
- {
- signals.disconnect(signalId);
- signalId = -1;
- return true;
- }
- return false;
-};
var toggleAutoFocus = function()
{
- if (disconnectAutoFocus())
+ if (signal.isConnected())
+ {
+ signal.disconnect();
io.notify("unique_tabs: autofocus disabled");
+ }
else
{
+ signal.connect();
io.notify("unique_tabs: autofocus enabled");
- connectAutoFocus();
}
};
@@ -110,14 +99,15 @@ var uniqueTabs = {
bind(c.shortcutToggleAutoFocus, toggleAutoFocus, c.commandToggleAutoFocus);
}
+ signal = new Signal("navigation", onNavigation);
if (c.autoFocus)
- connectAutoFocus();
+ signal.connect();
return true;
},
end : function() {
unbind(removeDuplicates);
unbind(toggleAutoFocus);
- disconnectAutoFocus();
+ signal.disconnect();
return true;
}
};
diff --git a/extensions/userscripts b/extensions/userscripts
index e8fd71ee..9d86d7ca 100644
--- a/extensions/userscripts
+++ b/extensions/userscripts
@@ -489,13 +489,13 @@ function userscriptsStart()
if (onStart.length > 0)
{
onStart.sort(function(a, b) { return b.priority - a.priority; });
- signals.connect("loadCommitted", loadCommittedCallback);
+ Signal.connect("loadCommitted", loadCommittedCallback);
ret = true;
}
if (onEnd.length > 0)
{
onEnd.sort(function(a, b) { return b.priority - a.priority; });
- signals.connect("documentLoaded", loadFinishedCallback);
+ Signal.connect("documentLoaded", loadFinishedCallback);
ret = true;
}
//metaData = {};
@@ -541,8 +541,8 @@ var userscripts = {
return parseScripts(c ? c.scripts || [] : []);
},
end : function () {
- signals.disconnect(loadFinishedCallback);
- signals.disconnect(loadCommittedCallback);
+ Signal.disconnect(loadFinishedCallback);
+ Signal.disconnect(loadCommittedCallback);
}
};
diff --git a/scripts/lib/dwb.js b/scripts/lib/dwb.js
index 0d946dc6..72f8c985 100644
--- a/scripts/lib/dwb.js
+++ b/scripts/lib/dwb.js
@@ -335,17 +335,27 @@
return _deprecated("sendRequestSync", "net.sendRequestSync", arguments);
}
},
+ "_deprecationWarning" :
+ {
+ value : function(on, nn)
+ {
+ io.print("\033[31;1mDWB DEPRECATION:\033[0m " + on + "() is deprecated, use " + nn + "() instead!");
+ }
+ },
"_deprecated" :
{
value : function(on, nn, args)
{
var i, l, ns, ctx;
io.print("\033[31;1mDWB DEPRECATION:\033[0m " + on + "() is deprecated, use " + nn + "() instead!");
- ns = nn.split(".");
- ctx = this;
- for (i=0, l=ns.length; i<l-1; i++)
- ctx = ctx[ns[i]];
- return ctx[ns[l-1]].apply(this, args);
+ if (args)
+ {
+ ns = nn.split(".");
+ ctx = this;
+ for (i=0, l=ns.length; i<l-1; i++)
+ ctx = ctx[ns[i]];
+ return ctx[ns[l-1]].apply(this, args);
+ }
}
},
"_initNewContext" :
diff --git a/scripts/lib/signals.js b/scripts/lib/signals.js
index 3078d42c..4e87342a 100644
--- a/scripts/lib/signals.js
+++ b/scripts/lib/signals.js
@@ -1,144 +1,479 @@
(function ()
{
- var _registered = {};
- var _blocked = false;
- var _pending = [];
- function _disconnect(sig)
+ var _regCount = {};
+ var _connectedSignals = {};
+ var _connectedMapping = {};
+
+ var _disconnect = function(signal)
{
- signals[sig] = null;
- delete _registered[sig];
- }
- var _disconnectByProp = function(prop, obj)
+ var name = signal.name, id = signal.id;
+ _regCount[name]--;
+
+ _connectedSignals[name][id] = null;
+ delete _connectedSignals[name][id];
+
+ _connectedMapping[id] = null;
+ delete _connectedMapping[id];
+
+
+ if (_regCount[name] == 0)
+ signals[name] = null;
+ return signal;
+ };
+ var _getSignalByCallback = function(callback)
{
- var sig, i, sigs;
- if (_blocked)
+ var id;
+ for (id in _connectedMapping)
{
- _pending.push({prop : prop, obj : obj});
- return;
+ if (callback == _connectedMapping[id].callback)
+ {
+ return _connectedMapping[id];
+ }
}
- for (sig in _registered)
- {
- sigs = _registered[sig];
- for (i = 0; i<sigs.length; i++)
+ return null;
+ };
+ var _getSignalBySelfOrCallback = function(selfOrCallback)
+ {
+ if (selfOrCallback instanceof Signal)
+ return selfOrCallback;
+ return _getSignalByCallback(selfOrCallback);
+ };
+ /**
+ *
+ * @name Signal
+ * @class
+ * A Signal can be used to connect to certain browser events. For a list
+ * of available signals see {@link signals}. Signals are directly
+ * emitted on {@link signals}, this class is just a convience
+ * class to handle signals.
+ * @description
+ * Constructs a new Signal
+ * @example
+ * function navigationCallback(wv, frame, request, response)
+ * {
+ * ...
+ * }
+ *
+ * // Create a new signal
+ * var a = new Signal("navigation", navigationCallback);
+ * var b = new Signal("navigation");
+ *
+ * // The following patterns are equivalent
+ * a.connect();
+ *
+ * b.connect(navigationCallback);
+ *
+ * // using the static method
+ * var c = Signal.connect("navigation", navigationCallback);
+ *
+ * // set the signal callback directly on {@link signals}
+ * // you won't get the constructed signal then
+ * signals.onNavigation = navigationCallback;
+ *
+ * @param {String} name
+ * The event to connect to
+ * @param {Function} [callback]
+ * Callback that will be called when the signal is emitted. If omitted
+ * a callback must be passed to {@link connect}.
+ *
+ * @returns {Signal}
+ * A new Signal
+ * */
+ Object.defineProperty(this, "Signal", {
+ writable : true,
+ value : (function() {
+ var id = 0;
+ return function(name, callback)
+ {
+ id++;
+ if (!name)
+ {
+ throw new Error("new Signal() : missing signal name");
+ }
+ return Object.create(Signal.prototype,
+ {
+ /**
+ * The id of the signal
+ * @name id
+ * @memberOf Signal.prototype
+ * @readonly
+ *
+ * */
+ "id" : { value : id },
+ /**
+ * The callback that will be called when the signal
+ * is emitted, the context of the signal will be the
+ * signal itself (i.e. <i>this</i> refers to the
+ * connected Signal).
+ *
+ * @name callback
+ * @memberOf Signal.prototype
+ *
+ * @example
+ * function a() {
+ * io.print("Calling from a");
+ * this.callback = b;
+ * }
+ * function b() {
+ * io.print("Calling from b");
+ * this.callback = a;
+ * }
+ * var s = new Signal("createTab", a).connect();
+ * */
+ "callback" : { value : callback, writable : true },
+ /**
+ * The name of the event
+ * @name name
+ * @memberOf Signal.prototype
+ * @readonly
+ * */
+ "name" : { value : name },
+ /**
+ * Disconnect this signal from the event, if disconnected the
+ * callback will no longer be called, to reconnect
+ * call signal.connect()
+ *
+ * @name disconnect
+ * @function
+ * @memberOf Signal.prototype
+ *
+ * @returns {Signal}
+ * self
+ *
+ * @example
+ * var i = 0;
+ * var signal = new Signal("navigation", function(wv, frame, request) {
+ * i++;
+ * if (i == 3)
+ * this.disconnect();
+ * });
+ * */
+ "disconnect" :
+ {
+ value : function()
+ {
+ if (this.isConnected())
+ _disconnect(this);
+ return this;
+ }
+ },
+ /**
+ * Connect this signal to the event
+ *
+ * @name connect
+ * @function
+ * @memberOf Signal.prototype
+ *
+ * @param {Function} [callback]
+ * The callback function to call, if no
+ * callback was passed to the constructor
+ * callback is mandatory.
+ *
+ * @returns {Signal}
+ * self
+ * @example
+ * function a() {
+ * ...
+ * }
+ * function b() {
+ * ...
+ * }
+ * var signal = new Signal("navigation", a);
+ * // connect to a
+ * signal.connect();
+ * // connect to b
+ * signal.connect(b);
+ * */
+ "connect" :
+ {
+ value : function(callback)
+ {
+ if (callback)
+ this.callback = callback;
+ if (this.isConnected())
+ return;
+
+ if (!this.callback)
+ throw new Error("Signal.connect() : missing callback");
+ var name = this.name, id = this.id;
+ if (!_regCount[name])
+ _regCount[name] = 0;
+ if (!_connectedSignals[name])
+ _connectedSignals[name] = {};
+ if (_regCount[name] == 0)
+ {
+ signals[name] = function() { return Signal.emit(name, arguments); };
+ }
+ _regCount[name]++;
+ _connectedSignals[name][id] = this;
+ _connectedMapping[id] = this;
+ return this;
+ }
+ },
+ /**
+ * Checks if a signal is connected
+ *
+ * @name isConnected
+ * @memberOf Signal.prototype
+ * @function
+ *
+ * @return {Boolean}
+ * <i>true</i> if the signal is connected
+ * */
+ "isConnected" :
+ {
+ value : function()
+ {
+ return Boolean(_connectedMapping[this.id]);
+ }
+ }
+ }
+ );
+ };
+ })()
+ });
+ Object.defineProperties(Signal, {
+ /**
+ * Connects to an event
+ *
+ * @name connect
+ * @memberOf Signal
+ * @function
+ *
+ * @param {String} name
+ * The signal to connect to
+ * @param {Function} callback
+ * Callback that will be called when the signal is emitted.
+ *
+ * @returns {Signal}
+ * A new Signal
+ *
+ * @example
+ * function onCloseTab()
+ * {
+ * ...
+ * }
+ * var s = Signal.connect("closeTab", onCloseTab);
+ * // equivalent to
+ * var s = new Signal("closeTab", onCloseTab);
+ * s.connect();
+ * */
+ "connect" :
{
- if (sigs[i][prop] == obj)
+ value : function(name, callback)
{
- if (_registered[sig].length === 1)
+ var signal = new Signal(name, callback);
+ return signal.connect();
+ }
+ },
+ /**
+ * Disconnects from an event.
+ * @name disconnect
+ * @memberOf Signal
+ * @function
+ *
+ * @param {Signal|Callback} object
+ * Either a Signal or the callback of a signal
+ * If a callback is passed to this function and the same
+ * callback is connected multiple times only the first matching
+ * callback will be disconnected, to disconnect all matching
+ * callbacks call use {@link Signal.disconnectAll}
+ *
+ * @returns {Signal}
+ * The disconnected Signal
+ *
+ * @example
+ * function callback(wv)
+ * {
+ * ...
+ * }
+ * var s = new Signal("loadStatus").connect(callback);
+ *
+ * // Disconnect from the first matching callback
+ * Signal.disconnect(callback);
+ *
+ * Signal.disconnect(s);
+ * // or equivalently
+ * s.disconnect();
+ * */
+ "disconnect" :
+ {
+ value : function(selfOrCallback)
+ {
+ return _getSignalBySelfOrCallback(selfOrCallback);
+ }
+ },
+ /**
+ * Connects all webviews to a GObject signal.
+ *
+ * @name connectWebView
+ * @memberOf Signal
+ * @function
+ *
+ * @param {String} signal The signal name
+ * @param {GObject~connectCallback} callback
+ * A callback function the will be called when the signal is
+ * emitted, the arguments of the callback correspond to the GObject
+ * callback
+ * @example
+ * Signal.connectWebView("hovering-over-link", function(title, uri) {
+ * io.write("/tmp/hovered_sites", "a", uri + " " + title);
+ * });
+ *
+ * */
+ "connectWebView" :
+ {
+ value : function(name, callback)
+ {
+ Signal.connect("createTab", function(wv) {
+ wv.connect(name, function() { callback.apply(wv, arguments);});
+ });
+ }
+ },
+ /**
+ * Emits a signal, can be used to implement custom signals.
+ *
+ * @name emit
+ * @memberOf Signal
+ * @function
+ *
+ * @param {String} signal The signal name
+ * @param {varargs} args Arguments passed to the callback function of
+ * {@link signals.connect}
+ *
+ * @returns {Boolean}
+ * The overall return value of all callback function, if one
+ * callback function returns <i>true</i> the overall return value
+ * will be <i>true</i>
+ * */
+ "emit" :
+ {
+ value : function(signal, args)
+ {
+ var id, current;
+ var ret = false;
+ var connected = _connectedSignals[signal];
+ for (id in connected)
+ {
+ current = connected[id];
+ ret = current.callback.apply(current, args) || ret;
+ }
+ return ret;
+ }
+ },
+ /**
+ * Disconnect from all signals with matching callback function
+ *
+ * @name disconnectAll
+ * @memberOf Signal
+ * @function
+ *
+ * @param {Function} callback
+ * A callback function
+ *
+ * @returns {Array}
+ * Array of signals that were disconnected
+ *
+ * @example
+ * function onNavigation(wv, frame, request)
+ * {
+ * ...
+ * }
+ * var a = new Signal("navigation", onNavigation).connect();
+ * var b = new Signal("navigation", onNavigation).connect();
+ *
+ * Signals.disconnectAll(onNavigation);
+ * */
+ "disconnectAll" :
+ {
+ value : function(callback)
+ {
+ var signals = [];
+ var signal;
+ while((signal = _getSignalBySelfOrCallback(callback)))
{
- _disconnect(sig);
+ signals.push(signal);
+ signal.disconnect();
}
+ return signals;
+
+ }
+ },
+ /**
+ * Connect to more than one signal at once
+ *
+ * @name connectAll
+ * @memberOf Signal
+ * @function
+ *
+ * @param {Array} signals
+ * Array of signals
+ * @param {Function} [callback]
+ * Callbackfunction to connect to
+ *
+ *
+ * @example
+ * function onNavigation(wv, frame, request)
+ * {
+ * ...
+ * }
+ * function onNavigation2(wv, frame, request)
+ * {
+ * ...
+ * }
+ * var a = new Signal("navigation", onNavigation).connect();
+ * var b = new Signal("navigation", onNavigation).connect();
+ *
+ * // disconnect from all signals
+ * var signals = Signal.disconnectAll(onNavigation);
+ *
+ * // reconnect to all signals
+ * Signal.connectAll(signals);
+ *
+ * // Reconnect to all signals with a new callback
+ * Signal.connectAll([a, b], onNavigation2);
+ * */
+ "connectAll" :
+ {
+ value : function(signalOrArray, callback)
+ {
+ var i, l;
+ if (signalOrArray instanceof Signal)
+ signalOrArray.connect(callback);
else
{
- sigs.splice(i, 1);
+ for (i=signalOrArray.length-1; i>=0; i--)
+ signalOrArray[i].connect(callback);
}
- return;
}
}
- }
- };
- var _connect = function(id, sig, func, pre)
- {
- pre = pre || 0;
- if (func === null || typeof func !== "function")
- {
- return -1;
- }
- if (_registered[sig] === undefined || _registered[sig] === null)
- {
- _registered[sig] = [];
- signals[sig] = function () { return signals.emit(sig, arguments); };
- }
- _registered[sig].push({ callback : func, id : id, pre : pre });
- _registered[sig].sort(function(a, b) { return b.pre - a.pre; });
- return id;
- };
- Object.defineProperties(signals,
- {
+ });
+ Object.defineProperties(signals, {
/**
- * Emits a signal, can be used to implement custom signals.
- *
* @name emit
* @memberOf signals
- * @function
- *
- * @param {String} signal The signal name
- * @param {varargs} args Arguments passed to the callback function of
- * {@link signals.connect}
- *
- * @returns {Boolean}
- * The overall return value of all callback function, if one
- * callback function returns <i>true</i> the overall return value
- * will be <i>true</i>
+ * @function
+ * @deprecated use {@link Signal.emit} instead
* */
"emit" :
{
- value : function(sig, args)
+ value : function(sig, func, pre)
{
- var sigs = _registered[sig];
- var currentSig, pending;
- var ret = false;
- var i, l;
- _blocked = true;
- for (i=0, l=sigs.length; i<l; i++)
- {
- currentSig = sigs[i];
- ret = currentSig.callback.apply(currentSig.callback, args) || ret;
- }
- _blocked = false;
- if (_pending.length > 0)
- {
- for (i=_pending.length-1; i>=0; --i)
- {
- pending = _pending[i];
- _disconnectByProp(pending.prop, pending.obj);
- }
- _pending = [];
- }
- return ret;
+ return _deprecated("signals.emit", "Signal.emit", arguments);
}
},
/**
- * Connects to a signal. Use this function to connect to a signal,
- * setting a callback function directly on an event will overwrite
- * all existing callbacks. The callbacks are executed in order they are
- * connected except precedence is set for some signals.
- *
- * @example
- * signals.connect("navigation", function(webview, frame, request, action) {
- * ...
- * });
- *
* @name connect
* @memberOf signals
* @function
- *
- * @param {String} event
- * The event name, see Events for details
- * @param {Function} callback
- * A callback function the will be called when the signal is
- * emitted, see Type Definitions for details
- * @param {Number} [precedence]
- * A number indicating the precedence of executing the callback,
- * the higher the number the earlier the function will be executed
- * in the callback queue, note that all callbacks connected from
- * scripts will be executed regardless of precedence. The default
- * precedence is 0.
- *
- * @returns {Number}
- * A unique signal id
+ * @deprecated use {@link Signal.connect} instead
* */
"connect" :
{
- value : (function ()
+ value : function(sig, func, pre)
{
- var id = 0;
- return function(sig, func, pre)
- {
- id++;
- _connect(id, sig, func, pre);
- return id;
- };
- })()
+ return _deprecated("signals.connect", "Signal.connect", arguments);
+ }
},
/**
* Connects all webviews to a GObject signal.
@@ -146,127 +481,53 @@
* @name connectWebView
* @memberOf signals
* @function
+ * @deprecated use {@link Signal.connectWebView} instead
*
- * @param {String} signal The signal name
- * @param {GObject~connectCallback} callback
- * A callback function the will be called when the signal is
- * emitted, the arguments of the callback correspond to the GObject
- * callback
- * @example
- * signals.connectWebView("hovering-over-link", function(title, uri) {
- * io.write("/tmp/hovered_sites", "a", uri + " " + title);
- * });
* */
"connectWebView" :
{
- value : function(name, callback)
+ value : function()
{
- this.connect("createTab", function(wv) {
- wv.connect(name, function() { callback.apply(wv, arguments);});
- });
+ return _deprecated("signals.connectWebView", "Signal.connectWebView", arguments);
}
},
/**
- * Disconnect from a signal
- *
* @name disconnect
* @memberOf signals
* @function
- *
- * @param {Number|Function} id|callback
- * The id returned from {@link connect} or the callback
- * function passed to connect. Note that if the same callback
- * is used more than once the signal must be disconnected by
- * id, otherwise the behaviour is undefined.
- * @example
- * signals.connect("loadFinished", function(wv) {
- * ...
- * signals.disconnect(this);
- * });
- * var id = signals.connect("loadCommitted", function(wv) {
- * ...
- * signals.disconnect(id);
- * });
+ * @deprecated use {@link Signal.disconnect} instead
* */
"disconnect" :
{
- value : function(obj) {
- if (typeof obj == "function")
- _disconnectByProp("callback", obj);
- else
- _disconnectByProp("id", obj);
-
+ value : function()
+ {
+ return _deprecated("signals.connect", "Signal.disconnect", arguments);
}
},
/**
- * Disconnect from all signals with matching name. Use with care, it
- * will stop the emission of the signal in <b>all scripts</b>. Can be used to
- * temporarily disable the emission of the signal.
- * To reconnect to all signals pass the returned object to
- * {@link signals.connectAll}.
- *
* @name disconnectAll
* @memberOf signals
* @function
- *
- * @param {String} signal
- * The signal name
- *
- * @returns {Object}
- * An object that can be passed to {@link signals.connectAll} or
- * <i>null</i>.
+ * @deprecated use {@link Signal.disconnectAll}
* */
"disconnectAll" :
{
- value : function (name)
+ value : function(callback)
{
- var sigs = null;
- if (signals[name] !== null && signals[name] !== undefined)
- {
- var ret = [];
- for (var i=0; i<_registered[name].length; i++)
- ret.push(_registered[name][i]);
- _disconnect(name);
-
- return { name : name, signals : ret };
- }
- return null;
+ return _deprecated("signals.disconnectAll", "Signal.disconnectAll", arguments);
}
},
/**
- * Reconnect to a signal previously disconnected with
- * {@link signals.disconnectAll}.
- *
* @name connectAll
* @memberOf signals
* @function
- *
- * @param {Object} detail
- * Object retrieved from {@link signals.disconnectAll}
- * @param {String} detail.name
- * Name of the signal
- * @param {Array[Object]} detail.signals[]
- * Array of signal data
- * @param {Number} detail.signals[].id
- * The id of the signal
- * @param {Function} detail.signals[].callback
- * The callback passed to {@link signals.connect}
- * @param {Number} detail.signals[].pre
- * The precedence
- *
+ * @deprecated use {@link Signal.connectAll} instead
* */
"connectAll" :
{
- value : function(sigs)
+ value : function()
{
- var sig, i, l;
- var name = sigs.name;
- var s = sigs.signals;
- for (i=0, l=s.length; i<l; i++)
- {
- sig = s[i];
- _connect(sig.id, name, sig.callback, sig.pre);
- }
+ return _deprecated("signals.connectAll", "Signal.connectAll", arguments);
}
}
});
diff --git a/src/scripts.c b/src/scripts.c
index 3e75685b..05a62807 100644
--- a/src/scripts.c
+++ b/src/scripts.c
@@ -166,7 +166,8 @@ static JSClassRef s_gobject_class,
s_deferred_class,
s_history_class;
static gboolean s_commandline = false;
-static JSObjectRef s_array_contructor;
+static JSObjectRef s_array_contructor,
+ s_signal_connect;
static JSObjectRef s_completion_callback;
static GQuark s_ref_quark;
static JSObjectRef s_init_before, s_init_after; // s_private;
@@ -2850,6 +2851,8 @@ watch_spawn(GPid pid, gint status, JSObjectRef deferred)
* needed and environment variables should be set
* @param {Object} [environ] Object that can be used to add environment
* variables to the childs environment
+ * @param {Boolean} [toStdin] If set to <i>true</i> stdout- and stderr-callback can be
+ * used to write to stdin of the childs
*
* @returns {Deferred}
* A deferred, it will be resolved if the child exits normally, it will be
@@ -2868,6 +2871,7 @@ system_spawn(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, siz
SpawnChannel *out = NULL, *err = NULL;
JSObjectRef oc = NULL, ec = NULL;
GPid pid;
+ gboolean get_stdin = false;
if (argc == 0)
@@ -2891,12 +2895,14 @@ system_spawn(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, siz
if (argc > 3)
envp = get_environment(ctx, argv[3], exc);
+ if (argc > 4)
+ get_stdin = JSValueToBoolean(ctx, argv[4]);
if (!g_shell_parse_argv(cmdline, &srgc, &srgv, NULL) ||
!g_spawn_async_with_pipes(NULL, srgv, envp, G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
NULL, NULL, &pid,
- oc != NULL || ec != NULL ? &infd : NULL,
+ get_stdin && (oc != NULL || ec != NULL) ? NULL : &infd,
oc != NULL ? &outfd : NULL,
ec != NULL ? &errfd : NULL, NULL))
{
@@ -3877,6 +3883,22 @@ signal_set(JSContextRef ctx, JSObjectRef object, JSStringRef js_name, JSValueRef
if (name == NULL)
return false;
+ if (g_str_has_prefix(name, "on") && strlen(name) > 3 && g_ascii_isupper(*(name+2)))
+ {
+ JSObjectRef func = js_value_to_function(ctx, value, exception);
+ if (func)
+ {
+ name[2] = g_ascii_tolower(name[2]);
+ const char *tmp = name+2;
+ JSValueRef js_value = js_char_to_value(ctx, tmp);
+ JSValueRef argv[] = { js_value, func };
+ puts(tmp);
+ JSObjectCallAsFunction(s_global_context, s_signal_connect, NULL, 2, argv, exception);
+
+ g_free(name);
+ return true;
+ }
+ }
for (int i = SCRIPTS_SIG_FIRST; i<SCRIPTS_SIG_LAST; i++)
{
@@ -4671,11 +4693,34 @@ create_global_object()
* All events are emitted on the signals object itself, for example
* "signals.keyPress = function() { ... };" would connect to the keyPress
* signal but it is <b>strongly discouraged</b> to use this pattern since it will
- * only allow to connect one callback to a certain signal, so {@link signals.connect}
- * which manages all signals should be used instead.
+ * only allow to connect one callback to a certain signal. To handle signals
+ * {@link Signal}-objects can be used, it manages signals, allows to connect
+ * more than one signal and also allows to easily disconnect/reconnect to
+ * signals.
+ *
+ * There is just one convenient pattern that allows setting
+ * callbacks directly on signals: if the signal name starts with "on"
+ * dwb will internally create a new Signal and connect to it with the given
+ * callback function, i.e. using
+ * <b>signals.onResource = function () {...}</b> allows to connect more than
+ * one callback to the "resource"-event, however it doesn't give you as much
+ * control as creating a {@link Signal}.
*
* @namespace
* @name signals
+ * @example
+ * function onNavigation(wv, frame, request)
+ * {
+ * ...
+ * if (request.uri == "http://www.example.com")
+ * this.disconnect();
+ * }
+ * // Connect to the navigation event
+ * // this is the preferred way.
+ * var s = new Signal("navigation", onNavigation).connect();
+ * // or equivalently, gi
+ * signals.onNavigation = onNavigation;
+ *
* */
cd = kJSClassDefinitionEmpty;
cd.className = "signals";
@@ -5262,6 +5307,10 @@ scripts_init(gboolean force)
g_string_free(content, true);
g_free(dir);
}
+ JSObjectRef signal = js_get_object_property(s_global_context, JSContextGetGlobalObject(s_global_context), "Signal");
+ s_signal_connect = js_get_object_property(s_global_context, signal, "connect");
+ JSValueProtect(s_global_context, s_signal_connect);
+
UNDEFINED = JSValueMakeUndefined(s_global_context);
JSValueProtect(s_global_context, UNDEFINED);
NIL = JSValueMakeNull(s_global_context);
@@ -5369,6 +5418,7 @@ scripts_end()
JSValueUnprotect(s_global_context, UNDEFINED);
JSValueUnprotect(s_global_context, NIL);
JSValueUnprotect(s_global_context, s_soup_session);
+ JSValueUnprotect(s_global_context, s_signal_connect);
//JSValueUnprotect(s_global_context, s_private);
JSClassRelease(s_gobject_class);
JSClassRelease(s_webview_class);