W3C home > Mailing lists > Public > spec-prod@w3.org > October to December 2012

Re: ReSpec2 not working locally in Firefox, Chrome or IE

From: Robin Berjon <robin@w3.org>
Date: Thu, 25 Oct 2012 14:33:29 +0200
Message-ID: <50893199.6050102@w3.org>
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 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Thursday, 25 October 2012 12:33:34 GMT