Nov 022011
 

If you don’t have a .ctags file in ~/

  touch .ctags
  [m]vim .ctags

Paste this in or just add the ‘–regex…’ lines to your existing ones

--langdef=js
--langmap=js:.js
--regex-JavaScript=/([A-Za-z0-9._$\(\)]+)[ \t]*[:=][ \t]*function[ \t]*\(/\1/m,method/
--regex-JavaScript=/([A-Za-z0-9._$\#\(\)]+)[ \t]*[:][ \t]*([A-Za-z0-9._\-\#\'\"]+)[ \t]*/\1/p,property/
--regex-JavaScript=/([A-Za-z0-9._$\#\(\)]+)[ \t]*[:][ \t]*([A-Za-z0-9\'\"._\-\#\(]+)[ \t]*\{/\1/p,property/
--regex-JavaScript=/var ([A-Za-z0-9._$\#]+)[ \t]*[=][ \t]*([A-Za-z0-9._'"\$\#\[\{]+)[,|;]/\1/v,variable/
--regex-JavaScript=/([A-Za-z0-9._$\#]+)[ \t]*[=][ \t]*([A-Za-z0-9._'"\$\#]+)extend\(/\1/c,class/

enjoy

 Posted by at 7:56 pm
Nov 042010
 

I am pasting this here so I can look at it easier. The original question, this and other answers can be found here

Your problem with Vim is that you don’t grok vi.

You mention cutting with yy and complain that you almost never want to cut whole lines. In fact programmers, editing source code, very often want to work on whole lines, ranges of lines and blocks of code. However, yy is only one of many way to yank text into the anonymous copy buffer (or “register” as it’s called in vi).

The “Zen” of vi is that you’re speaking a language. The initial y is a verb. The statement yy is a simple statement which is, essentially, an abbreviation for 0 y$:

1. 0 go to the beginning of this line.
2. y yank from here (up to where?)
3. $ up to the end of this line.

This can also be expressed as dd P (delete the current line and paste a copy back into place; leaving a copy in the anonymous register as a side effect). The y and d “verbs” take any movement as their “subject.” Thus yW is “yank from here (the cursor) to the end of the current/next (big) word” and y’a is “yank from here to the line containing the mark named ‘a’.”

If you only understand basic up, down, left, and right cursor movements then vi will be no more productive than a copy of “notepad” for you. (Okay, you’ll still have syntax highlighting and the ability to handle files larger than a piddling ~45KB or so; but work with me here).

vi has 26 “marks” and 26 “registers.” A mark is set to any cursor location using the m command. Each mark is designated by a single lower case letter. Thus ma sets the ‘a’ mark to the current location, and mz sets the ‘z’ mark. You can move to the line containing a mark using the ‘ (single quote) command. Thus ‘a moves to the beginning of the line containing the ‘a’ mark. You can move to the precise location of any mark using the ` (backquote) command. Thus `z will move directly to the exact location of the ‘z’ mark.

Because these are “movements” they can also be used as subjects for other “statements.”

So, one way to cut an arbitrary selection of text would be to drop a mark (I usually use ‘a’ as my “first” mark, ‘z’ as my next mark, ‘b’ as another, and ‘e’ as yet another (I don’t recall ever having interactively used more than four marks in 15 years of using vi; one creates one’s own conventions regarding how marks and registers are used by macros that don’t disturb one’s interactive context). Then we go the the other end of our desired text; we can start at either end, it doesn’t matter. Then we can simply use d`a to cut or y`a to copy. Thus the whole process has a 5 keystrokes overhead (six if we started in “insert” mode and needed to Esc out command mode). Once we’ve cut or copied then pasting in a copy is a single keystroke: p.

I say that this is one way to cut or copy text. However, it is only one of many. Frequently we can more succinctly describe the range of text without moving our cursor around and dropping a mark. For example if I’m in a paragraph of text I can use { and } movements to the beginning or end of the paragraph respectively. So, to move a paragraph of text I cut it using { d} (3 keystrokes). (If I happen to already be on the first or last line of the paragraph I can then simply use d} or d{ respectively.

The notion of “paragraph” defaults to something which is usually intuitively reasonable. Thus it often works for code as well as prose.

Frequently we know some pattern (regular expression) that marks one end or the other of the text in which we’re interested. Searching forwards or backwards are movements in vi. Thus they can also be used as “subjects” in our “statements.” So I can use d/foo to cut from the current line to the next line containing the string “foo” and y?bar to copy from the current line to the most recent (previous) line containing “bar.” If I don’t want whole lines I can still use the search movements (as statements of their own), drop my mark(s) and use the `x commands as described previously.

In addition to “verbs” and “subjects” vi also has “objects” (in the grammatical sense of the term). So far I’ve only described the use of the anonymous register. However, I can use any of the 26 “named” registers by prefixing the “object” reference with ” (the double quote modifier). Thus if I use “add I’m cutting the current line into the ‘a’ register and if I use “by/foo then I’m yanking a copy of the text from here to the next line containing “foo” into the ‘b’ register. To paste from a register I simply prefix the paste with the same modifier sequence: “ap pastes a copy of the ‘a’ register’s contents into the text after the cursor and “bP pastes a copy from ‘b’ to before the current line.

This notion of “prefixes” also adds the analogs of grammatical “adjectives” and “adverbs’ to our text manipulation “language.” Most commands (verbs) and movement (verbs or objects, depending on context) can also take numeric prefixes. Thus 3J means “join the next three lines” and d5} means “delete from the current line through the end of the fifth paragraph down from here.”

This is all intermediate level vi. None of it is Vim specific and there are far more advanced tricks in vi if you’re ready to learn them. If you were to master just these intermediate concepts then you’d probably find that you rarely need to write any macros because the text manipulation language is sufficiently concise and expressive to do most things easily enough using the editor’s “native” language.
A sampling of more advanced tricks:

There are a number of : commands, most notably the :% s/foo/bar/g global substitution technique. (That’s not advanced but other : commands can be). The whole : set of commands was historically inherited by vi’s previous incarnations as the ed (line editor) and later the ex (extended line editor) utilities. In fact vi is so named because it’s the visual interface to ex.

: commands normally operate over lines of text. ed and ex were written in an era when terminal screens were uncommon and many terminals were “teletype” (TTY) devices. So it was common to work from printed copies of the text, using commands through an extremely terse interface (common connection speeds were 110 baud, or, roughly, characters per second — which is slower than a fast typist; lags were common on multi-user interactive sessions; additionally there was often some motivation to conserve paper).

So the syntax of most : commands includes an address or range of addresses (line number) followed by a command. Naturally one could use literal line numbers: :127,215 s/foo/bar to change the first occurrence of “foo” into “bar” on each line between 127 and 215. One could also use some abbreviations such as . or $ for current and last lines respectively. One could also use relative prefixes + and – to refer to offsets after or before the curent line, respectively. Thus: :.,$j meaning “from the current line to the last line, join them all into one line”. :% is synonymous with :1,$ (all the lines).

The :… g and :… v commands bear some explanation as they are incredibly powerful. :… g is a prefix for “globally” applying a subsequent command to all lines which match a pattern (regular expression) while :… v applies such a command too all lines which do NOT match the given pattern (“v” from “conVerse”). As with other ex commands these can be prefixed by addressing/range references. Thus :.,+21g/foo/d means “delete any lines containing the string “foo” from the current one through the next 21 lines” while :.,$v/bar/d means “from here to the end of the file, delete any lines which DON’T contain the string “bar.”

It’s interesting that the common Unix command grep was actually inspired by this ex command (and is named after the way in which it was documented). The ex command :g/re/p (grep) was the way they documented how to “globally” “print” lines containing a “regular expression” (re). When ed and ex were used, the :p command was one of the first that anyone learned and often the first one used when editing any file. It was how you printed the current contents (usually just one page full at a time using :.,+25p or some such).

Note that :% g/…/d or (its reVerse/conVerse counterpart: :% v/…/d are the most common usage patterns. However there are couple of other ex commands which are worth remembering:

We can use m to move lines around, and j to join lines. For example if you have a list and you want to separate all the stuff matching (or conversely NOT matching some pattern) without deleting them, then you can use something like: :% g/foo/m$ … and all the “foo” lines will have been moved to the end of the file. (Note the other tip about using the end of your file as a scratch space). This will have preserved the relative order of all the “foo” lines while having extracted them from the rest of the list. (This would be equivalent to doing something like: 1G!GGmap!Ggrep foo1G:1,’a g/foo’/d (copy the file to it’s own tail, filter the tail through group, and delete all the stuff from the head).

To join lines usually I can find a pattern for all the lines which need to be joined to their predecessor (all the lines which start with “^ ” rather than “^ * ” in some bullet list, for example). For that case I’d use: :% g/^ /-1j (for every matching line, go up one line and join them). (BTW: for bullet lists trying to search for the bullet lines and join to the next doesn’t work for a couple reasons … it can join one bullet line to another, and it won’t join any bullet line to all of its continuations; it’ll only work pairwise on the matches).

Almost needless to mention you can use our old friend s (substitute) with the g and v (global/converse-global) commands. Usually you don’t need to do so. However, consider some case where you want to perform a substitution only on lines matching some other pattern. Often you can use a complicated pattern with captures and use back references to preserve the portions of the lines that you DON’T want to change. However, it will often be easier to separate the match from the substitution: :% g/foo/s/bar/zzz/g — for every line containing “foo” substitute all “bar” with “zzz.” (Something like :% s/\(.*foo.*\)bar\(.*\)/\1zzz\2/g would only work for the cases those instances of “bar” which were PRECEDED by “foo” on the same line; it’s ungainly enough already, and would have to be mangled further to catch all the cases where “bar” preceded “foo”)

The point is that there are more than just p, s, and d lines in the ex command set.

The : addresses can also refer to marks. Thus you can use: :’a,’bg/foo/j to join any line containing the string foo to its subsequent line, if it lies between the lines between the ‘a’ and ‘b’ marks. (Yes, all of the preceding ex command examples can be limited to subsets of the file’s lines by prefixing with these sorts of addressing expressions).

That’s pretty obscure (I’ve only used something like that a few times in the last 15 years). However, I’ll freely admit that I’ve often done things iteratively and interactively that could probably have been done more efficiently if I’d taken the time to think out the correct incantation.

Another very useful vi or ex command is :r to read in the contents of another file. Thus: :r foo inserts the contents of the file named “foo” at the current line.

More powerful is the :r! command. This reads the results of a command. It’s the same as suspending the vi session, running a command, redirecting its output to a temporary file, resuming your vi session, and reading in the contents from the temp. file.

Even more powerful are the ! (bang) and :… ! (ex bang) commands. These also execute external commands and read the results into the current text. However, they also filter selections of our text through the command! This we can sort all the lines in our file using 1G!Gsort (G is the vi “goto” command; it defaults to going to the last line of the file, but can be prefixed by a line number, such as 1, the first line). This is equivalent to the ex variant :1,$!sort. Writers often use ! with the Unix fmt or fold utilities for reformating or “word wrapping” selections of text. A very common macro is {!}fmt (reformat the current paragraph). Programmers sometimes use it to run their code, or just portions of it, through indent or other code reformatting tools.

Using the :r! and ! commands means that any external utility or filter can be treated as an extension of our editor. I have occasionally used these with scripts that pulled data from a database, or with wget or lynx commands that pulled data off a website, or ssh commands that pulled data from remote systems.

Another useful ex command is :so (short for :source). This reads the contents of a file as a series of commands. When you start vi it normally, implicitly, performs a :source on ~/.exinitrc file (and Vim usually does this on ~/.vimrc, naturally enough). The use of this is that you can change your editor profile on the fly by simply sourcing in a new set of macros, abbreviations, and editor settings. If you’re sneaky you can even use this as a trick for storing sequences of ex editing commands to apply to files on demand.

For example I have a seven line file (36 characters) which runs a file through wc, and inserts a C-style comment at the top of the file containing that word count data. I can apply that “macro” to a file by using a command like: vim +’so mymacro.ex’ ./mytarget

(The + command line option to vi and Vim is normally used to start the editing session at a given line number. However it’s a little known fact that one can follow the + by any valid ex command/expression, such as a “source” command as I’ve done here; for a simple example I have scripts which invoke: vi +’/foo/d|wq!’ ~/.ssh/known_hosts to remove an entry from my SSH known hosts file non-interactively while I’m re-imaging a set of servers).

Usually it’s far easier to write such “macros” using Perl, AWK, sed (which is, in fact, like grep a utility inspired by the ed command).

The @ command is probably the most obscure vi command. In occasionally teaching advanced systems administration courses for close to a decade I’ve met very few people who’ve ever used it. @ executes the contents of a register as if it were a vi or ex command.
Example: I often use: :r!locate … to find some file on my system and read its name into my document. From there I delete any extraneous hits, leaving only the full path to the file I’m interested in. Rather than laboriously Tab-ing through each component of the path (or worse, if I happen to be stuck on a machine without Tab completion support in its copy of vi) I just use:

1. 0i:r (to turn the current line into a valid :r command),
2. “cdd (to delete the line into the “c” register) and
3. @c execute that command.

That’s only 10 keystrokes (and the expression “cdd @c is effectively a finger macro for me, so I can type it almost as quickly as any common six letter word).
A sobering thought

I’ve only scratched to surface of vi’s power and none of what I’ve described here is even part of the “improvements” for which vim is named! All of what I’ve described here should work on any old copy of vi from 20 or 30 years ago.

There are people who have used considerably more of vi’s power than I ever will.

 Posted by at 9:11 pm  Tagged with:
Sep 212010
 

Working with Dojo for an enterprise project I found myself with the need to add icons at run-time to menu items. Dojo’s built in icon class system, in which the image URLs are specified in a style sheet, wouldn’t work for this as the images are added later by clients via a proprietary application that stores the image locations as a resource and provides a service endpoint which can be called via AJAX to return a JSON object which holds the locations for all of the images the client specified.

I did some googling but turned up only old results that didn’t seem to really utilize what I consider to be one of Dojo’s finer points, that is the ability to customize Dijits by inheriting from one and then overriding only what you want to change. In this case I opened up the Dojo source and looked at the dijit.MenuItem. The lines I needed to work with are shown here:

...
    templateString: dojo.cache("dijit", "templates/MenuItem.html"),

    attributeMap: dojo.delegate(dijit._Widget.prototype.attributeMap, {
    label: { node: "containerNode", type: "innerHTML" },
    iconClass: { node: "iconNode", type: "class" }
    }),
...

and here is the MenuItem.html fragment which is in the templates folder:

<tr class="dijitReset dijitMenuItem" dojoAttachPoint="focusNode" waiRole="menuitem" tabIndex="-1"
        dojoAttachEvent="onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick">
    <td class="dijitReset dijitMenuItemIconCell" waiRole="presentation">
        <img src="${_blankGif}" alt="" class="dijitIcon dijitMenuItemIcon" dojoAttachPoint="iconNode"/>
    </td>
    <td class="dijitReset dijitMenuItemLabel" colspan="2" dojoAttachPoint="containerNode"></td>
    <td class="dijitReset dijitMenuItemAccelKey" style="display: none" dojoAttachPoint="accelKeyNode"></td>
    <td class="dijitReset dijitMenuArrowCell" waiRole="presentation">
        <div dojoAttachPoint="arrowWrapper" style="visibility: hidden">
            <img src="${_blankGif}" alt="" class="dijitMenuExpand"/>
            <span class="dijitMenuExpandA11y">+</span>
        </div>
    </td>
</tr>

We going to use the attributeMap property to map a ‘src’ to that image in the template which we will pass in when instantiating our own version of a MenuItem. I set up a namespace for the client (we’ll use Foo for this) called Foo.UI where I could declare custom dijits. I then just declared this custom MenuItem by mixing in the old one and overriding its templateString and attributeMap properties, here is the complete code for my custom MenuItem:

dojo.provide("Foo.UI.MenuItem");
dojo.require("dijit.MenuItem");

dojo.declare('Foo.UI.MenuItem', dijit.MenuItem, {
    tpl: ['<tr class="dijitReset dijitMenuItem" dojoAttachPoint="focusNode" waiRole="menuitem" tabIndex="-1"',
        'dojoAttachEvent="onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick">',
        '<td class="dijitReset dijitMenuItemIconCell" waiRole="presentation" style="padding:1px 2px;">',
        '<img src = "" alt="" class="dijitIcon dijitMenuItemIcon mavbarIcon" dojoAttachPoint="iconNode"/></a></td>',
        '<td class="dijitReset dijitMenuItemLabel" colspan="2" dojoAttachPoint="containerNode" style="padding:1px 2px;"></td>',
        '<td class="dijitReset dijitMenuItemAccelKey" style="display: none" dojoAttachPoint="accelKeyNode"></td>',
        '<td class="dijitReset dijitMenuArrowCell" waiRole="presentation">',
        '<div dojoAttachPoint="arrowWrapper" style="visibility: hidden">',
        '<img src="${_blankGif}" alt="" class="dijitMenuExpand"/>',
        '<span class="dijitMenuExpandA11y">+</span></div></td></tr>'
    ],
    // we don't need the iconClass property so override the mapping
    // this will work for our MenuBarItem as well...
    attributeMap: dojo.delegate(dijit._Widget.prototype.attributeMap, {
        label: { node: "containerNode", type: "innerHTML" },
        icon: {node: "iconNode", type: "attribute", attribute: "src"}
    }),
    postMixInProperties: function() {
        this.templateString = this.tpl.join('');
        this.inherited(arguments);
    }
});

So elsewhere, in a function which has made an instance of a dijit.Menu I am looping over the JSON object returned from that endpoint and assigning the images like so (the labels and titles are stored on the object as well):

... new Foo.UI.MenuItem({
    label:  obj.text,
    icon: obj.href,
    title: obj.tooltip,
    onClick: function() {
        console.log('Hello World');
    }
})
...

Brilliant, I really like this about dojo.dijit! When the new instance of Foo.UI.MenuItem is made the properties I passed (label, icon, title, and onClick) in are available to the attributMap. I simply ‘map’ the value I passed in as ‘icon’ to what will be the ‘src’ property of that ‘img’ tag in the template at run-time. The result ended up like this:

Icons!

Icons are being specified at run-time

Now you could do this many different ways. You could specify a new HTML template and load that instead of putting the template in the mixin (like I did above), or you can go as far as overriding dijit._Templated class and changing the buildRendering() method to use another templating engine, but this should help to get you started.

Jul 102010
 

I finally put together a page to host my articles published in JSMag for those of you who might have missed them. The articles, titled “Roll Your Own” and dealing with the proposition of creating a custom JavaScript library from scratch, will run about a month or so behind the magazine’s releases so if you like the columns go pick up the current issue here.

The ‘Roll Your Own’ columns.

Jul 012010
 

The other day I forked the excellent javascript-tools Textmate bundle in order to add Douglas Crockford’s JSLint as an option to go along with JavaScriptLint and the Closure Compiler. You can find it here. I want to look at using Safari’s compiler in order to alleviate the Rhino dependancy, ad possibly include the newest jslint.js with a config file but, unfortunately, don’t have time at the moment. I will soon, but until then this early version at least fits in functionally and aesthetically with the rest of the bundle. Rhino is expected to be installed, as well as jslint,js to be located in ‘~/Library/JSLint’.

The enterprising can just open the bundle contents and hack away at the dclint.rb file to change any paths or dependencies. Hey look, screenshots!

Lint Menu

Added entry into the lint options menu

Jslint output

Fits into the bundle aesthetics

RML.post(#2)

 JavaScript  Comments Off
Apr 112010
 

Quick example of a header section of a web page that contains a few form elements done with RML:

  markup: {
    header: function() {
      var $header = RML.div({
        id:'header',
        content: RML.siblings(
          RML.h1('The Chat'),
          RML.hr(),
          RML.div({
            _class:'message-form',
            content: RML.textarea({
              name:'txt-message',
              id:'txt-message',
              rows:'4',
              cols:'60'
          }),
          RML.input({
            type:'button',
            id:'btn-send-message',
            name:'btn-send-message',
            value:'Send Message',
          }),
          RML.input({
            type:'button',
            id:'btn-clear-message',
            name:'btn-clear-message',
            value:'Clear Message',
          }),
          RML.input({
            type:'button',
            id:'btn-logout',
            name:'btn-logout',
            value:'Log Out',
          })
        )
      });
    return $header;
    } //end header
  }

I’m using it here in a larger object literal method which can be called with a refinement like so:

HTML rendered by the RML methods
The rendered HTML

Get the code at github or here on the RML page. I’ll post more later this week…

Apr 082010
 

I am going to blog more in depth this weekend about this little markup generating JavaScript that I’m working on. I know there are others, but what fun is that? Basically, RML will generate tag-based markup like HTML and XML from JavaScript. I have been using it for templating alone and within a larger Ext.js application with pleasing results. I just need to add more tag shortcuts to the object, but it is very usable now. Get it here or at my github repo.

Jan 132010
 

Just a quick post about integrating JSLint with Vim on a Windows XP machine. I had posted awhile back about integrating JavascriptLint with Vim on XP, but while re-reading The Good Parts I got the urge to revisit JSLint just to revel in the Crockfordness of it all…

First off, get Jesse Hallett’s excellent jslint.vim plugin here. I installed this on my Fedora box without a hitch (well, the only hitch was figuring out the name of the Spidermonkey package for Fedora 12, ‘js-devel’ I believe it was) but my work XP machine would spit this out when attempting a :jslint command:

Error detected while processing function <SNR>17_JSLint:
line  43:
E484: Con't open file C:\...\...\...\...\VIo1F3B.tmp

It’s obvious that some paths (literally, figuratively) were getting crossed somewhere (*Note you may also want to attempt to use cscript from the command line just to make sure it is, in fact, installed and working. I did, and mine was*.)

In my experience the first place to check for errors with Vim plugins is the PATH so I opened up Jesse’s plugin and focused on this section (lines 41-59 on his github repo version):

  let s:plugin_path = '"' . expand("~/") . '"'
  if has("win32")
    let s:cmd = 'cscript /NoLogo '
    let s:plugin_path = s:plugin_path . "vimfiles"
    let s:runjslint_ext = 'wsf'
  else
    if has("gui_macvim") && filereadable('/System/Library/Frameworks/JavaScriptCore.framework/Resources/jsc')
      let s:cmd = '/System/Library/Frameworks/JavaScriptCore.framework/Resources/jsc'
    else
      let s:cmd = 'js'
    endif
    let s:plugin_path = s:plugin_path . ".vim"
    let s:runjslint_ext = 'js'
  endif
  let s:plugin_path = s:plugin_path . "/plugin/jslint/"
  let s:cmd = "cd " . s:plugin_path . " && " . s:cmd . " " . s:plugin_path
               \ . "runjslint." . s:runjslint_ext
  let s:jslintrc_file = expand('~/.jslintrc')

Here’s the version I ended up with after experimenting for awhile:

let s:plugin_path = '"' . expand("C:/Program Files/Vim/vimfiles") . '"'
  let s:cmd = 'cscript /NoLogo '
  let s:runjslint_ext = 'wsf'
let s:plugin_path = s:plugin_path . "/plugin/jslint/"
let s:cmd = "cd " . s:plugin_path . " && " . s:cmd . " " . s:plugin_path
       \ . "runjslint." . s:runjslint_ext
let s:jslintrc_file = expand('C:/Program Files/Vim/_jslintrc')

So, I ended up changing 3 things:

  • Remove tests for which OS is being used
  • Explicitly state the plugin path
  • Changed the name and path of the jslintrc file

First, since we know this is for XP, the tests for Win32, Mac and ‘Nix are not needed. Second, there are more compact and portable ways to specify this path, but posting it this way makes it easy to adapt to your system path. Third, On my XP system my .vimrc is actually _vimrc and I keep it here in the vimfiles directory so it made sense to me to do the same with a jslintrc.

Speaking of the _jslintrc, it looks like the ‘fulljslint.js’ file is updated quite a bit on the jslint.com website, and allows for more options in the jslintrc file. I need to experiment with that next

Dec 312009
 

I want to post a quick bit here about three methods I use in the X library which make use of element classnames. First a method to detect if an element has a given class:

X.hasClass = function(element, $class) {
    var pattern = new RegExp("(^| )" + $class + "( |$)");
    //ternary to choose
    return pattern.test(element.className) ? true : false;
};

Breaking that down, you have the function taking two arguments. One, the element to check for the presence of the class name and two, the class name itself. Next, a RegEx is defined which will attempt to match the class name you passed in. The RexEx itself is made so that a portion of a string can be matched because of the way that classnames are applied to elements on the DOM, i.e. “spam eggs vikings”. Last, the ternary (return pattern.test…) executes depending on what the test() method returns. Remember, test() is a function of the RegEx object which returns a bool depending on a positive(or lack of) match. Test() is going to return a ‘true’ of the class name is found, ‘false’ if not.If you are unfamiliar with ternary operators, let’s explain by looking at what an if/else doing the same thing would look like.

if (pattern.test(element.className)) {
    return true;
}
else {
    return false;
}

That works, but it’s not the lean and mean js machine we are going for here. Now, the one line of the ternary:

return pattern.test(element.className) ? true : false;

And it works like this:
an action -something to evaluate- ? do if true : do if false

So, in practice you could check if an element had a class name by calling:

X.hasClass(myElement, 'myClass');

hasClass is going to return a Bool though, so usually you will use it as part of an expression:

if(X.hasClass(myElement, 'myClass') {
    do stuff if true
}

I rarely use hasClass outright, but the next function does.

To add a class to a single element or a collection of elements we have this:

X.addClass = function(element, $class) {
    var i;
    //is the element array-like?
    if(element.length) {
        for (i = 0; i < element.length; i++) {
            if (!X.hasClass(element[i], $class)) {
                element[i].className += element[i].className === "" ?
                $class : " "+$class;
            }
        }
    }
    else { //not array-like
        if (!X.hasClass(element, $class)) {
            element.className += element.className === "" ?
                $class : " "+$class;
        }
    }
    return element;
};

In Summary, addClass takes 2 arguments, an element and a class name, checks to see if the element passed in is a single element or a collection of elements, then checks the element(s) to see if they have the passed in class name (via hasClass). If not, element is then checked for the presence of any other classes. Why? If there is another class name already assigned to the element(s) you need to insert a space in front of the new class being appended. Finally the class name you passed in is appended (as long as it’s not already there) and the element is returned. Let’s combine the get method with this in a couple of practical examples:

Say you have an HTML page with these four divs contained in a fifth div:

<div id="stripes">
    <div id="div1"></div>
    <div id="div2"></div>
    <div id="div3"></div>
    <div id="div4"></div>
</div>

And maybe some styles to go with them:

#div1, #div2, #div3, #div4 {
    height: 50px;
    margin-top:10px;
    border-bottom: 1px solid #000;
}
.green {
    background-color: #7f9e7b;
}
.slate {
    background-color: #424242;
}
.grey {
    background-color: #888;
}

So, on a goofy little test page you might have this:

Classless divs

Classless divs


Since the get method returns either a single element or a collection of them, and since our new addClass function can handle either scenario you could grab all those divs and set their background to say, green, in one pass:

X.addClass(X.get('div', X.get('#stripes')), 'green');

Giving you this:

Now with some class (green to be exact)

Now with some class (green to be exact)

Breaking that expression down, recall that the get method will allow you to pass in a ‘context’ to restrain searching. Because I only wanted the divs inside of the div with the id of “stripes” I passed it (‘#stripes’) in along with the search for the generic ‘div’ tagname:

var divs = X.get('div', X.get('#stripes'));

You can break this up into 2 expressions if you want:

var stripes = X.get('#stripes');
var divs = X.get('div', stripes);

After getting the elements, I sent them to addClass. If you used the more verbose code above you would have:

var stripes = X.get('#stripes');
var divs = X.get('div', stripes);
X.addclass(divs, 'green');

In these examples the fact that addClass returns the element passed in is of no consequence. JavaScript functions always return a value, even if one is not specified (undefined in that case), so specifying element as the return value could just be ignored, but we are going to use it next to combine with removeClass.

Here is that removeClass function:

X.removeClass = function(element, $class) {
    var pattern = new RegExp("(^| )" + $class + "( |$)"),
    i;
    //is element array-like?
    if(element.length) {
        for (i = 0; i < element.length; i++) {
            element[i].className = element[i].className.replace(pattern, "$1");
            element[i].className = element[i].className.replace(/ $/, "");            
        }
    }
    else { //nope
        element.className = element.className.replace(pattern, "$1");
        element.className = element.className.replace(/ $/, "");
    }
    return element;
};

Before doing something pedestrian like just removing the ‘green’ classnames from the divs inside of ‘stripes’ let’s swing for the fence and remove the classnames, then add new ones all in one go. weeee!:

X.removeClass(X.addClass(X.get('div', X.get('#stripes')), 'slate'), 'green');

Now that test page would look like:

Class changed to 'slate'

Class changed to 'slate'

This works because of the fact that addClass is returning the element list containing all of the divs we want removeClass to operate on. If you look close you’ll notice that all you needed to do was to take the previous expression we used for adding the green classes at once:

X.addClass(X.get('div', X.get('#stripes')), 'green');

and wrapping it with the removeClass call:

X.removeClass([--previous expression--], 'slate');

There’s more to breakdown, but not too much. The removeClass function just uses the same methodology that addClass does for checking if element is an array-like object (has a length?) then looks for the passed in classname with a RegExp which will replace a match with an empty string using the ‘$1′ backreference (the second call to replace makes sure no whitespace is left over). Finally the element is returned, just like addClass. And, yes, you could invert the order to addClass(removeClass()), it doesn’t matter

All of these examples could have, obviously, been used on single elements. X.get, X.addClass and X.removeClass will take care of that for you. So if you wanted to change the second div back to green you would go:

X.removeClass(X.addClass(X.get('#div2'), 'green'), 'slate');

Notice there is no need to specify a context when using an id (it should be unique).

Dec 032009
 

Quick post here because I’ll probably need this myself later. I didn’t have any problems getting Emacs, CEDET, and ECB up and running on my Fedora box but my WinXP machine refused to byte-compile the cedet-build.el lisp file. This looks to be a common problem for folks using Emacs on Win with CEDET’s latest files from Sourceforge. After seeing that some people had success after getting the newest CVS repository files for CEDET I immediately searched for a git mirror (not wanting to have to use CVS) and found it here

The instructions on CEDET’s website are:
“If you are on Windows, and or don’t have make for some reason, you can use CEDET’s built in project management system to force CEDET to bootstrap itself. You can initiate the build process like this:”

    cd path/to/cedetdirectory
    emacs -Q -l cedet-build.el -f cedet-build

Since the Windows version of Emacs is in a self contained directory (mine is emacs-23.1/) with an executable named ‘runemacs.exe’ in the folder ‘emacs-23.1/bin/’ on my Desktop, I just changed the command to fit the environment properly. Opening a Cygwin bash prompt I did this:

$ cd ~/Desktop/cedet/
$ ~/Desktop/emacs-23.1/bin/runemacs.exe -Q -l cedet-build.el -f cedet-build

AND the freezing on step 6, setting up EDE goes away. ECB can now be setup