AvacDom Selector
Posted February 7th 2012, 8:51pm
I've recently been working on a new selector engine, which means a way of selecting elements. And I finished pretty recently, and so far I am happy with the result.
My new selector is just a single basic function, and it allows for traversing the DOM quickly and easily in a single string, simply by using symbols which mean things.

ALL of the methods used internally are native Javascript, which means it is reasonably fast.
Okay so here's how it works.

The symbols available for use are '+', '~', '>', '^', '<', '(', '[', '#','{', '.' and they each represent a movement in the DOM.
'+' - A plus symbol means 'nextSibling'
'~' - a squigly symbol means 'previousSibling' (I didn't use a minus sign, because they can often be used in ID names)
'>' - a greater than symbol means 'firstChild'
'^' - This up pointing symbol means 'lastChild'
'<' - a less than symbol means 'parentNode'
'(' - a bracket represent a tagname. For example '(body)' or '(div)'. An index can be specified inside the brackets like so '(div[1])'
'[' - a square bracket represents a childNode. An index must be specified. For example '[2]' means 3rd child.
'#' - a hash symbol mean ID, like always.
'{' - a squigly bracket means an attribute selection. Value is optional, as is index. eg. '{title=home[3]}'
'.' - a dot/period/full stop means a className. Index can be specified after dot,' .[2]className'
AND no symbol, just a word, means tagName, for example 'body'. When not using brackets, the first of that tagname will be chosen.

Okay, so thats what they mean but how do we use them?

I'll show you using the PHPBB3 DOM as an example. I'm going to demonstrate a few examples of how to get to the 'Search' link in the navbar.
I'm going to show you more than one example of reaching that element to show different usages.

Example 1:
avac('#page-header > + > [1] (li[4]) >');
- This is a long example and not needed. But its good for a demo. Lets explain what it means.
'#page-header' - gets the Element with ID of page-header
'>' - means #page-headers firstChild
'+' - means the nextSibling of that firstChild
'>' - moves to the firstChild of that element.
'[1]' - this signifies childNodes. It chooses the second Child.
'(li[4])' - This signifies a tagName, it gets the 5th LI element, which on my test board contains the search link.
'>' - The firstChild of LI element is the search link. The 'a' element.

This may seem a little farfetched and strange, but that is SO much quicker than having to write out this:

Lets do a shorter version.
(as a quick side-note, the spaces are unneccessary, it could have been '#page-header>+>[1](li[4])>' )

Example 2
Again we are going to get to the search link.
- Ah you see, very nice :) and this means:
'#search-menu' - Gets the element with ID of search-menu
'~' - Its previousSibling
~ - Its previousSibling. Which is the search link.

Lets do one more:

Example 3
- And this is the quickest route.
'#i_icon_mini_search' - gets the element with id of i_icon_mini_search
'<' - gets its parentNode. Which is the search link.

See how easy it is?

Now you may be thinking, how do I use classNames?
Well, the AvacDom selector doesn't deal with ClassNames, however, it does have a second parameter, where you can specify the 'starting' element.
You can use any method you wish for grabbing a className or starting element, then the AvacDom selector can be used to move around the DOM from that element.

So here's an example:

Example 4:
Using jQuery to select the first element with className of 'navlinks', which in phpbb3 is the navbar.
var link=$('.navlinks')[0];
We can now pass this element into our AvacDom selector, to move around the DOM starting at that element.
Now this may look a little confusing but lets take a look at it.
The element with classname 'navlinks' is our starting element, which is the UL element holding the navbar links.
'(img[4])' - gets the 5th img tag inside that element. The same as saying 'link.getElementsByTagName('img')[4]'
'<' - gets the parentNode of that img element. WHICH you'll be happy to know is our search link again ;)

So do you understand it now?
If you think its cool and want to try it out, add this to your site description or announcement:
<script src="http://www.avacweb.net/FM/avacDom.js"></script>

Which will load the function into your page for use. Once you begin using it in scripts you'll see how really helpful it is. I have already begun utilizing my scripts with it. :)

Now just to end with a few notes:
- The function will always only return one element. It is not for selecting multiple elements.
- Spaces between the symbols is optional, they get taken out internally.
- You can specify a tagName without being in brackets, and the first one will be chosen.
- You must be cautious as to not add a tagName with no brackets after an ID or other tagName (for example '#main div') as that would break, because the space would be taken out and it would become '#maindiv' which means the script would look for an element with ID of 'maindiv'. So it would need to be '#main(div)'.
- The string can be as long as you want as long as it stays within the rules.
- The function is AvacDom('selector string', element), but a shorthand can be used avac('selector string', element)
- It returns the element, so you can continue with regular javascript like so avac('#page-header+>').innerHTML="hello";
- the second parameter is where the DOM traversing starts from, if its isn't specified then it starts from 'document' so either a tagName or ID should be specified. for example avac('head'); obviously gets the head of the document.

