Generates a usable preferences page for Opera extensions on the fly.
The motto: to handle preferences, write as little code as possible.
An example (works only in Opera, obviously).
To fully incorporate weakspec into your extension, you'll need 3 files:
options.html
extstorage.js
populator.js
They are all pre-compiled from CoffeeScript & can be found in
for-extensions
directory.
The main one is options.html
. It reads special options.weakspec.js
file, in which you specify a list of preferences (their groups, names,
types, default values, verification callbacks, etc). If
options.weakspec.js
is valid, options.html
automatically generate a
bunch of GUI elements, where users of your extension can set & check the
extension preferences.
That's very handy, I think. You don't need to write a boring 'preferences' code by yourself.
Please see examples
directory for several ready extensions. e02 goes
into more details about other real life staff.
All preferences are physically sit in widget.preferences
object. Unfortunately it is not a hash but a object similar to W3C
webstorage--a flat key-value store, where values can be only
strings.
weakspec encodes values into JSONified strings. To decode them, use 2
routines from extstorage.js
. See e02 example extension.
A short example:
var weakspec = {
"Rotation" : {
"angle" : {
"type" : "number",
"default" : 180,
"desc" : "Angle in degrees",
"range" : [-360, 360]
},
"domquery" : {
"type" : "string",
"default" : "img",
"desc" : "CSS selector",
"help" : "... for document.querySelectorAll()",
"allowEmpty" : false,
"validationRegexp" : null
}
}
}
Spec requires 1 variable weakspec
, which is a hash. A hash must
contain at least 1 group. Each group has unlimited number of
preferences. In the example above, we have 1 group named 'Rotation',
which have 2 preferences, named 'angle' & 'domquery'.
A 'type' key designates a GUI element for a preference & its additional options. For example, 'number' type can hold only a JavaScript number. If you supply an array or a string for it, a validation will fail.
-
default
A default value. Cannot be null. The possible value depends on a type.
-
desc
A description string that will be drawn on the left side.
-
help
A help string that will popup if user hovers the '?' sign on the right.
-
validationCallback
A function that takes 1 argument--a value and return
true
if value is valid &false
otherwise. Use this if your preference is so complex that provided constraints cannot suit you. ItvalidationCallback
is present & !=null
, all other constraints are ignored.
Any JS number, signed or unsigned.
-
range
An array of 2 elements: min & max.
A (probably short) JS string.
-
allowEmpty
A boolean. If
true
, the preference can contain empty string""
. -
validationRegexp
A string that contains a JS regexp. The preference value will be checked against it.
A fixed array of strings. Multi or single selectable.
-
data
An array.
-
selectedSize
A array of integers with 2 elements. For example:
"foobar" : { "desc" : "...", "type" : "list", "default" : ["one", "three"], "selectedSize" : [1, 2], "validationCallback" : null, "data" : ["one", "two", "three", "four"] }
[1, 2]
inselectedSize
means that min 1 element & max 2 elements in the list can be selected. IfselectedSize
would be equal to[1, 1]
that means only 1 element can be selected.
A JS boolean: true
or false
.
A JS string that can contain newlines.
-
allowEmpty
A boolean. If
true
, the preference can contain empty string""
. -
range
An array of 2 elements: min string length & max string length.
A string that represents color values in #rrggbb
(a hex triplet)
format.
A string that contain a valid email address.
-
allowEmpty
A boolean. If
true
, the preference can contain empty string""
.
A string in UTC ISO 8601 format (without decimal fractions).
-
allowEmpty
A boolean. If
true
, the preference can contain empty string""
. -
range
An array of 2 elements: min & max.
A string in YYYY-MM-DD
format.
-
allowEmpty
A boolean. If
true
, the preference can contain empty string""
. -
range
An array of 2 elements: min & max.
A string in YYYY-WNN
format, where 'W' is a literal char & 'NN' is a number
[1...48].
-
allowEmpty
A boolean. If
true
, the preference can contain empty string""
. -
range
An array of 2 elements: min & max.
options.weakspec.js
can have weakspec_opts
hash. At this moment, you
can supply with it a custom header displayed by options.html
. For
example:
var weakspec_opts = {}
weakspec_opts.header = "<h1>Hi, Mom!</h1>"
(Or any other valid html in weakspec_opts.header
.)
While constructing options.weakspec.js
open options.html
in Opera as
a any other local html page. You don't need to open it only from the
installed extension (but you can, of course). widget.preferences
object will be mocked.
Also make sure, you've unchecked [Scripts]->[Show parse errors and break on exception] in Dragonfly's Settings.
% gmake options.html
Run tests:
-
DOM-less part:
% gmake
-
Browser related (with Jasmine):
test/SpecRunner.html
-
Names of groups & preferences cannot contain
|
char. -
range
fortext
preference works only for upper limit due to availability ofmaxlength
html5 attribute for a textarea element but absence ofminlength
. -
datetime
expects iso 8601 format in UTC without decimal fractions. -
time
is broken. Probably it's an Opera bug, because<input type='time'>
cannot get through a validation phase.
MIT.