This project is archived and is in readonly mode.

#627 ✓invalid
csuwldcat

Add context option to $ and $$

Reported by csuwldcat | March 21st, 2009 @ 04:16 PM | in 2.0 (closed)

I was trying to work with mootools inside and across XUL elements and tabs for a FF addon I was doing and basically was racing my buddy who was using jQuery. I got stuck at the point I wanted to get into the DOM of a XUL tab in the borwser. jQuery has a 'context' option that lets you set the scope (or starting point) for the $ retrieval and extend function. So i looked at the jQ code and was able to reproduce the exact same effect in Mootools with a single argument addition and a line in the function. The $$ was harder and my code is likely to get changed for that, but have a look, I would love to see this in the lib:


//$ Fn with context added
$C: function(el, context, nocash){
   context = (context) ? context : this.document;
   if (el && el.$family && el.uid) return el;
   var type = $type(el);
   return ($[type]) ? $[type](el, nocash, context) : null;
},

//$$ Fn with context added
$$C: function(selector, context, xul){ // EXAMPLE:
	context = (xul) ? $C(context.body, context) : context;
	var args = selector.flatten();
	if (args.length == 1 && typeof args[0] == 'string') return context.getElements(args[0].toString());
	var elements = [];
	for (var i = 0, l = args.length; i < l; i++){
		var item = args[i];
		switch ($type(item)){
			case 'element': elements.push(item); break;
			case 'string': elements.extend(context.getElements(item, true));
		}
	}
	return new Elements(elements);
}

Some sample uses here, the first one looks even more different because it also employs Jan and Arron's event delegation to set the event:


//Example of $C usage with a context set
$C('header', t.tabDoc).addEvents({
  'click(li)': function(){
    if(this.hasClass('modded_by_xul')){
	this.morph({'height':50,'margin-top':0}).removeClass('modded_by_xul');
    }
    else{this.morph({'height':500,'margin-top':100}).addClass('modded_by_xul');}
    }
});

// Example of teh $$C usage with a context set				
$$C(['#footer p'], t.tabDoc, true).addEvent('click', function(){
    if(this.hasClass('modded_by_xul')){
	this.morph({'background-color':'#fff','margin-top':0}).removeClass('modded_by_xul');
    }
    else{this.morph({'background-color':'#f00','margin-top':100}).addClass('modded_by_xul');
    }
});

Comments and changes to this ticket

  • Christoph Pojer

    Christoph Pojer March 21st, 2009 @ 07:06 PM

    • Tag changed from 1.3, contexxt to 1.3, contexxt
    • State changed from “new” to “invalid”

    You can also use document.getElement or document.getElements on any other element. For example $('myElement').getElements(selector). There is no need for a context option in $ or $$. However, with the next major release of MooTools you can safely overwrite $ or $$ for any purpose you want.

  • Thomas Aylott

    Thomas Aylott March 21st, 2009 @ 07:48 PM

    A race with a jQuery pal sounds like big fun times. I'd love to hear the full story. I hope you won ;)

  • csuwldcat

    csuwldcat March 21st, 2009 @ 08:12 PM

    Well I must retort, have either of you tried to do a FF Addon using Mootools to modify web pages from XUL? Hate to break it to you but $(myBrowserTab).getElement(selector) does not work fellas. It will bork because the CONTEXT of that $ grab is going to be the XUL document inside the browser's chrome not tab's document that you are hoping for. You need a way to get the context of the document you are targeting. Just look at the $ function and think about it before you dismiss this:

    $C: function(el, context, nocash){ context = (context) ? context : this.document; //ADDED THIS LINE if (el && el.$family && el.uid) return el; var type = $type(el); return ($[type]) ? $[type](el, nocash, context) : null; //this.document used to be where context is on this line }

    If you do it your way the $ function will look in the overlay xul doc for the tab because this.document (as the original $ function has it) is the overlay xul doc. The problem is that the tab that you are trying to reference is not in that document, so whadaya know it returns no element to then go a getElement() call. Do you understand what I am saying?

    If all else fails, you could create an empty addon, include mootools, and try and access an element from a newly created tab, then watch it bork.

    The $C mod that is provided will also work on other context issues such as iframes. If there is a same domain issue you would no longer need to create an iframe with any special properties, you can just set its document as the context of your C$ function and bam instant abilities, you dig?

    Please take a second, if you can do a FF Addon and do it in a more simple way I am all ears but I seriously doubt it...

    In closing the guy who did the xootools port also had these problems and thought this was a great augmentation.

  • csuwldcat

    csuwldcat March 21st, 2009 @ 08:19 PM

    • Tag changed from 1.3, contexxt to 1.3, context

    Seriously guys, really seriously, give this a second though, an am almost positive that you haven't encountered this before...

  • csuwldcat

    csuwldcat March 21st, 2009 @ 08:21 PM

    • Assigned user changed from “Jan Kassens” to “Tom Occhino”

    Tom, can someone verify this against what the first guys is suggesting to see that $().getElements() will not work in the way suggested...

  • ibolmo

    ibolmo March 21st, 2009 @ 08:39 PM

    Hey csuwldcat,

    I feel the pain, I've attempted to just ignore using the DOM when I did a FFx extension. Luckily, I was extending Firebug, so they had helper functions for that kind of thing.

    For this to work, you'd have to replicate what is done for new iFrames, but with new Contexts that have not been extended with MooTools (or is the page already loaded with MooTools?).

    If not extended with MooTools, then you need to come up with perhaps a var Context = new Native(....) that extends it (which basically means new Window(...) and new Document(...)).

    If extended, then you can just use context.window.$ and context.window.$$.

  • csuwldcat

    csuwldcat March 22nd, 2009 @ 02:55 AM

    Well for XUL tabs (borwser tabs) you can have unfettered access to them and do what you want with script in them without having the library included as long as you create a linked var for the tab's document that is wrapped in a XPCNativeWrapper. That wrapper basically allows your scripting against that tab's DOM to not interfere with the existing scripts and libs on the page in the tab. The catch is that to reach in to the tab's XPCNativeWrapper and get the element selected from where you are (the XUL overlay doc like a sidebar or bottom toolbar) you need to set the context of the $ function, if you leave it as this.document as the functions is natively set to in Mootools, that is your overlay XUL doc not the wrapped tab's doc, so undefined errors abound.

    I have been speaking with Rey Bango and a peer and I are writing a Moz tutorial/article on using Mootools and jQuery to script in XUL. I am handling the Mootools version. The solution that I put in the first post of this ticket works perfectly and if there is no better ways presented I will write the article to that affect. I was basically giving you mootoolers who are better coders likely than I the opportunity to vette this a bit before I write the article. Please let me know what you all think on this.

  • Christoph Pojer

    Christoph Pojer March 22nd, 2009 @ 03:02 AM

    I think XUL is a too small target group to directly implement this into MooTools even if there is no other way to do it yet. As I stated above the next major release of mootools will make it possible for you to directly replace $ and $$ with whatever code you like because internally it won't rely on those functions any more so this will be a perfect solution for developing with MooTools in XUL.

    I'm very interested in using MooTools in XUL and I appreciate if I could assist with and proof-read that tutorial before it goes live. Maybe you can also give me an example on how exactly the XUL stuff works so I can probably help you figure out the best solution (maybe a little class as ibolmo stated). Feel free to contact me (contact info: http://og5.net/christoph/page/About )

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

Shared Ticket Bins

Tags

Pages