summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/dwb-js.7391
-rw-r--r--api/jsapi.7.txt248
-rw-r--r--api/jsapi.txt326
-rw-r--r--extensions/requestpolicy624
-rw-r--r--scripts/base.js26
-rw-r--r--scripts/lib/dwb.js34
-rw-r--r--src/dwb.c1
-rw-r--r--src/js.c8
-rw-r--r--src/js.h1
-rw-r--r--src/scripts.c323
-rw-r--r--src/view.c7
11 files changed, 1526 insertions, 463 deletions
diff --git a/api/dwb-js.7 b/api/dwb-js.7
index 1c3e07ac..f39a13ea 100644
--- a/api/dwb-js.7
+++ b/api/dwb-js.7
@@ -2,12 +2,12 @@
.\" Title: dwb-js
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.77.1 <http://docbook.sf.net/>
-.\" Date: 12/05/2012
+.\" Date: 12/09/2012
.\" Manual: \ \&
.\" Source: \ \&
.\" Language: English
.\"
-.TH "DWB\-JS" "7" "12/05/2012" "\ \&" "\ \&"
+.TH "DWB\-JS" "7" "12/09/2012" "\ \&" "\ \&"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -701,27 +701,6 @@ A string with the file content
.nr an-break-flag 1
.br
.ps +1
-\fBString io.statusBar(Object text)\fR
-.RS 4
-.sp
-Sets the statusbar text\&. The statusbar consists of two labels, a \fImiddle\fR label and a \fIright\fR label, on both labels pango markup can be used
-.PP
-\fItext\&.middle\fR
-.RS 4
-Text for the middle label
-.RE
-.PP
-\fItext\&.right\fR
-.RS 4
-Text for the right label
-.RE
-.RE
-.sp
-.it 1 an-trap
-.nr an-no-space-flag 1
-.nr an-break-flag 1
-.br
-.ps +1
\fBBoolean io.write(String path, String mode, String text)\fR
.RS 4
.sp
@@ -1156,6 +1135,241 @@ Label used for displaying uris, third child of
Label used for status information, fourth child of
\fBgui\&.statusBox\fR\&.
.RE
+.SS "Deferred"
+.sp
+Deferred objects can be used to manage asynchronous operations\&. It can trigger a callback function when an asynchrounous operation has finished, and allows chaining of callbacks\&. Deferred basically have 2 callback chains, a \fIdone\fR\-chain and a \fIfail\fR\-chain\&. If a asynchronous operation is successful the deferred should be resolved and the done callback chain of the deferred is called\&. If a asynchronous operation fails the deferred should be rejected and the fail callback chain of the deferred is called\&.
+.sp
+Deferreds implement the following methods:
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBvoid Deferred.done(Function callback)\fR
+.RS 4
+.sp
+Registers a function for the done\-chain\&.
+.PP
+\fIcallback\fR
+.RS 4
+A callback function that will be called when the Deferred is resolved\&. If the function returns a deferred the original deferred will be replaced with the new deferred\&.
+.RE
+.PP
+\fIreturns\fR
+.RS 4
+A new deferred that can be used to chain callbacks\&.
+.RE
+.RE
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBDeferred Deferred.fail(Function callback)\fR
+.RS 4
+.sp
+Registers a function for the fail\-chain\&.
+.PP
+\fIcallback\fR
+.RS 4
+A callback function that will be called when the deferred is rejected\&. If the function returns a deferred the original deferred will be replaced with the new deferred\&.
+.RE
+.PP
+\fIreturns\fR
+.RS 4
+A new deferred that can be used to chain callbacks\&.
+.RE
+.RE
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBDeferred Deferred.reject(arguments)\fR
+.RS 4
+.sp
+Rejects a deferred, the fail\-chain is called when a deferred is rejected\&.
+.PP
+\fIarguments\fR
+.RS 4
+Arguments passed to the
+\fIfail\fR
+callbacks\&.
+.RE
+.RE
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBvoid Deferred.resolve(arguments)\fR
+.RS 4
+.sp
+Resolves a deferred, the done\-chain is called when a deferred is resolved\&.
+.PP
+\fIarguments\fR
+.RS 4
+Arguments passed to the
+\fIdone\fR
+callbacks\&.
+.RE
+.RE
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBDeferred Deferred.then(Function ondone, Function onfail)\fR
+.RS 4
+.sp
+Registers a function for the done and fail chain\&.
+.PP
+\fIondone\fR
+.RS 4
+A callback function that will be called when the deferred is resolved\&. If the function returns a deferred the original deferred will be replaced with the new deferred\&.
+.RE
+.PP
+\fIonfail\fR
+.RS 4
+A callback function that will be called when the deferred is rejected\&. If the function returns a deferred the original deferred will be replaced with the new deferred\&.
+.RE
+.PP
+\fIreturns\fR
+.RS 4
+A new deferred that can be used to chain callbacks\&.
+.RE
+.sp
+Simple usage of a deferred:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+function loadUri(uri) {
+ var d = new Deferred();
+ tabs\&.current\&.loadUri(uri, function(wv) {
+ if (wv\&.loadStatus == LoadStatus\&.finished)
+ {
+ d\&.resolve("Finished");
+ return true;
+ }
+ else if (wv\&.loadStatus == LoadStatus\&.failed)
+ {
+ d\&.reject("Failed");
+ return true;
+ }
+ });
+ return d;
+}
+
+loadUri("http://www\&.example\&.com")\&.then(
+ function(response) {
+ io\&.print(response); // Finished
+ },
+ function(response) {
+ io\&.print(response); // Failed
+ }
+);
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Chaining of a deferred:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+function foo()
+{
+ var d = new Deferred();
+ timerStart(2000, function() {
+ d\&.reject("rejected");
+ });
+ return d;
+}
+
+function onResponse(response)
+{
+ io\&.print(response);
+}
+
+// Will print "rejected" twice to stdout after 2 seconds
+foo()\&.fail(onResponse)\&.fail(onResponse);
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Note that if the deferred is rejected only the fail chain is called, when it is resolved only the done chain is called\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+function foo()
+{
+ var d = new Deferred();
+ timerStart(2000, function() {
+ d\&.reject("rejected");
+ // Already rejected, will not execute the done chain
+ d\&.resolve("rejected");
+ });
+ return d;
+}
+
+function onResponse(response)
+{
+ io\&.print(response);
+}
+
+// Only the fail will be executed
+
+foo()\&.fail(onResponse)\&.done(onResponse);
+foo()\&.done(onResponse)\&.fail(onResponse);
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Changing the deferred in a callback chain:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+function foo(message)
+{
+ var d = new Deferred();
+ timerStart(2000, function() {
+ d\&.resolve(message);
+ });
+ return d;
+}
+function callback1(response)
+{
+ io\&.print(response); // Prints "foo" after 2 seconds
+
+ // Return a new Deferred, will replace the old one\&.
+ return foo("bar");
+}
+function callback2(response)
+{
+ io\&.print(response); // Prints "bar" after 4 seconds
+}
+
+foo("foo")\&.done(callback1)\&.done(callback2);
+.fi
+.if n \{\
+.RE
+.\}
+.RE
.SH "WEBKIT OBJECTS"
.sp
All webkit objects correspond to gobject objects, i\&.e\&. they have the same properties, but the javascript properties are all camelcase\&. For example, a WebKitWebView has the property \fBzoom\-level\fR, the corresponding javascript property is \fBzoomLevel\fR:
@@ -1194,6 +1408,23 @@ The following methods are implemented by all Objects derived from GObject
.nr an-break-flag 1
.br
.ps +1
+\fBvoid object.blockSignal(Number signalid)\fR
+.RS 4
+.sp
+Blocks emission of a gobect signal\&.
+.PP
+\fIsignalid\fR
+.RS 4
+The signalid returned from
+\fBobject\&.connect\fR
+.RE
+.RE
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
\fBNumber object.connect(String name, Function callback, [Boolean after])\fR
.RS 4
.sp
@@ -1225,6 +1456,37 @@ The signal id of the signal\&.
.nr an-break-flag 1
.br
.ps +1
+\fBNumber object.connectBlocked(String name, Function callback, [Boolean after])\fR
+.RS 4
+.sp
+Connect to a gobject\-signal but block the emission of the own callback during execution of the callback, useful if the object is connected to a notify event and the the property is changed in the callback function\&.
+.PP
+\fIname\fR
+.RS 4
+The signal name to connect to\&.
+.RE
+.PP
+\fIcallback\fR
+.RS 4
+Callback function that will be called when the signal is emitted\&.
+.RE
+.PP
+\fIafter\fR
+.RS 4
+Whether to install the handler after the default handler, default false\&.
+.RE
+.PP
+\fIreturns\fR
+.RS 4
+The signal id of the signal\&.
+.RE
+.RE
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
\fBBoolean object.disconnect(Number id)\fR
.RS 4
.sp
@@ -1277,6 +1539,37 @@ The signal id of the signal\&.
.nr an-break-flag 1
.br
.ps +1
+\fBNumber object.notifyBlocked(String name, Function callback, [Boolean after])\fR
+.RS 4
+.sp
+Wrapper function for property\-change notification, the same as \fIobject\&.connectBlocked("notify::" + name, callback, after);\fR\&.
+.PP
+\fIname\fR
+.RS 4
+The property name to connect to, the name can also be in camelcase\&.
+.RE
+.PP
+\fIcallback\fR
+.RS 4
+Callback function that will be called when the property changes\&.
+.RE
+.PP
+\fIafter\fR
+.RS 4
+Whether to install the handler after the default handler, default after\&.
+.RE
+.PP
+\fIreturns\fR
+.RS 4
+The signal id of the signal\&.
+.RE
+.RE
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
\fBObject GObject.getPrivate(String key, Object identifier)\fR
.RS 4
.sp
@@ -1323,6 +1616,23 @@ The property value
A local object to identify the calling script, the identifier must either be of type Object or of type Function\&.
.RE
.RE
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBvoid object.unblockSignal(Number signalid)\fR
+.RS 4
+.sp
+Unblocks a signal previously blocked with \fBobject\&.blockSignal\fR\&.
+.PP
+\fIsignalid\fR
+.RS 4
+The signalid returned from
+\fBobject\&.connect\fR
+.RE
+.RE
.SS "webview"
.sp
The webview object represents the widget that actually displays the site content\&.
@@ -1449,7 +1759,7 @@ Number of steps, pass a negative value to go back in history
\fBBoolean wv.loadUri(String uri, [Function callback])\fR
.RS 4
.sp
-Load an uri in a webview\&.
+Loads an uri in a webview\&.
.PP
\fIuri\fR
.RS 4
@@ -1472,6 +1782,28 @@ true if the uri is loaded
.nr an-break-flag 1
.br
.ps +1
+\fBvoid wv.reload(void)\fR
+.RS 4
+.sp
+Reloads a webview
+.RE
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBvoid wv.stopLoading()\fR
+.RS 4
+.sp
+Stops any ongoing loading\&.
+.RE
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
\fBNumber wv.toPng(String filename, [Number width, Number height], [Boolean keepAspect])\fR
.RS 4
.sp
@@ -1502,17 +1834,6 @@ Whether to keep the aspect ratio, if set to true the new image will have the sam
A cairo_status_t (0 on success) or \-1 if an error occured\&.
.RE
.RE
-.sp
-.it 1 an-trap
-.nr an-no-space-flag 1
-.nr an-break-flag 1
-.br
-.ps +1
-\fBvoid wv.reload(void)\fR
-.RS 4
-.sp
-Reload a webview
-.RE
.SS "frame"
.sp
A frame represents a frame or iframe\&. Due to same origin policy it is not possible to inject scripts from a webview into iframes with a different domain\&. For this purpose the frame object can be used\&.
diff --git a/api/jsapi.7.txt b/api/jsapi.7.txt
index 7c4e132f..a9bfb561 100644
--- a/api/jsapi.7.txt
+++ b/api/jsapi.7.txt
@@ -323,16 +323,6 @@ _path_;; Path to a file that should be read
_returns_;; A string with the file content
****
-==== String io.statusBar(Object text)
-****
-
-Sets the statusbar text. The statusbar consists of two labels, a 'middle' label and
-a 'right' label, on both labels pango markup can be used
-
-_text.middle_;; Text for the middle label
-_text.right_;; Text for the right label
-****
-
==== Boolean io.write(String path, String mode, String text)
****
@@ -523,6 +513,180 @@ _gui.uriLabel (GtkLabel, read)_;; Label used for displaying uris, third child of
_gui.statusLabel (GtkLabel, read)_;; Label used for status information, fourth child of *gui.statusBox*.
+=== Deferred ===
+
+Deferred objects can be used to manage asynchronous operations. It can trigger a
+callback function when an asynchrounous operation has finished, and allows
+chaining of callbacks.
+Deferred basically have 2 callback chains, a _done_-chain and a _fail_-chain.
+If a asynchronous operation is successful the deferred should be resolved and
+the done callback chain of the deferred is called.
+If a asynchronous operation fails the deferred should be rejected and
+the fail callback chain of the deferred is called.
+
+
+Deferreds implement the following methods:
+
+==== void Deferred.done(Function callback)
+****
+
+Registers a function for the done-chain.
+
+_callback_;; A callback function that will be called when the Deferred is
+resolved. If the function returns a deferred the original deferred will be replaced with
+the new deferred.
+_returns_;; A new deferred that can be used to chain callbacks.
+****
+
+==== Deferred Deferred.fail(Function callback)
+****
+
+Registers a function for the fail-chain.
+
+_callback_;; A callback function that will be called when the deferred is
+rejected. If the function returns a deferred the original deferred will be replaced with
+the new deferred.
+_returns_;; A new deferred that can be used to chain callbacks.
+****
+
+==== Deferred Deferred.reject(arguments)
+****
+
+Rejects a deferred, the fail-chain is called when a deferred is rejected.
+
+_arguments_;; Arguments passed to the _fail_ callbacks.
+****
+
+==== void Deferred.resolve(arguments)
+****
+
+Resolves a deferred, the done-chain is called when a deferred is resolved.
+
+_arguments_;; Arguments passed to the _done_ callbacks.
+****
+
+==== Deferred Deferred.then(Function ondone, Function onfail)
+****
+
+Registers a function for the done and fail chain.
+
+_ondone_;; A callback function that will be called when the deferred is
+resolved. If the function returns a deferred the original deferred will be replaced with
+the new deferred.
+_onfail_;; A callback function that will be called when the deferred is
+rejected. If the function returns a deferred the original deferred will be replaced with
+the new deferred.
+_returns_;; A new deferred that can be used to chain callbacks.
+****
+
+
+Simple usage of a deferred:
+
+[source,javascript]
+---------------------------------
+function loadUri(uri) {
+ var d = new Deferred();
+ tabs.current.loadUri(uri, function(wv) {
+ if (wv.loadStatus == LoadStatus.finished)
+ {
+ d.resolve("Finished");
+ return true;
+ }
+ else if (wv.loadStatus == LoadStatus.failed)
+ {
+ d.reject("Failed");
+ return true;
+ }
+ });
+ return d;
+}
+
+loadUri("http://www.example.com").then(
+ function(response) {
+ io.print(response); // Finished
+ },
+ function(response) {
+ io.print(response); // Failed
+ }
+);
+---------------------------------
+
+Chaining of a deferred:
+
+[source,javascript]
+---------------------------------
+function foo()
+{
+ var d = new Deferred();
+ timerStart(2000, function() {
+ d.reject("rejected");
+ });
+ return d;
+}
+
+function onResponse(response)
+{
+ io.print(response);
+}
+
+// Will print "rejected" twice to stdout after 2 seconds
+foo().fail(onResponse).fail(onResponse);
+---------------------------------
+
+Note that if the deferred is rejected only the fail chain is called, when it is
+resolved only the done chain is called.
+[source,javascript]
+---------------------------------
+function foo()
+{
+ var d = new Deferred();
+ timerStart(2000, function() {
+ d.reject("rejected");
+ // Already rejected, will not execute the done chain
+ d.resolve("rejected");
+ });
+ return d;
+}
+
+function onResponse(response)
+{
+ io.print(response);
+}
+
+// Only the fail will be executed
+
+foo().fail(onResponse).done(onResponse);
+foo().done(onResponse).fail(onResponse);
+---------------------------------
+
+Changing the deferred in a callback chain:
+
+[source,javascript]
+---------------------------------
+function foo(message)
+{
+ var d = new Deferred();
+ timerStart(2000, function() {
+ d.resolve(message);
+ });
+ return d;
+}
+function callback1(response)
+{
+ io.print(response); // Prints "foo" after 2 seconds
+
+ // Return a new Deferred, will replace the old one.
+ return foo("bar");
+}
+function callback2(response)
+{
+ io.print(response); // Prints "bar" after 4 seconds
+}
+
+foo("foo").done(callback1).done(callback2);
+---------------------------------
+
+
== WEBKIT OBJECTS ==
All webkit objects correspond to gobject objects, i.e. they have the same
@@ -555,6 +719,14 @@ if (myObject instanceof GObject)
The following methods are implemented by all Objects derived from GObject
+==== void object.blockSignal(Number signalid)
+****
+
+Blocks emission of a gobect signal.
+
+_signalid_;; The signalid returned from *object.connect*
+****
+
==== Number object.connect(String name, Function callback, [Boolean after])
****
@@ -572,6 +744,20 @@ false.
_returns_;; The signal id of the signal.
****
+==== Number object.connectBlocked(String name, Function callback, [Boolean after])
+****
+
+Connect to a gobject-signal but block the emission of the own callback during
+execution of the callback, useful if the object is connected to a notify event
+and the the property is changed in the callback function.
+
+_name_;; The signal name to connect to.
+_callback_;; Callback function that will be called when the signal is emitted.
+_after_;; Whether to install the handler after the default handler, default
+false.
+_returns_;; The signal id of the signal.
+****
+
==== Boolean object.disconnect(Number id)
****
@@ -594,6 +780,19 @@ after.
_returns_;; The signal id of the signal.
****
+==== Number object.notifyBlocked(String name, Function callback, [Boolean after])
+****
+
+Wrapper function for property-change notification, the same as
+_object.connectBlocked("notify::" + name, callback, after);_.
+
+_name_;; The property name to connect to, the name can also be in camelcase.
+_callback_;; Callback function that will be called when the property changes.
+_after_;; Whether to install the handler after the default handler, default
+after.
+_returns_;; The signal id of the signal.
+****
+
==== Object GObject.getPrivate(String key, Object identifier)
****
@@ -617,6 +816,13 @@ _identifier_;; A local object to identify the calling script, the identifier
must either be of type Object or of type Function.
****
+==== void object.unblockSignal(Number signalid)
+****
+
+Unblocks a signal previously blocked with *object.blockSignal*.
+
+_signalid_;; The signalid returned from *object.connect*
+****
=== webview ===
@@ -673,7 +879,7 @@ _steps_;; Number of steps, pass a negative value to go back in history
==== Boolean wv.loadUri(String uri, [Function callback])
****
-Load an uri in a webview.
+Loads an uri in a webview.
_uri_;; The uri to load
_callback_;; A callback function that will be called when the load status
@@ -681,6 +887,20 @@ changes, return true to stop the emission, optional
_returns_;; true if the uri is loaded
****
+==== void wv.reload(void)
+****
+
+Reloads a webview
+****
+
+
+==== void wv.stopLoading()
+****
+
+Stops any ongoing loading.
+****
+
+
==== Number wv.toPng(String filename, [Number width, Number height], [Boolean keepAspect])
****
@@ -699,12 +919,6 @@ _returns_;; A cairo_status_t (0 on success) or -1 if an error occured.
****
-==== void wv.reload(void)
-****
-
-Reload a webview
-****
-
=== frame ===
A frame represents a frame or iframe. Due to same origin policy it
diff --git a/api/jsapi.txt b/api/jsapi.txt
index 0e8eda9d..c4972638 100644
--- a/api/jsapi.txt
+++ b/api/jsapi.txt
@@ -532,25 +532,6 @@ _returns_;; A string with the file content
****
****
-[[statusBar]]
-[float]
-==== *statusBar()* ====
-
-[source,javascript]
-----
-void io.statusBar(Object text)
-----
-
-Sets the statusbar text. The statusbar consists of two labels, a 'middle' label and
-a 'right' label, on both labels pango markup can be used
-
- ::
-
-_text.middle_;; Text for the middle label
-_text.right_;; Text for the right label
-****
-
-****
[[write]]
[float]
==== *write()* ====
@@ -1064,6 +1045,221 @@ gui.statusLabel GtkLabel read
Label used for status information, fourth child of *gui.statusBox*.
****
+[[Deferred]]
+=== Deferred ===
+
+Deferred objects can be used to manage asynchronous operations. It can trigger a
+callback function when an asynchrounous operation has finished, and allows
+chaining of callbacks.
+Deferred basically have 2 callback chains, a _done_-chain and a _fail_-chain.
+If a asynchronous operation is successful the deferred should be resolved and
+the done callback chain of the deferred is called.
+If a asynchronous operation fails the deferred should be rejected and
+the fail callback chain of the deferred is called.
+
+
+Deferreds implement the following methods:
+
+****
+[float]
+==== *done()* ====
+
+[source,javascript]
+----
+Deferred Deferred.done(Function callback)
+----
+
+Registers a function for the done-chain.
+
+ ::
+
+_callback_;; A callback function that will be called when the Deferred is
+resolved. If the function returns a deferred the original deferred will be replaced with
+the new deferred.
+_returns_;; A new deferred that can be used to chain callbacks.
+****
+
+****
+[float]
+==== *fail()* ====
+
+[source,javascript]
+----
+void Deferred.fail(Function callback)
+----
+
+Registers a function for the fail-chain.
+
+ ::
+
+_callback_;; A callback function that will be called when the deferred is
+rejected. If the function returns a deferred the original deferred will be replaced with
+the new deferred.
+_returns_;; A new deferred that can be used to chain callbacks.
+****
+
+****
+[float]
+==== *reject()* ====
+
+[source,javascript]
+----
+void Deferred.reject(arguments)
+----
+
+Rejects a deferred, the fail-chain is called when a deferred is rejected.
+
+ ::
+
+_arguments_;; Arguments passed to the _fail_ callbacks.
+****
+
+****
+[float]
+==== *resolve()* ====
+
+[source,javascript]
+----
+Deferred Deferred.resolve(arguments)
+----
+
+Resolves a deferred, the done-chain is called when a deferred is resolved.
+
+ ::
+
+_arguments_;; Arguments passed to the _done_ callbacks.
+****
+
+****
+[float]
+==== *then()* ====
+
+[source,javascript]
+----
+Deferred Deferred.then(Function ondone, Function onfail)
+----
+
+Registers a function for the done and fail chain.
+
+ ::
+
+_ondone_;; A callback function that will be called when the deferred is
+resolved. If the function returns a deferred the original deferred will be replaced with
+the new deferred.
+_onfail_;; A callback function that will be called when the deferred is
+rejected. If the function returns a deferred the original deferred will be replaced with
+the new deferred.
+_returns_;; A new deferred that can be used to chain callbacks.
+****
+
+==== *Examples* ====
+
+Simple usage of a deferred:
+
+[source,javascript]
+---------------------------------
+function loadUri(uri) {
+ var d = new Deferred();
+ tabs.current.loadUri(uri, function(wv) {
+ if (wv.loadStatus == LoadStatus.finished)
+ {
+ d.resolve("Finished");
+ return true;
+ }
+ else if (wv.loadStatus == LoadStatus.failed)
+ {
+ d.reject("Failed");
+ return true;
+ }
+ });
+ return d;
+}
+
+loadUri("http://www.example.com").then(
+ function(response) {
+ io.print(response); // Finished
+ },
+ function(response) {
+ io.print(response); // Failed
+ }
+);
+---------------------------------
+
+Chaining of a deferred:
+
+[source,javascript]
+---------------------------------
+function foo()
+{
+ var d = new Deferred();
+ timerStart(2000, function() {
+ d.reject("rejected");
+ });
+ return d;
+}
+
+function onResponse(response)
+{
+ io.print(response);
+}
+
+// Will print "rejected" twice to stdout after 2 seconds
+foo().fail(onResponse).fail(onResponse);
+---------------------------------
+
+Note that if the deferred is rejected only the fail chain is called, when it is
+resolved only the done chain is called.
+[source,javascript]
+---------------------------------
+function foo()
+{
+ var d = new Deferred();
+ timerStart(2000, function() {
+ d.reject("rejected");
+ // Already rejected, will not execute the done chain
+ d.resolve("rejected");
+ });
+ return d;
+}
+
+function onResponse(response)
+{
+ io.print(response);
+}
+
+// Only the fail will be executed
+
+foo().done(onResponse).fail(onResponse);
+foo().fail(onResponse).done(onResponse);
+---------------------------------
+
+Changing the deferred in a callback chain:
+
+[source,javascript]
+---------------------------------
+function foo(message)
+{
+ var d = new Deferred();
+ timerStart(2000, function() {
+ d.resolve(message);
+ });
+ return d;
+}
+function callback1(response)
+{
+ io.print(response); // Prints "foo" after 2 seconds
+
+ // Return a new Deferred, will replace the old one.
+ return foo("bar");
+}
+function callback2(response)
+{
+ io.print(response); // Prints "bar" after 4 seconds
+}
+
+foo("foo").done(callback1).done(callback2);
+---------------------------------
+
[[Webkitobjects]]
== Webkit objects ==
@@ -1120,6 +1316,23 @@ All Objects derived from GObjets implement the following methods.
****
[float]
+==== *blockSignal()* ====
+
+[source,javascript]
+----
+Number object.blockSignal(Number signalid)
+----
+
+Blocks emission of a gobect signal.
+
+ ::
+
+_signalid_;; The signalid returned from *object.connect*
+****
+
+
+****
+[float]
==== *connect()* ====
[source,javascript]
@@ -1145,6 +1358,28 @@ _returns_;; The signal id of the signal.
****
[float]
+==== *connectBlocked()* ====
+
+[source,javascript]
+----
+Number object.connectBlocked(String name, Function callback, [Boolean after])
+----
+
+Connect to a gobject-signal but block the emission of the own callback during
+execution of the callback, useful if the object is connected to a notify event
+and the the property is changed in the callback function.
+
+ ::
+
+_name_;; The signal name to connect to.
+_callback_;; Callback function that will be called when the signal is emitted.
+_after_;; Whether to install the handler after the default handler, default
+false.
+_returns_;; The signal id of the signal.
+****
+
+****
+[float]
==== *disconnect()* ====
[source,javascript]
@@ -1169,7 +1404,7 @@ _returns_;; +true+ if the signal was disconnected
Number object.notify(String name, Function callback, [Boolean after])
----
-Wrapper function for property-change notification, the same as
+Wrapper function for property-change notification but with signal blocking, same as
_object.connect("notify::" + name, callback, after);_.
::
@@ -1181,6 +1416,27 @@ _returns_;; The signal id of the signal.
****
****
+[float]
+==== *notifyBlocked()* ====
+
+[source,javascript]
+----
+Number object.notifyBlocked(String name, Function callback, [Boolean after])
+----
+
+Wrapper function for property-change notification but with signal blocking, same as
+_object.connectBlocked("notify::" + name, callback, after);_.
+
+ ::
+
+_name_;; The property name to connect to, can also be in camelcase.
+_callback_;; Callback function that will be called when the property changes.
+_after_;; Whether to install the handler after the default handler.
+_returns_;; The signal id of the signal.
+****
+
+
+****
[[getPrivate]]
[float]
==== *getPrivate()* ====
@@ -1216,6 +1472,22 @@ _identifier_;; A local object to identify the calling script, the identifier
must either be of type object or of type function.
****
+****
+[float]
+==== *unblockSignal()* ====
+
+[source,javascript]
+----
+Number object.unblockSignal(Number signalid)
+----
+
+Unblocks a signal previously blocked with *object.blockSignal*.
+
+ ::
+
+_signalid_;; The signalid returned from *object.connect*
+****
+
====
[float]
@@ -1439,7 +1711,7 @@ _steps_;; Number of steps, pass a negative value to go back in history
Boolean wv.loadUri(String uri, [Function callback])
----
-Load an uri in a webview.
+Loads an uri in a webview.
::
@@ -1464,6 +1736,18 @@ Reload a webview
****
[float]
+==== *stopLoading()* ====
+
+[source,javascript]
+----
+void wv.stopLoading(void)
+----
+
+Stops any ongoing loading.
+****
+
+****
+[float]
==== *toPng()* ====
[source,javascript]
diff --git a/extensions/requestpolicy b/extensions/requestpolicy
index 5ec6d6d4..f8d6b62e 100644
--- a/extensions/requestpolicy
+++ b/extensions/requestpolicy
@@ -87,338 +87,380 @@ INFO>*/
var me = "requestpolicy";
var defaultConfig = {
-//<DEFAULT_CONFIG
- // path to a whitelist
- whiteList : data.configDir + "/" + data.profile + "/requestpolicy.json",
+ //<DEFAULT_CONFIG
+ // path to a whitelist
+ whiteList : data.configDir + "/" + data.profile + "/requestpolicy.json",
- // shortcut to block/allow requests
- shortcut : "erp",
+ // shortcut to block/allow requests
+ shortcut : "erp",
- // shortcut to unblock requests from current site that are blocked on all
- // sites
- unblockCurrent : "erC",
+ // shortcut to unblock requests from current site that are blocked on all
+ // sites
+ unblockCurrent : "erC",
- // shortcut to unblock requests that are blocked on all sites
- unblockAll : "erA",
+ // shortcut to unblock requests that are blocked on all sites
+ unblockAll : "erA",
- // reload current site after blocking / unblocking a request
- autoreload : false,
+ // reload current site after blocking / unblocking a request
+ autoreload : false,
- // notify about blocked requests
- notify : false
+ // notify about blocked requests
+ notify : false
-//>DEFAULT_CONFIG
+ //>DEFAULT_CONFIG
};
var config = {};
var sigs = {
- resource : -1,
- navigation : -1,
- loadFinished : -1
+ resource : -1,
+ navigation : -1,
+ loadFinished : -1
};
var persistentList = null;
var tmpList = {};
-var getPrivate = (function () {
- var identifier = {};
- return function (wv) {
- var p = wv.getPrivate("foo", identifier);
- if (p === null) {
- p = { domains : [], blocked : 0 };
- wv.setPrivate("foo", p, identifier);
- }
- return p;
- };
+var getPrivate = (function ()
+{
+ var identifier = {};
+ return function (wv) {
+ var p = wv.getPrivate("foo", identifier);
+ if (!p)
+ {
+ p = { domains : [], blocked : 0 };
+ wv.setPrivate("foo", p, identifier);
+ }
+ return p;
+ };
})();
-function listAdd(o, key, value, doWrite) {
- if (!o[key])
- o[key] = [];
- if (o[key].fastIndexOf(value) == -1)
- o[key].push(value);
- if (doWrite)
- io.write(config.whiteList, "w", JSON.stringify(persistentList));
-}
-function listRemove(o, firstParty, domain, doWrite) {
- var idx;
- if (o[firstParty] && (idx = o[firstParty].fastIndexOf(domain)) != -1) {
- o[firstParty].splice(idx, 1);
- if (o[firstParty].length === 0)
- delete o[firstParty];
+function listAdd(o, key, value, doWrite)
+{
+ if (!o[key])
+ o[key] = [];
+ if (o[key].fastIndexOf(value) == -1)
+ o[key].push(value);
if (doWrite)
- io.write(config.whiteList, "w", JSON.stringify(persistentList));
- return true;
- }
- return false;
+ io.write(config.whiteList, "w", JSON.stringify(persistentList));
+}
+function listRemove(o, firstParty, domain, doWrite)
+{
+ var idx;
+ if (o[firstParty] && (idx = o[firstParty].fastIndexOf(domain)) != -1)
+ {
+ o[firstParty].splice(idx, 1);
+ if (o[firstParty].length === 0)
+ delete o[firstParty];
+ if (doWrite)
+ io.write(config.whiteList, "w", JSON.stringify(persistentList));
+ return true;
+ }
+ return false;
}
// MENU {{{
-function showMenu() {
- var tmpWhiteListed, whiteListed;
- var isWhiteListed = false;
- var dom, i, l, domains, labels, currentDomain;
-
- var domain = tabs.current.mainFrame.domain;
- if (domain === null)
- return;
-
- domains = getPrivate(tabs.current).domains;
- labels = [];
- currentDomain = tabs.current.mainFrame.domain;
-
- for (i=0, l=domains.length; i<l; ++i){
- (function(dom) {
- if (persistentList._alwaysBlock && persistentList._alwaysBlock.fastIndexOf(dom) != -1)
- return;
- whiteListed = persistentList[domain] && persistentList[domain].fastIndexOf(dom) != -1;
- tmpWhiteListed = tmpList[domain] && tmpList[domain].fastIndexOf(dom) != -1;
- if (!persistentList._always || persistentList._always.fastIndexOf(dom) == -1) {
- if (!whiteListed && !tmpWhiteListed) {
- labels.push({
- left : "[" + dom + "] allow",
+function showMenu()
+{
+ var tmpWhiteListed, whiteListed;
+ var isWhiteListed = false;
+ var dom, i, l, domains, labels, currentDomain;
+
+ var domain = tabs.current.mainFrame.domain;
+ if (domain === null)
+ return;
+
+ domains = getPrivate(tabs.current).domains;
+ labels = [];
+ currentDomain = tabs.current.mainFrame.domain;
+
+ for (i=0, l=domains.length; i<l; ++i)
+ {
+ (function(dom)
+ {
+ if (persistentList._alwaysBlock && persistentList._alwaysBlock.fastIndexOf(dom) != -1)
+ return;
+
+ whiteListed = persistentList[domain] && persistentList[domain].fastIndexOf(dom) != -1;
+ tmpWhiteListed = tmpList[domain] && tmpList[domain].fastIndexOf(dom) != -1;
+ if (!persistentList._always || persistentList._always.fastIndexOf(dom) == -1)
+ {
+ if (!whiteListed && !tmpWhiteListed)
+ {
+ labels.push({
+ left : "[" + dom + "] allow",
+ action : function () {
+ listAdd(persistentList, currentDomain, dom, true);
+ }
+ });
+ labels.push({
+ left : "[" + dom + "] allow temporarily",
+ action : function() {
+ listAdd(tmpList, currentDomain, dom, false);
+ }
+ });
+ }
+
+ else
+ {
+ labels.push({
+ left : "[" + dom + "] block",
+ action : function() {
+ listRemove(persistentList, currentDomain, dom, true);
+ listRemove(tmpList, currentDomain, dom, false);
+ }
+ });
+ }
+ }
+ isWhiteListed = isWhiteListed || whiteListed || tmpWhiteListed;
+ if (!persistentList._always || persistentList._always.fastIndexOf(dom) == -1)
+ {
+ labels.push({
+ left : "[" + dom + "] allow on all sites",
+ action : function() {
+ listAdd(persistentList, "_always", dom, true);
+ }
+ });
+ }
+ else
+ {
+ labels.push({
+ left : "[" + dom + "] don't allow on all sites",
+ action : function() {
+ listRemove(persistentList, "_always", dom, true);
+ }
+ });
+ }
+ labels.push({
+ left : "[" + dom + "] block on all sites",
+ action : function () {
+ listAdd(persistentList, "_alwaysBlock", dom, true);
+ }
+ });
+ })(domains[i]);
+ }
+ var allAllowed = (persistentList._all && persistentList._all.fastIndexOf(domain) != -1) ||
+ (tmpList._all && tmpList._all.fastIndexOf(domain) != -1);
+ if (isWhiteListed || allAllowed)
+ {
+ labels.unshift({
+ left : "Block all requests on " + domain,
action : function () {
- listAdd(persistentList, currentDomain, dom, true);
+ delete persistentList[currentDomain];
+ listRemove(persistentList, "_all", currentDomain, false);
+ // necessary if persistentList.currentDomain exists
+ io.write(config.whiteList, "w", JSON.stringify(persistentList));
+ delete tmpList[currentDomain];
+ listRemove(tmpList, "_all", currentDomain, false);
}
- });
- labels.push({
- left : "[" + dom + "] allow temporarily",
+ });
+ }
+ if (allAllowed)
+ {
+ labels.unshift({
+ left : "Don't allow all requests on " + domain,
action : function() {
- listAdd(tmpList, currentDomain, dom, false);
+ listRemove(tmpList, "_all", currentDomain, false);
+ listRemove(persistentList, "_all", currentDomain, true);
}
- });
- }
-
- else {
- labels.push({
- left : "[" + dom + "] block",
+ });
+ }
+ else
+ {
+ labels.unshift({
+ left : "Temporarily allow all requests on " + domain,
action : function() {
- listRemove(persistentList, currentDomain, dom, true);
- listRemove(tmpList, currentDomain, dom, false);
+ listAdd(tmpList, "_all", currentDomain, false);
+ }
+ });
+ labels.unshift({
+ left : "Allow all requests on " + domain,
+ action : function() {
+ listAdd(persistentList, "_all", currentDomain, true);
}
- });
- }
- }
- isWhiteListed = isWhiteListed || whiteListed || tmpWhiteListed;
- if (!persistentList._always || persistentList._always.fastIndexOf(dom) == -1) {
- labels.push({
- left : "[" + dom + "] allow on all sites",
- action : function() {
- listAdd(persistentList, "_always", dom, true);
- }
- });
- }
- else {
- labels.push({
- left : "[" + dom + "] don't allow on all sites",
- action : function() {
- listRemove(persistentList, "_always", dom, true);
- }
- });
- }
- labels.push({
- left : "[" + dom + "] block on all sites",
- action : function () {
- listAdd(persistentList, "_alwaysBlock", dom, true);
- }
});
- })(domains[i]);
- }
- var allAllowed = (persistentList._all && persistentList._all.fastIndexOf(domain) != -1) ||
- (tmpList._all && tmpList._all.fastIndexOf(domain) != -1);
- if (isWhiteListed || allAllowed) {
- labels.unshift({
- left : "Block all requests on " + domain,
- action : function () {
- delete persistentList[currentDomain];
- listRemove(persistentList, "_all", currentDomain, false);
- // necessary if persistentList.currentDomain exists
- io.write(config.whiteList, "w", JSON.stringify(persistentList));
- delete tmpList[currentDomain];
- listRemove(tmpList, "_all", currentDomain, false);
- }
- });
- }
- if (allAllowed) {
- labels.unshift({
- left : "Don't allow all requests on " + domain,
- action : function() {
- listRemove(tmpList, "_all", currentDomain, false);
- listRemove(persistentList, "_all", currentDomain, true);
- }
- });
- }
- else {
- labels.unshift({
- left : "Temporarily allow all requests on " + domain,
- action : function() {
- listAdd(tmpList, "_all", currentDomain, false);
- }
- });
- labels.unshift({
- left : "Allow all requests on " + domain,
- action : function() {
- listAdd(persistentList, "_all", currentDomain, true);
- }
- });
- }
-
- tabComplete("Requestpolicy:", labels, function (response) {
- var i, l, len;
- for (i=0, len = labels.length; i<len; ++i) {
- l = labels[i];
- if (l.left == response) {
- l.action();
- if (config.autoreload) {
- tabs.current.reload();
- }
- }
}
- }, true);
+
+ tabComplete("Requestpolicy:", labels, function (response) {
+ var i, l, len;
+ for (i=0, len = labels.length; i<len; ++i)
+ {
+ l = labels[i];
+ if (l.left == response)
+ {
+ l.action();
+ if (config.autoreload)
+ tabs.current.reload();
+ }
+ }
+ }, true);
}//}}}
-function unblockCurrent() {
- if (!persistentList._alwaysBlock) {
- io.notify("No domains to unblock");
- return;
- }
- var domains = getPrivate(tabs.current).domains;
- //var domains = persistentList._alwaysBlock;
- var labels = [], i, l;
- for (i=0, l = domains.length; i<l; i++) {
- if (persistentList._alwaysBlock.fastIndexOf(domains[i]) != -1) {
- labels.push({ left : domains[i] });
+
+function unblockCurrent()
+{
+ if (!persistentList._alwaysBlock)
+ {
+ io.notify("No domains to unblock");
+ return;
}
- }
- if (labels.length > 0) {
- tabComplete("Unblock:", labels, function(response) {
- listRemove(persistentList, "_alwaysBlock", response, true);
- if (config.autoreload)
- tabs.current.reload();
- }, true);
- }
- else {
- io.notify("No domains to unblock");
- }
+ var domains = getPrivate(tabs.current).domains;
+ //var domains = persistentList._alwaysBlock;
+ var labels = [], i, l;
+ for (i=0, l = domains.length; i<l; i++)
+ {
+ if (persistentList._alwaysBlock.fastIndexOf(domains[i]) != -1)
+ labels.push({ left : domains[i] });
+ }
+ if (labels.length > 0)
+ {
+ tabComplete("Unblock:", labels, function(response) {
+ listRemove(persistentList, "_alwaysBlock", response, true);
+ if (config.autoreload)
+ tabs.current.reload();
+ }, true);
+ }
+ else
+ io.notify("No domains to unblock");
}
-function unblockAll() {
- if (!persistentList._alwaysBlock) {
- io.notify("No domains to unblock");
- return;
- }
- var i, l, labels = [];
- var domains = persistentList._alwaysBlock;
- for (i=0, l=domains.length; i<l; ++i) {
- labels.push({ left : domains[i] });
- }
- if (labels.length > 0) {
- tabComplete("Unblock:", labels, function(response) {
- listRemove(persistentList, "_alwaysBlock", response, true);
- if (config.autoreload)
- tabs.current.reload();
- }, true);
- }
+
+function unblockAll()
+{
+ if (!persistentList._alwaysBlock)
+ {
+ io.notify("No domains to unblock");
+ return;
+ }
+ var i, l, labels = [];
+ var domains = persistentList._alwaysBlock;
+ for (i=0, l=domains.length; i<l; ++i)
+ labels.push({ left : domains[i] });
+
+ if (labels.length > 0)
+ {
+ tabComplete("Unblock:", labels, function(response) {
+ listRemove(persistentList, "_alwaysBlock", response, true);
+ if (config.autoreload)
+ tabs.current.reload();
+ }, true);
+ }
}
-function blockRequest(wv, request, priv, domain) {
- request.uri = "about:blank";
- priv.blocked++;
- if (config.notify && wv == tabs.current)
- io.notify("RP: blocked " + domain);
- return true;
+
+function blockRequest(wv, request, priv, domain)
+{
+ request.uri = "about:blank";
+ priv.blocked++;
+ if (config.notify && wv == tabs.current)
+ io.notify("RP: blocked " + domain);
+ return true;
}
// SIGNALS {{{
-var resourceCB = (function () {
- var regexEmpty = /^\s*$/;
- return function resourceCB(wv, frame, request, response) {
- var o, message, domain, firstParty;
- if (regexEmpty.test(request.uri))
- return false;
-
- message = request.message;
- if (!message)
- return false;
-
- firstParty = util.domainFromHost(message.firstParty.host);
- domain = util.domainFromHost(message.uri.host);
- if (firstParty == domain)
- return false;
-
- o = getPrivate(wv);
- if (o.domains.fastIndexOf(domain) == -1)
- o.domains.push(domain);
-
- // Check for requests that are always blocked
- if (persistentList._alwaysBlock && persistentList._alwaysBlock.fastIndexOf(domain) != -1)
- return blockRequest(wv, request, o, domain);
-
- // Check if domain is always allowed
- if ((persistentList._all && persistentList._all.fastIndexOf(firstParty) != -1) ||
- (tmpList._all && tmpList._all.fastIndexOf(firstParty) != -1))
- return false;
-
- // Check request is always allowed
- if (persistentList._always && persistentList._always.fastIndexOf(domain) != -1)
- return false;
-
- // Check if request is whitelisted
- if ( (!persistentList[firstParty] || persistentList[firstParty].fastIndexOf(domain) == -1) &&
- (!tmpList[firstParty] || tmpList[firstParty].fastIndexOf(domain) == -1))
- return blockRequest(wv, request, o, domain);
- };
+var resourceCB = (function ()
+{
+ var regexEmpty = /^\s*$/;
+ return function resourceCB(wv, frame, request, response)
+ {
+ var o, message, domain, firstParty;
+ if (regexEmpty.test(request.uri))
+ return false;
+
+ message = request.message;
+ if (!message)
+ return false;
+
+ firstParty = util.domainFromHost(message.firstParty.host);
+ domain = util.domainFromHost(message.uri.host);
+ if (firstParty == domain)
+ return false;
+
+ o = getPrivate(wv);
+ if (o.domains.fastIndexOf(domain) == -1)
+ o.domains.push(domain);
+
+ // Check for requests that are always blocked
+ if (persistentList._alwaysBlock && persistentList._alwaysBlock.fastIndexOf(domain) != -1)
+ return blockRequest(wv, request, o, domain);
+
+ // Check if domain is always allowed
+ if ((persistentList._all && persistentList._all.fastIndexOf(firstParty) != -1) ||
+ (tmpList._all && tmpList._all.fastIndexOf(firstParty) != -1))
+ return false;
+
+ // Check request is always allowed
+ if (persistentList._always && persistentList._always.fastIndexOf(domain) != -1)
+ return false;
+
+ // Check if request is whitelisted
+ if ( (!persistentList[firstParty] || persistentList[firstParty].fastIndexOf(domain) == -1) &&
+ (!tmpList[firstParty] || tmpList[firstParty].fastIndexOf(domain) == -1))
+ return blockRequest(wv, request, o, domain);
+ };
})();
-function navigationCB(wv, frame) {
- if (frame == wv.mainFrame) {
- var o = getPrivate(wv);
- o.domains = [];
- o.blocked = 0;
- }
-}
-function loadFinishedCB(wv) {
- if (wv != tabs.current)
- return;
+function navigationCB(wv, frame)
+{
+ if (frame == wv.mainFrame)
+ {
+ var o = getPrivate(wv);
+ o.domains = [];
+ o.blocked = 0;
+ }
+ }
- var blocked = getPrivate(wv).blocked;
- if (blocked > 0)
- io.notify("RP: blocked " + blocked + " requests");
+function loadFinishedCB(wv)
+{
+ if (wv != tabs.current)
+ return;
+
+ var blocked = getPrivate(wv).blocked;
+ if (blocked > 0)
+ 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 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;
- }
- });
+function disconnect()
+{
+ sigs.forEach(function (key, value) {
+ if (value != -1)
+ {
+ signals.disconnect(value);
+ sigs[key] = -1;
+ }
+ });
}//}}}
return {
- init : function(c) {
- config = extensions.getConfig(c, defaultConfig);
- if (system.fileTest(config.whiteList, FileTest.regular | FileTest.symlink)) {
- var rawWhiteList = io.read(config.whiteList);
- try {
- persistentList = JSON.parse(rawWhiteList);
- }
- catch (e) {
- extensions.debug(me, e, "Error parsing persistentList");
- }
+ defaultConfig : defaultConfig,
+ init : function(c)
+ {
+ config = c;
+ if (system.fileTest(config.whiteList, FileTest.regular | FileTest.symlink))
+ {
+ var rawWhiteList = io.read(config.whiteList);
+ try
+ {
+ persistentList = JSON.parse(rawWhiteList);
+ }
+ catch (e)
+ {
+ extensions.debug(me, e, "Error parsing persistentList");
+ }
+ }
+ persistentList = persistentList || {};
+ connect();
+ bind(config.shortcut, showMenu, "requestpolicy");
+ bind(config.unblockCurrent, unblockCurrent, "requestpolicyUnblockCurrent");
+ bind(config.unblockAll, unblockAll, "requestpolicyUnblockAll");
+ return true;
+ },
+ end : function ()
+ {
+ disconnect();
+ unbind("requestpolicy");
+ unbind("requestpolicyUnblockCurrent");
+ unbind("requestpolicyUnblockAll");
}
- persistentList = persistentList || {};
- connect();
- bind(config.shortcut, showMenu, "requestpolicy");
- bind(config.unblockCurrent, unblockCurrent, "requestpolicyUnblockCurrent");
- bind(config.unblockAll, unblockAll, "requestpolicyUnblockAll");
- return true;
- },
- end : function () {
- disconnect();
- unbind("requestpolicy");
- unbind("requestpolicyUnblockCurrent");
- unbind("requestpolicyUnblockAll");
- }
-}
+};
// vim: set ft=javascript:
diff --git a/scripts/base.js b/scripts/base.js
index 0fd8dfd0..280d6d03 100644
--- a/scripts/base.js
+++ b/scripts/base.js
@@ -16,6 +16,7 @@ Object.freeze((function () {
lastInput : null,
lastPosition : 0,
newTab : false,
+ notify : null,
hintTypes : [ "a, textarea, select, input:not([type=hidden]), button, frame, iframe, [onclick], [onmousedown]," +
"[role=link], [role=option], [role=button], [role=option], img", // HINT_T_ALL
//[ "iframe",
@@ -278,7 +279,6 @@ Object.freeze((function () {
active.overlay.parentNode.removeChild(active.overlay);
active.hint.style.font = globals.font;
-
}
globals.active = element;
if (!globals.active.overlay)
@@ -287,6 +287,16 @@ Object.freeze((function () {
if (!globals.markHints)
globals.active.hint.parentNode.appendChild(globals.active.overlay);
+ var e = element.element;
+ if (e.href || e.src)
+ globals.notify.innerText = encodeURI(e.href || e.ret);
+ else if (e.name)
+ globals.notify.innerText = e.tagName.toLowerCase() + ", name=" + e.name;
+ else if (e.innerText && e.innerText.trim().length > 0)
+ globals.notify.innerText = e.tagName.toLowerCase() + ": " + e.innerText.replace("\n\r", "").trim();
+ else
+ globals.notify.innerText = e.tagName.toLowerCase();
+
globals.active.overlay.style.background = globals.activeColor;
globals.active.hint.style.fontSize = globals.bigFont;
};
@@ -448,6 +458,18 @@ Object.freeze((function () {
return __evaluate(globals.elements[0].element, type);
}
+ globals.notify = document.createElement("div");
+ globals.notify.style.cssText =
+ "bottom:0px;left:0px;position:fixed;z-index:1000;" +
+ "text-overflow:ellipsis;white-space:nowrap;overflow:hidden;max-width:100%;" +
+ "border-right:1px solid #555;" +
+ "border-top:1px solid #555;" +
+ "padding-right:2px;" +
+ "border-radius:0px 5px 0px 0px;letter-spacing:0px;background:" + globals.bgColor + ";" +
+ "color:" + globals.fgColor + ";font:" + globals.font + ";font-size:" + globals.fontSize + ";";
+ globals.notify.id = "dwb_hint_notifier";
+ document.body.appendChild(globals.notify);
+
__getTextHints(globals.elements);
globals.activeArr = globals.elements;
__setActive(globals.elements[0]);
@@ -569,6 +591,8 @@ Object.freeze((function () {
globals.lastPosition = 0;
globals.lastInput = null;
globals.positions = [];
+ globals.notify.parentNode.removeChild(globals.notify);
+ globals.notify = null;
};
var __evaluate = function (e, type)
{
diff --git a/scripts/lib/dwb.js b/scripts/lib/dwb.js
index a66afb67..b0cd86a7 100644
--- a/scripts/lib/dwb.js
+++ b/scripts/lib/dwb.js
@@ -155,7 +155,7 @@
var i = _getPrivateIdx(this, key, identifier);
if (i !== -1)
return _privProps[i].value;
- return null;
+ return undefined;
}
},
"notify" :
@@ -164,6 +164,38 @@
{
return this.connect("notify::" + util.uncamelize(name), callback, after || false);
}
+ },
+ "connectBlocked" :
+ {
+ value : function(name, callback, after)
+ {
+ var self = this;
+ var sig = self.connect(name, function() {
+ self.blockSignal(sig);
+ callback.apply(null, arguments);
+ self.unblockSignal(sig);
+ });
+ return sig;
+ }
+ },
+ "notifyBlocked" :
+ {
+ value : function(name, callback, after)
+ {
+ return this.connectBlocked("notify::" + util.uncamelize(name), callback, after || false);
+ }
+ }
+ });
+ Object.defineProperties(Deferred.prototype, {
+ "done" : {
+ value : function(method) {
+ return this.then(method);
+ }
+ },
+ "fail" : {
+ value : function(method) {
+ return this.then(null, method);
+ }
}
});
})();
diff --git a/src/dwb.c b/src/dwb.c
index 7fdb6f7f..9974875b 100644
--- a/src/dwb.c
+++ b/src/dwb.c
@@ -4210,7 +4210,6 @@ dwb_init_gui()
/* entry */
dwb.gui.entry = gtk_entry_new();
- gtk_entry_set_inner_border(GTK_ENTRY(dwb.gui.entry), NULL);
gtk_entry_set_has_frame(GTK_ENTRY(dwb.gui.entry), false);
gtk_entry_set_inner_border(GTK_ENTRY(dwb.gui.entry), false);
diff --git a/src/js.c b/src/js.c
index c1a2a85d..e69a5ecf 100644
--- a/src/js.c
+++ b/src/js.c
@@ -332,4 +332,12 @@ js_array_iterator_next(js_array_iterator *iter, JSValueRef *exc)
return JSObjectGetPropertyAtIndex(iter->ctx, iter->array, iter->current_index++, exc);
}
+JSObjectRef
+js_value_to_function(JSContextRef ctx, JSValueRef val, JSValueRef *exc)
+{
+ JSObjectRef ret = JSValueToObject(ctx, val, exc);
+ if (ret != NULL && JSObjectIsFunction(ctx, ret))
+ return ret;
+ return NULL;
+}
diff --git a/src/js.h b/src/js.h
index 9fe6fd7b..d0aa51e2 100644
--- a/src/js.h
+++ b/src/js.h
@@ -38,6 +38,7 @@ gboolean js_print_exception(JSContextRef ctx, JSValueRef exception);
JSObjectRef js_make_function(JSContextRef ctx, const char *script);
JSValueRef js_json_to_value(JSContextRef ctx, const char *text);
JSValueRef js_context_change(JSContextRef, JSContextRef, JSValueRef, JSValueRef *);
+JSObjectRef js_value_to_function(JSContextRef, JSValueRef, JSValueRef *);
typedef struct _js_array_iterator {
JSContextRef ctx;
diff --git a/src/scripts.c b/src/scripts.c
index ec1a6ede..95e2158e 100644
--- a/src/scripts.c
+++ b/src/scripts.c
@@ -62,6 +62,12 @@ struct _SSignal {
GObject *object;
JSObjectRef func;
};
+typedef struct DeferredPriv_s
+{
+ JSObjectRef reject;
+ JSObjectRef resolve;
+ JSObjectRef next;
+} DeferredPriv;
//static GSList *s_signals;
#define S_SIGNAL(X) ((SSignal*)X->data)
@@ -97,10 +103,13 @@ static Sigmap s_sigmap[] = {
static JSObjectRef make_object_for_class(JSContextRef ctx, JSClassRef class, GObject *o, gboolean);
-static JSValueRef connect_object(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc);
-static JSValueRef disconnect_object(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc);
+static JSValueRef gobject_connect(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc);
+static JSValueRef gobject_block_signal(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc);
+static JSValueRef gobject_unblock_signal(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc);
+static JSValueRef gobject_disconnect(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc);
static JSValueRef wv_load_uri(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc);
+static JSValueRef wv_stop_loading(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc);
static JSValueRef wv_history(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc);
static JSValueRef wv_reload(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc);
static JSValueRef wv_inject(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc);
@@ -108,12 +117,15 @@ static JSValueRef wv_inject(JSContextRef ctx, JSObjectRef function, JSObjectRef
static JSValueRef wv_to_png(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc);
#endif
static JSStaticFunction default_functions[] = {
- { "connect", connect_object, kJSDefaultAttributes },
- { "disconnect", disconnect_object, kJSDefaultAttributes },
+ { "connect", gobject_connect, kJSDefaultAttributes },
+ { "blockSignal", gobject_block_signal, kJSDefaultAttributes },
+ { "unblockSignal", gobject_unblock_signal, kJSDefaultAttributes },
+ { "disconnect", gobject_disconnect, kJSDefaultAttributes },
{ 0, 0, 0 },
};
static JSStaticFunction wv_functions[] = {
{ "loadUri", wv_load_uri, kJSDefaultAttributes },
+ { "stopLoading", wv_stop_loading, kJSDefaultAttributes },
{ "history", wv_history, kJSDefaultAttributes },
{ "reload", wv_reload, kJSDefaultAttributes },
{ "inject", wv_inject, kJSDefaultAttributes },
@@ -190,6 +202,7 @@ enum {
CONSTRUCTOR_DOWNLOAD,
CONSTRUCTOR_FRAME,
CONSTRUCTOR_SOUP_MESSAGE,
+ CONSTRUCTOR_DEFERRED,
CONSTRUCTOR_LAST,
};
@@ -203,7 +216,7 @@ static JSObjectRef make_object(JSContextRef ctx, GObject *o);
static JSObjectRef s_sig_objects[SCRIPTS_SIG_LAST];
static JSGlobalContextRef s_global_context;
static GSList *s_script_list;
-static JSClassRef s_gobject_class, s_webview_class, s_frame_class, s_download_class, s_download_class, s_message_class;
+static JSClassRef s_gobject_class, s_webview_class, s_frame_class, s_download_class, s_download_class, s_message_class, s_deferred_class;
static gboolean s_commandline = false;
static JSObjectRef s_array_contructor;
static JSObjectRef s_completion_callback;
@@ -277,6 +290,7 @@ inject(JSContextRef ctx, JSContextRef wctx, JSObjectRef function, JSObjectRef th
if (func != NULL && JSObjectIsFunction(ctx, func))
{
JSValueRef wret = JSObjectCallAsFunction(wctx, func, NULL, count, count == 1 ? args : NULL, NULL) ;
+ // This could be replaced with js_context_change
char *retx = js_value_to_json(wctx, wret, -1, NULL);
if (retx)
{
@@ -356,8 +370,8 @@ ssignal_new()
static void
make_callback(JSContextRef ctx, JSObjectRef this, GObject *gobject, const char *signalname, JSValueRef value, StopCallbackNotify notify, JSValueRef *exception)
{
- JSObjectRef func = JSValueToObject(ctx, value, exception);
- if (func != NULL && JSObjectIsFunction(ctx, func))
+ JSObjectRef func = js_value_to_function(ctx, value, exception);
+ if (func != NULL)
{
CallbackData *c = callback_data_new(gobject, this, func, notify);
g_signal_connect_swapped(gobject, signalname, G_CALLBACK(callback), c);
@@ -430,9 +444,13 @@ tabs_get_nth(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, siz
static GList *
find_webview(JSObjectRef o)
{
- GList *r = NULL;
- for (r = dwb.state.views; r && VIEW(r)->script_wv != o; r=r->next);
- return r;
+ for (GList *r = dwb.state.fview; r; r=r->next)
+ if (VIEW(r)->script_wv == o)
+ return r;
+ for (GList *r = dwb.state.fview->prev; r; r=r->prev)
+ if (VIEW(r)->script_wv == o)
+ return r;
+ return NULL;
}
/* wv_status_cb {{{*/
static gboolean
@@ -470,6 +488,15 @@ wv_load_uri(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t arg
return false;
}/*}}}*/
+static JSValueRef
+wv_stop_loading(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc)
+{
+ WebKitWebView *wv = JSObjectGetPrivate(this);
+ if (wv != NULL)
+ webkit_web_view_stop_loading(wv);
+ return UNDEFINED;
+}
+
/* wv_history {{{*/
static JSValueRef
wv_history(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc)
@@ -729,11 +756,9 @@ static JSObjectRef
sp_callback_create(JSContextRef ctx, size_t argc, const JSValueRef argv[], JSValueRef *exc)
{
JSObjectRef ret = NULL;
- if (argc > 0)
+ if (argc > 0)
{
- ret = JSValueToObject(ctx, argv[0], exc);
- if (ret == NULL || !JSObjectIsFunction(ctx, ret))
- ret = NULL;
+ ret = js_value_to_function(ctx, argv[0], exc);
}
return ret;
}
@@ -970,15 +995,11 @@ global_bind(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size
return JSValueMakeBoolean(ctx, false);
}
keystr = js_value_to_char(ctx, argv[0], JS_STRING_MAX, exc);
- JSObjectRef func = JSValueToObject(ctx, argv[1], exc);
+
+ JSObjectRef func = js_value_to_function(ctx, argv[1], exc);
if (func == NULL)
goto error_out;
- if (!JSObjectIsFunction(ctx, func))
- {
- js_make_exception(ctx, exc, EXCEPTION("bind: not a function."));
- goto error_out;
- }
if (argc > 2)
{
name = js_value_to_char(ctx, argv[2], JS_STRING_MAX, exc);
@@ -1147,8 +1168,8 @@ global_send_request(JSContextRef ctx, JSObjectRef f, JSObjectRef thisObject, siz
if (uri == NULL)
return JSValueMakeNumber(ctx, -1);
- function = JSValueToObject(ctx, argv[1], exc);
- if (function == NULL || !JSObjectIsFunction(ctx, function))
+ function = js_value_to_function(ctx, argv[1], exc);
+ if (function == NULL)
goto error_out;
if (argc > 2)
@@ -1219,14 +1240,10 @@ global_tab_complete(JSContextRef ctx, JSObjectRef f, JSObjectRef thisObject, siz
js_make_exception(ctx, exc, EXCEPTION("tabComplete: invalid argument."));
return UNDEFINED;
}
- s_completion_callback = JSValueToObject(ctx, argv[2], exc);
+ s_completion_callback = js_value_to_function(ctx, argv[2], exc);
if (s_completion_callback == NULL)
return UNDEFINED;
- if (!JSObjectIsFunction(ctx, s_completion_callback))
- {
- js_make_exception(ctx, exc, EXCEPTION("tabComplete: arguments[2] is not a function."));
- return UNDEFINED;
- }
+
dwb.state.script_comp_readonly = false;
if (argc > 3 && JSValueIsBoolean(ctx, argv[3]))
{
@@ -1320,12 +1337,10 @@ global_timer_start(JSContextRef ctx, JSObjectRef f, JSObjectRef thisObject, size
if ((msec = JSValueToNumber(ctx, argv[0], exc)) == NAN )
return JSValueMakeNumber(ctx, -1);
- JSObjectRef func = JSValueToObject(ctx, argv[1], exc);
- if (func == NULL || !JSObjectIsFunction(ctx, func))
- {
- js_make_exception(ctx, exc, EXCEPTION("timerStart: argument 2 is not a function."));
+ JSObjectRef func = js_value_to_function(ctx, argv[1], exc);
+ if (func == NULL)
return JSValueMakeNumber(ctx, -1);
- }
+
JSValueProtect(ctx, func);
int ret = g_timeout_add((int)msec, (GSourceFunc)timeout_callback, func);
@@ -1379,6 +1394,116 @@ util_get_mode(JSContextRef ctx, JSObjectRef f, JSObjectRef thisObject, size_t ar
{
return JSValueMakeNumber(ctx, BASIC_MODES(dwb.state.mode));
}
+
+void
+deferred_destroy(JSContextRef ctx, JSObjectRef this, DeferredPriv *priv)
+{
+ g_return_if_fail(this != NULL);
+
+ if (priv == NULL)
+ priv = JSObjectGetPrivate(this);
+ JSObjectSetPrivate(this, NULL);
+
+ g_free(priv);
+
+ JSValueUnprotect(ctx, this);
+}
+
+static JSObjectRef
+deferred_new(JSContextRef ctx)
+{
+ DeferredPriv *priv = g_malloc(sizeof(DeferredPriv));
+ priv->resolve = priv->reject = priv->next = NULL;
+
+ JSObjectRef ret = JSObjectMake(ctx, s_deferred_class, priv);
+ JSValueProtect(ctx, ret);
+
+ return ret;
+}
+static JSValueRef
+deferred_then(JSContextRef ctx, JSObjectRef f, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc)
+{
+ DeferredPriv *priv = JSObjectGetPrivate(this);
+ if (priv == NULL)
+ return NIL;
+
+ if (argc > 0)
+ priv->resolve = js_value_to_function(ctx, argv[0], NULL);
+ if (argc > 1)
+ priv->reject = js_value_to_function(ctx, argv[1], NULL);
+
+ priv->next = deferred_new(ctx);
+
+ return priv->next;
+}
+static DeferredPriv *
+deferred_transition(JSContextRef ctx, JSObjectRef old, JSObjectRef new)
+{
+ DeferredPriv *opriv = JSObjectGetPrivate(old);
+ DeferredPriv *npriv = JSObjectGetPrivate(new);
+
+ npriv->resolve = opriv->resolve;
+ npriv->reject = opriv->reject;
+ npriv->next = opriv->next;
+
+ deferred_destroy(ctx, old, opriv);
+ return npriv;
+}
+static JSValueRef
+deferred_resolve(JSContextRef ctx, JSObjectRef f, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc)
+{
+ JSValueRef ret = NULL;
+
+ DeferredPriv *priv = JSObjectGetPrivate(this);
+ if (priv == NULL)
+ return UNDEFINED;
+
+ if (priv->resolve)
+ ret = JSObjectCallAsFunction(ctx, priv->resolve, NULL, argc, argv, exc);
+
+ JSObjectRef next = priv->next;
+ deferred_destroy(ctx, this, priv);
+
+ if (next)
+ {
+ if ( ret && JSValueIsObjectOfClass(ctx, ret, s_deferred_class) )
+ {
+ JSObjectRef o = JSValueToObject(ctx, ret, NULL);
+ deferred_transition(ctx, next, o)->reject = NULL;
+ }
+ else
+ deferred_resolve(ctx, f, next, argc, argv, exc);
+ }
+ return UNDEFINED;
+}
+static JSValueRef
+deferred_reject(JSContextRef ctx, JSObjectRef f, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc)
+{
+ JSValueRef ret = NULL;
+
+ DeferredPriv *priv = JSObjectGetPrivate(this);
+ if (priv == NULL)
+ return UNDEFINED;
+
+ if (priv->reject)
+ ret = JSObjectCallAsFunction(ctx, priv->reject, NULL, argc, argv, exc);
+
+ JSObjectRef next = priv->next;
+ deferred_destroy(ctx, this, priv);
+
+ if (next)
+ {
+ if ( ret && JSValueIsObjectOfClass(ctx, ret, s_deferred_class) )
+ {
+ JSObjectRef o = JSValueToObject(ctx, ret, NULL);
+ deferred_transition(ctx, next, o)->resolve = NULL;
+ }
+ else
+ deferred_reject(ctx, f, next, argc, argv, exc);
+ }
+ return UNDEFINED;
+}
+
/* DATA {{{*/
/* data_get_profile {{{*/
static JSValueRef
@@ -1532,8 +1657,8 @@ system_spawn(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, siz
}
if (argc > 1)
{
- oc = JSValueToObject(ctx, argv[1], NULL);
- if ( oc == NULL || !JSObjectIsFunction(ctx, oc) )
+ oc = js_value_to_function(ctx, argv[1], NULL);
+ if ( oc == NULL )
{
if (!JSValueIsNull(ctx, argv[1]))
ret |= SPAWN_STDOUT_FAILED;
@@ -1541,8 +1666,8 @@ system_spawn(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, siz
}
}
if (argc > 2) {
- ec = JSValueToObject(ctx, argv[2], NULL);
- if ( ec == NULL || !JSObjectIsFunction(ctx, ec) )
+ ec = js_value_to_function(ctx, argv[2], NULL);
+ if ( ec == NULL )
{
if (!JSValueIsNull(ctx, argv[2]))
ret |= SPAWN_STDERR_FAILED;
@@ -1557,7 +1682,9 @@ system_spawn(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, siz
}
if (!g_shell_parse_argv(cmdline, &srgc, &srgv, NULL) ||
- !g_spawn_async_with_pipes(NULL, srgv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL, oc != NULL ? &outfd : NULL, ec != NULL ? &errfd : NULL, NULL))
+ !g_spawn_async_with_pipes(NULL, srgv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL,
+ oc != NULL ? &outfd : NULL,
+ ec != NULL ? &errfd : NULL, NULL))
{
js_make_exception(ctx, exc, EXCEPTION("spawning %s failed."), cmdline);
ret |= SPAWN_FAILED;
@@ -1709,38 +1836,13 @@ io_error(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t
}
return UNDEFINED;
}/*}}}*/
-static JSValueRef
-io_status_bar(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exc)
-{
- if (argc < 1)
- return UNDEFINED;
-
- JSObjectRef o = JSValueToObject(ctx, argv[0], exc);
- if (o == NULL)
- return UNDEFINED;
-
- char *middle = js_get_string_property(ctx, o, "middle");
- char *right = js_get_string_property(ctx, o, "right");
-
- if (middle != NULL)
- gtk_label_set_markup(GTK_LABEL(dwb.gui.urilabel), middle);
-
- if (right != NULL)
- gtk_label_set_markup(GTK_LABEL(dwb.gui.rstatus), right);
-
- g_free(middle);
- g_free(right);
- return UNDEFINED;
-}
static JSValueRef
io_dir_names(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exc)
{
if (argc < 1)
- {
- js_make_exception(ctx, exc, EXCEPTION("io.dirNames: missing argument."));
return NIL;
- }
+
JSValueRef ret;
GDir *dir;
char *dir_name = js_value_to_char(ctx, argv[0], PATH_MAX, exc);
@@ -1752,7 +1854,8 @@ io_dir_names(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, siz
if ((dir = g_dir_open(dir_name, 0, NULL)) != NULL)
{
GSList *list = NULL;
- while ((name = g_dir_read_name(dir)) != NULL) {
+ while ((name = g_dir_read_name(dir)) != NULL)
+ {
list = g_slist_prepend(list, (gpointer)js_char_to_value(ctx, name));
}
g_dir_close(dir);
@@ -1820,10 +1923,7 @@ static JSValueRef
io_print(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exc)
{
if (argc == 0)
- {
- js_make_exception(ctx, exc, EXCEPTION("io.print needs an argument."));
return UNDEFINED;
- }
FILE *stream = stdout;
if (argc >= 2)
@@ -1884,10 +1984,7 @@ static JSObjectRef
download_constructor_cb(JSContextRef ctx, JSObjectRef constructor, size_t argc, const JSValueRef argv[], JSValueRef* exception)
{
if (argc<1)
- {
- js_make_exception(ctx, exception, EXCEPTION("Download constructor: missing argument"));
return JSValueToObject(ctx, NIL, NULL);
- }
char *uri = js_value_to_char(ctx, argv[0], -1, exception);
if (uri == NULL)
@@ -1907,6 +2004,11 @@ download_constructor_cb(JSContextRef ctx, JSObjectRef constructor, size_t argc,
WebKitDownload *download = webkit_download_new(request);
return JSObjectMake(ctx, s_download_class, download);
}/*}}}*/
+static JSObjectRef
+deferred_constructor_cb(JSContextRef ctx, JSObjectRef constructor, size_t argc, const JSValueRef argv[], JSValueRef* exception)
+{
+ return deferred_new(ctx);
+}
/* stop_download_notify {{{*/
static gboolean
@@ -1955,57 +2057,57 @@ download_cancel(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t
static JSValueRef
gui_get_window(JSContextRef ctx, JSObjectRef object, JSStringRef property, JSValueRef* exception)
{
- return make_object_for_class(ctx, s_gobject_class, G_OBJECT(dwb.gui.window), false);
+ return make_object_for_class(ctx, s_gobject_class, G_OBJECT(dwb.gui.window), true);
}
static JSValueRef
gui_get_main_box(JSContextRef ctx, JSObjectRef object, JSStringRef property, JSValueRef* exception)
{
- return make_object_for_class(ctx, s_gobject_class, G_OBJECT(dwb.gui.vbox), false);
+ return make_object_for_class(ctx, s_gobject_class, G_OBJECT(dwb.gui.vbox), true);
}
static JSValueRef
gui_get_tab_box(JSContextRef ctx, JSObjectRef object, JSStringRef property, JSValueRef* exception)
{
- return make_object_for_class(ctx, s_gobject_class, G_OBJECT(dwb.gui.topbox), false);
+ return make_object_for_class(ctx, s_gobject_class, G_OBJECT(dwb.gui.topbox), true);
}
static JSValueRef
gui_get_content_box(JSContextRef ctx, JSObjectRef object, JSStringRef property, JSValueRef* exception)
{
- return make_object_for_class(ctx, s_gobject_class, G_OBJECT(dwb.gui.mainbox), false);
+ return make_object_for_class(ctx, s_gobject_class, G_OBJECT(dwb.gui.mainbox), true);
}
static JSValueRef
gui_get_status_widget(JSContextRef ctx, JSObjectRef object, JSStringRef property, JSValueRef* exception)
{
- return make_object_for_class(ctx, s_gobject_class, G_OBJECT(dwb.gui.statusbox), false);
+ return make_object_for_class(ctx, s_gobject_class, G_OBJECT(dwb.gui.statusbox), true);
}
static JSValueRef
gui_get_status_alignment(JSContextRef ctx, JSObjectRef object, JSStringRef property, JSValueRef* exception)
{
- return make_object_for_class(ctx, s_gobject_class, G_OBJECT(dwb.gui.alignment), false);
+ return make_object_for_class(ctx, s_gobject_class, G_OBJECT(dwb.gui.alignment), true);
}
static JSValueRef
gui_get_status_box(JSContextRef ctx, JSObjectRef object, JSStringRef property, JSValueRef* exception)
{
- return make_object_for_class(ctx, s_gobject_class, G_OBJECT(dwb.gui.status_hbox), false);
+ return make_object_for_class(ctx, s_gobject_class, G_OBJECT(dwb.gui.status_hbox), true);
}
static JSValueRef
gui_get_message_label(JSContextRef ctx, JSObjectRef object, JSStringRef property, JSValueRef* exception)
{
- return make_object_for_class(ctx, s_gobject_class, G_OBJECT(dwb.gui.lstatus), false);
+ return make_object_for_class(ctx, s_gobject_class, G_OBJECT(dwb.gui.lstatus), true);
}
static JSValueRef
gui_get_entry(JSContextRef ctx, JSObjectRef object, JSStringRef property, JSValueRef* exception)
{
- return make_object_for_class(ctx, s_gobject_class, G_OBJECT(dwb.gui.entry), false);
+ return make_object_for_class(ctx, s_gobject_class, G_OBJECT(dwb.gui.entry), true);
}
static JSValueRef
gui_get_uri_label(JSContextRef ctx, JSObjectRef object, JSStringRef property, JSValueRef* exception)
{
- return make_object_for_class(ctx, s_gobject_class, G_OBJECT(dwb.gui.urilabel), false);
+ return make_object_for_class(ctx, s_gobject_class, G_OBJECT(dwb.gui.urilabel), true);
}
static JSValueRef
gui_get_status_label(JSContextRef ctx, JSObjectRef object, JSStringRef property, JSValueRef* exception)
{
- return make_object_for_class(ctx, s_gobject_class, G_OBJECT(dwb.gui.rstatus), false);
+ return make_object_for_class(ctx, s_gobject_class, G_OBJECT(dwb.gui.rstatus), true);
}
/*}}}*/
@@ -2030,7 +2132,7 @@ signal_set(JSContextRef ctx, JSObjectRef object, JSStringRef js_name, JSValueRef
s_sig_objects[i] = NULL;
dwb.misc.script_signals &= ~(1<<i);
}
- else if ( (o = JSValueToObject(ctx, value, exception)) != NULL && JSObjectIsFunction(ctx, o))
+ else if ( (o = js_value_to_function(ctx, value, exception)) != NULL)
{
s_sig_objects[i] = o;
dwb.misc.script_signals |= (1<<i);
@@ -2197,11 +2299,12 @@ on_disconnect_object(SSignal *sig, GClosure *closure)
static void
notify_callback(GObject *o, GParamSpec *param, JSObjectRef func)
{
- JSValueRef argv[] = { make_object(s_global_context, o) };
+ JSObjectRef jso = make_object(s_global_context, o);
+ JSValueRef argv[] = { jso };
JSObjectCallAsFunction(s_global_context, func, NULL, 1, argv, NULL);
}
static JSValueRef
-connect_object(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc)
+gobject_connect(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc)
{
GConnectFlags flags = 0;
gulong id = 0;
@@ -2216,8 +2319,8 @@ connect_object(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t
if (name == NULL)
goto error_out;
- JSObjectRef func = JSValueToObject(ctx, argv[1], exc);
- if (func == NULL || !JSObjectIsFunction(ctx, func))
+ JSObjectRef func = js_value_to_function(ctx, argv[1], exc);
+ if (func == NULL)
goto error_out;
GObject *o = JSObjectGetPrivate(this);
@@ -2229,7 +2332,7 @@ connect_object(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t
if (strncmp(name, "notify::", 8) == 0)
{
- g_signal_connect_data(o, name, G_CALLBACK(notify_callback), func, NULL, flags);
+ id = g_signal_connect_data(o, name, G_CALLBACK(notify_callback), func, NULL, flags);
}
else
{
@@ -2266,8 +2369,33 @@ error_out:
g_free(name);
return JSValueMakeNumber(ctx, id);
}
+
static JSValueRef
-disconnect_object(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc)
+gobject_block_signal(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc)
+{
+ double sigid;
+ if (argc > 0 && (sigid = JSValueToNumber(ctx, argv[0], exc)) != NAN)
+ {
+ GObject *o = JSObjectGetPrivate(this);
+ if (o != NULL)
+ g_signal_handler_block(o, (int)sigid);
+ }
+ return UNDEFINED;
+}
+static JSValueRef
+gobject_unblock_signal(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc)
+{
+ double sigid;
+ if (argc > 0 && (sigid = JSValueToNumber(ctx, argv[0], exc)) != NAN)
+ {
+ GObject *o = JSObjectGetPrivate(this);
+ if (o != NULL)
+ g_signal_handler_unblock(o, (int)sigid);
+ }
+ return UNDEFINED;
+}
+static JSValueRef
+gobject_disconnect(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc)
{
int id;
if (argc > 0 && JSValueIsNumber(ctx, argv[0]) && (id = JSValueToNumber(ctx, argv[0], exc)) != NAN)
@@ -2515,7 +2643,6 @@ create_global_object()
{ "dirNames", io_dir_names, kJSDefaultAttributes },
{ "notify", io_notify, kJSDefaultAttributes },
{ "error", io_error, kJSDefaultAttributes },
- { "statusBar", io_status_bar, kJSDefaultAttributes },
{ 0, 0, 0 },
};
class = create_class("io", io_functions, NULL);
@@ -2607,6 +2734,18 @@ create_global_object()
s_constructors[CONSTRUCTOR_SOUP_MESSAGE] = create_constructor(s_global_context, "SoupMessage", s_message_class, NULL, NULL);
+ JSStaticFunction deferred_functions[] = {
+ { "then", deferred_then, kJSDefaultAttributes },
+ { "resolve", deferred_resolve, kJSDefaultAttributes },
+ { "reject", deferred_reject, kJSDefaultAttributes },
+ { 0, 0, 0 },
+ };
+ cd = kJSClassDefinitionEmpty;
+ cd.className = "Deferred";
+ cd.staticFunctions = deferred_functions;
+ s_deferred_class = JSClassCreate(&cd);
+ s_constructors[CONSTRUCTOR_DEFERRED] = create_constructor(s_global_context, "Deferred", s_deferred_class, deferred_constructor_cb, NULL);
+
JSStaticValue gui_values[] = {
{ "window", gui_get_window, NULL, kJSDefaultAttributes },
{ "mainBox", gui_get_main_box, NULL, kJSDefaultAttributes },
@@ -2666,8 +2805,8 @@ apply_scripts()
int i=0;
// XXX Not needed?
- JSValueRef *scripts = g_try_malloc(length * sizeof(JSValueRef));
- JSObjectRef *objects = g_try_malloc(length * sizeof(JSObjectRef));
+ JSValueRef *scripts = g_malloc(length * sizeof(JSValueRef));
+ JSObjectRef *objects = g_malloc(length * sizeof(JSObjectRef));
for (GSList *l=s_script_list; l; l=l->next, i++)
{
scripts[i] = JSObjectMake(s_global_context, NULL, NULL);
diff --git a/src/view.c b/src/view.c
index 856d10f6..f4194d0e 100644
--- a/src/view.c
+++ b/src/view.c
@@ -423,6 +423,7 @@ view_hovering_over_link_cb(WebKitWebView *web, char *title, char *uri, GList *gl
}
}/*}}}*/
+
/* view_mime_type_policy_cb {{{*/
static gboolean
view_mime_type_policy_cb(WebKitWebView *web, WebKitWebFrame *frame, WebKitNetworkRequest *request, char *mimetype, WebKitWebPolicyDecision *policy, GList *gl)
@@ -453,8 +454,6 @@ view_mime_type_policy_cb(WebKitWebView *web, WebKitWebFrame *frame, WebKitNetwor
return false;
}/*}}}*/
-
-
/* view_navigation_policy_cb {{{*/
static gboolean
view_navigation_policy_cb(WebKitWebView *web, WebKitWebFrame *frame, WebKitNetworkRequest *request, WebKitWebNavigationAction *action,
@@ -990,9 +989,9 @@ view_init_signals(GList *gl)
v->status->signals[SIG_LOAD_STATUS] = g_signal_connect(v->web, "notify::load-status", G_CALLBACK(view_load_status_cb), gl);
v->status->signals[SIG_LOAD_ERROR] = g_signal_connect(v->web, "load-error", G_CALLBACK(view_load_error_cb), gl);
- v->status->signals[SIG_LOAD_STATUS_AFTER] = g_signal_connect_after(v->web, "notify::load-status", G_CALLBACK(view_load_status_after_cb), gl);
+ v->status->signals[SIG_LOAD_STATUS_AFTER] = g_signal_connect(v->web, "notify::load-status", G_CALLBACK(view_load_status_after_cb), gl);
v->status->signals[SIG_POPULATE_POPUP] = g_signal_connect(v->web, "populate-popup", G_CALLBACK(view_populate_popup_cb), gl);
- v->status->signals[SIG_PROGRESS] = g_signal_connect(v->web, "notify::progress", G_CALLBACK(view_progress_cb), gl);
+ v->status->signals[SIG_PROGRESS] = g_signal_connect(v->web, "notify::progress", G_CALLBACK(view_progress_cb), gl);
v->status->signals[SIG_TITLE] = g_signal_connect(v->web, "notify::title", G_CALLBACK(view_title_cb), gl);
v->status->signals[SIG_URI] = g_signal_connect(v->web, "notify::uri", G_CALLBACK(view_uri_cb), gl);
v->status->signals[SIG_SCROLL] = g_signal_connect(v->web, "scroll-event", G_CALLBACK(view_scroll_cb), gl);