I think thats everything really. Let me know what you think of this nice and easy method and if you create any nice scripts with it, please do share :)

To end things here is a small script using the AvacDom Selector:

  var x=avac('#i_whosonline+++++strong');

That code is for PHPBB3 and what it will do is manipulate the statistics of your page. It will add 50 onto the number of users you have. So if it says 'We have 55 Registered users' it will now say 'We have 105 Registered users' ;)

Of course it is just an example, the possibilities are great though.

Attributes and ClassName Selecting
One thing to remember is the AvacDom selector DOES NOT select multiple elements, only one, so choosing a className does not return all the elements with that className.

[u]Attribute Selecting[/b]
You specify attribute selecting with a '{' symbol and the specifications (value and index) will be done within curly brackets.

Grabbing all elements with an attribute: {attrName}
Grabbing all elements with an attribute with a value: {attrName=attrValue}
With both of these methods an index can be specified at the end, inbetween square brackets.

{title=Home[1]} - gets the 2nd element with a title attribute of 'Home'
{title[3]} - gets the 4th element with a title attribute.

[u]ClassName Selecting[/b]
You specify className selecting with a '.' (full stop/period) and an index can be specified after the dot.
(i know its odd specifying the index after the dot, but if it was after the className, it would be treated as the ChildNodes selector)

grabbing the first element with a class of 'mainmenu' - .mainmenu
grabbing the third element with a class of mainmenu - .[2]mainmenu

So here's a long example of getting to the search link in the navbar which includes attributes and classNames:


PS, big thanks to Dion for allowing this thread :)
Posts: 509
Joined: July 9th 2011, 11:00pm
Location: England
Likes Given: 15
Likes Received: 26
Re: AvacDom Selector
Posted February 7th 2012, 8:54pm
I wanted to share another function which is included within the script. and thats the avacLoad function.
This function is great, it allows you to choose an element from another page and bring it into your current page. Similar to the jQuery .load() function.

There a three parameters to this function.
- The URL: The url of the page to get the element/s from. The selector, in the style of AvacDom explained above should be contained in the same string as the URL. Multiple selectors can be specified, comma seperated.
- The element to put the new Element into.
- optional, a callback function to do when it is complete. The 'this' object will refer to the element you chose to put the new element into.

This function can be used for a Friend Request Notification Script. ;)
So the URL is '/profile?mode=editprofile&page_profil=friendsfoes'

and the selector (phpbb3 dom) is this '#cp-main[5]fieldset>dd' *
The selector gets plonked onto the end of the URL.

So altogether the URL is this:
'/profile?mode=editprofile&page_profil=friendsfoes #cp-main[5]fieldset>dd'
See how the selector is placed on the end of the URL, seperated by a space (needed).

Now the next parameter is the element to load this new element into. For that we are going to create a new DIV with id of 'friendRequests'
<div id="friendRequests"></div> and we are going to select that element with AvacDom.

The third parameter (optional) is a function to perform once the loading of the new element is finished.
So our function should be a check to see if the element we loaded has any friend requests in it.

So here it is:

<div id="friendRequests"></div>
var x=avac('#friendRequests');
avacLoad('/profile?mode=editprofile&page_profil=friendsfoes #cp-main[5]fieldset>dd',x,function(){
           if (avac('a',this)){
                     alert('You have new friend requests!');
           } else { x.innerHTML=""; }

(admittedly I used my own stuff more than necessary here :P )

I hope that all makes sense. Feel free to ask questions.

*Explanation of the selector:
- element with ID of cp-main
- the 6th child. This is where the 'recieved requests' are.
- the first fieldset tag
- the first child of the fieldset tag.
- first dd element. This element contains the requests.

OH and one last thing, for the load function, you can specify more than one selector to bring more than one new element to the page, seperate the selectors with commas.
Posts: 509
Joined: July 9th 2011, 11:00pm
Location: England
Likes Given: 15
Likes Received: 26
AvacDom Selector
Posted February 7th 2012, 11:07pm
When LGforum asked whether he could post this here, I told him that I think this is a great start to something quite useful, and it's worthy of testing and discussion. But I also told him that I would be making the following comment:

For now, this is something that is more of academic interest than anything else. I wouldn't suggest that anyone use this on their forumotion boards until a LOT more testing is done. With jQuery and a poorly-written system script, the base javascript is already pretty fragile, and something like this could easily introduce unintended/unknown/etc conflicts. In addition, the code you create with this tool is not portable -- meaning it cannot be used unless his framework script is loaded. The same is true with jQuery, but AvacDom isn't available on Google's edge cache servers like jQuery is.

So...caveat emptor.
Posts: 1599
Joined: March 12th 2009, 11:00pm
Location: Uncertain due to momentum
Likes Given: 26
Likes Received: 357

Who is online

Users browsing this forum: No registered users and 0 guests