Making ubiq scripts easier to read

2 views
Skip to first unread message

Guy Fraser

unread,
Aug 31, 2008, 6:05:34 PM8/31/08
to ubiquity-core
Scripts that are easier to read benefit both new developers, learning
ubiq for the first time, and end-users, trying to work out what a
script does before installing it.

These are just some ponderings I had on how scripts could be made a
bit easier to read and some ways to promote consistency for certain
references.

*Easy to understand references*

One of my pet-hates with many ubiq scripts is the use of "pBlock" or
similar to reference the preview area. Why not call it "previewArea"
or something like that?

*Consistent references*

Reading through ubiq scripts I've seen all sorts of references to this
param including "p", "pBlock", "previewBlock", "preview", etc., and
that got me wondering how to promote consistent naming of things.

Currently, the reference to the preview block is passed in as the
first argument to the preview() method of a verb. However, would it be
better to simply scope the preview method to an object that has a
bunch of ready made references?

For example, in the ubiq core, you'd do something like this:

verb.preview.apply(usefulReferencesObj, arg1, arg2, etc)

So in the apply method you'd instantly have a bunch of useful
references, for example:

... snip ...

preview: function(arg1, arg2, etc) {
// stuff
this.preview.innerHTML = whatever;
}

The list of pre-defined properties and methods could then be listed on
a doc page in the author guide - the main benefit being that everyone
would then be referring to those things using standard names making
the code more readable and ubiq easier to learn.

*Nouns should be defined using a helper method*

It's great that we can define our own nouns, however it would be
useful if there was a helper method to do so. If nothing else this
would make it easy to scan a JS file and locate nouns, just as we can
locate verbs.

I'd really like to see ubiq files that just define nouns - so we get a
repository of nouns that don't necessarily have associated verbs.

You could then display a list of nouns, etc.

Furthermore, when defining a noun using the helper method, that method
could check that the noun is valid before adding it to the repository
of nouns - eg. does it have a suggest method, etc.

*Better named helper methods*

CmdUtils is a bit vague - it gives no real indication as to where the
reference is defined, eg. is it part of ubiq or firefox?

What if there were something like:

nouns = [] // an object that deals exclusively with nouns
verbs = [] // an object that deals exclusively with verbs
utils // general utils provided by ubiq

So you could do:

nouns.add({
// object defining a noun
});

verbs.add({ ... });

The add method is essentially a wrapper for push() that does some
extra checking (eg. make sure the name isn't a reserved word) and also
adds a named reference for the verb/noun.

Suggested methods and properties for nouns/verbs would be:

.length // how many nouns / verbs are there?
.find(str) // find matching nouns/verbs in the object by name,
returning an array
.checkForUpdates(str) // check either a specific noun/verb for updates
(if str defined) otherwise check them all

In code, I could do things like:

nouns.contact.suggest(str) // get suggestions for arbitrary text

Note: "contact" is currently known as "noun_type_contact" which is a
bit verbose IMHO - why not just call it contact and make it obvious
that it's a noun using the nouns object?

*Example of a v1.0 script*

nouns.add({
name: 'access_key', // mandatory
authors: [{ ... }], // optional - array of author objects
homepage: '...', // optional
icon: '...', // optional - url to icon for this noun
license: '...', // optional - comma separated list of licenses
summary: '...', // optional - a short summary of what this noun is
for
description: '...', // optional - longer description of this noun
_whatever: function() { // optional
// internal method defined by noun developer
},
validate: function(input) { // optional?
// is the input applicable to this noun
},
suggest: function() { // optional if there is a validate method?
}
});

verbs.add({
name: 'access', // mandatory
authors: [{ ... }], // optional - array of author objects
homepage: '...', // optional
icon: '...', // optional - url to icon for this verb
license: '...', // optional - comma separated list of licenses
summary: '...', // optional - a short summary of what this verb does
description: '...', // optional - longer description of this noun
_whatever: function() { // optional
// internal method defined by verb developer
},
preview: { // mandatory - generates preview
this.previewArea.innerHTML(...);
},
execute: { // optional - execute the command
}
});

As you can see, everything is much more consistent and nouns become
first class citizens alongside verbs - hopefully promoting a growing
repository of re-usable nouns.

The authors array makes it easier to list multiple people who
contribute to a project, each author being defined in an object as
follows:

{name: '...', email: '...', homepage: '...', role: 'role they played
in this noun/verb'}

I believe "magic" words, like "this" and "in" etc., should also be
extensible, for example:

magic.add({
// object defining the magic word and what it does somehow
});

Anyway, I'll stop there to see what people think :)

Guy Fraser

unread,
Aug 31, 2008, 6:15:20 PM8/31/08
to ubiquity-core
Oh, forgot one other essential method on the verbs object:

verbs.find(str) // return an array of verbs matching the str

The find method would start simple - eg. just using jQuery's grep
method to return a list of verbs that contain the string passed in.

Then it would start to order and filter the list of returned values,
for example:

* for each of the verbs, look at what nouns they use and call the
validate method - if the noun isn't applicable, the verb isn't
applicable so ignore it
* how many times has the verb been used - bump popular verbs up the
list
* etc.

Oh, and another useful property for verb definitions:

.validate() // similar to noun validate method, the verb would look at
where it's being used (eg. URL of current tab) to determine if it's
usable in this context

Comments?

Guy Fraser

unread,
Aug 31, 2008, 6:19:17 PM8/31/08
to ubiquity-core
One more useful thing for verb definitions:

.aliases: ['foo','bar']

One or more aliases for the verb (rather than needing to create
duplicate definitions). The add method would create named references
to the verb definition object based on it's name and it's aliases.

Same property could exist in magic word definitions :)

Guy Fraser

unread,
Aug 31, 2008, 7:37:42 PM8/31/08
to ubiquity-core
I wish there was a way to edit posts! Gah!

Anyway, just thought of something else - a context property:

verbs.add({
...
contexts: [ ... ]
...
});

Valid entries in the array would be:

* 'command' = the verb applies when user is typing in a command
* 'context-menu' = command appears in context menu
* 'edit-menu' = command appears in edit menu
* 'view-menu' = command appears in view menu
* 'tools-menu' = command appears in tools menu

In cases where the command is appearing in a menu, the menu item would
be hidden if there are no suggestions or the verb/nouns don't
validate.

By not having verbs appearing in the context menu by default, and only
appear when they validate or there are suggestions, the context menu
will be much more useful IMHO.

Guy Fraser

unread,
Aug 31, 2008, 7:39:28 PM8/31/08
to ubiquity-core
Another context based on one of my recent posts:

* 'toolbar' = makes a toolbar button available for the verb :)

Guy Fraser

unread,
Aug 31, 2008, 7:56:40 PM8/31/08
to ubiquity-core
(sorry for all the separate messages, keep having ideas...)

The validate() and suggest() methods would work in tandem.

For example, if I have a single-word noun the validate() could return
false if the current text selection isn't a single word, however the
suggest() could provide a list of single words from that text so I
could choose a word from it at which point the noun would validate in
turn making the verb using that noun validate.
Reply all
Reply to author
Forward
0 new messages