- From: Robin Berjon <robin@w3.org>
- Date: Thu, 25 Oct 2012 14:33:29 +0200
- To: Richard Cyganiak <richard@cyganiak.de>
- CC: spec-prod@w3.org
On 20/10/2012 19:33 , Richard Cyganiak wrote:
> Given that v2 is now obsolete, and that the documentation shipping
> with v3 is rather thin, can you tell me how one is supposed to
> develop ReSpec extensions these days?
If you've developed an extension for RSv2, then you should be in very
familiar territory.
If you look at one of the simplest modules, you can see how it works:
"""
// Module core/remove-respec
// Removes all ReSpec artefacts right before processing ends
define(
[],
function () {
return {
run: function (conf, doc, cb, msg) {
msg.pub("start", "core/remove-respec");
$(".remove, script[data-requiremodule]", doc).remove();
msg.pub("end", "core/remove-respec");
cb();
}
};
}
);
"""
To scan through this quickly, the usual structure is:
• A comment explaining what the module does, and listing the
configuration options
• A call to define(). This is what defines a module that can then be
required.
• The first parameter is an array of dependencies. Here there are none,
but you could have ["core/utils", "w3c/style"] for instance. Those get
loaded for you (and compiled into the build). You can also use that to
load text files (prefixing the file with text!). For more, check out
RequireJS.
• The second parameter is a function. The parameters to that function
are the objects corresponding to the dependencies you required (here, none).
• That function can do whatever it wants, but at some point it needs to
return an object that is the implementation of the module (here, that's
all it does).
• If the module is just a bunch of helpers (like core/utils.js) then
that object can be whatever. If it's meant to be one of the processors
in the pipeline (as above) then it must have at least one method called
"run".
• The run() method gets called with four parameters:
- conf: the configuration in use (defined by the document, with
defaults resolved and URI parameter overrides applied)
- doc: the Document being processed. Note that this is important
because it may not be the same as the 'document' object in scope for
your script. That's why you see that the jQuery code above does
$("selector", doc) in order to ensure that the selector is applied in
the right context.
- cb: that's a function which you call to indicate that the next step
in the pipeline can happen. If your pipeline step is synchronous, just
call that as the very last thing. If your pipeline step is asynchronous
and it's perfectly fine for the next step to proceed before you're
finished, call that as soon as it's fine for the next module to process
the document.
- msg: this is an eventing object that can be used to report all
sorts of information to ReSpec, and in fact to shells that can
encapsulate your document (e.g. to extract all the issues without
needing to know the syntax for issues). But the important thing is that
as soon as your module starts processing, you need to send it a "start"
message with your module name. And when you're done processing, you
likewise send an "end" message. Unlike cb(), you don't do this as soon
as possible in the asynchronous case but rather only when all processing
that might happen has been completed (successfully or not). This is
important because it allows ReSpec to know when all processing is done
(which can be used by tools to know that the spec has been generated),
or if there is a problem with a module it can discover that too. In the
simple sync case, just send "end" just before you call cb().
That's all for module creation. After that, if it's something you wish
to add to the core W3C processing, then add it to profile-w3c-common.js
(please only use that for truly consensual stuff though). If you want to
make another profile (in order to write other types of specs or
documents) then create something just like profile-w3c-common.js and
list the modules you want to have in there. That becomes your entry point.
If it's for a W3C module, you'll want to write some tests. See
tests/SpecRunner.html and tests/spec/* for details.
If it's for a different profile, you will very likely want to use some
like tools/build-w3c-common.js in order to produce a build. Builds are a
lot faster, and can also be used from the local FS without triggering
SOP errors.
I think that's it!
Yeah, I should dump this information in a page :)
--
Robin Berjon - http://berjon.com/ - @robinberjon
Received on Thursday, 25 October 2012 12:33:34 UTC