Posts Tagged ‘Swell’

SleepyCod
by SleepyCod

Even more Drag&Drop coolness between your desktop and your browser!

Posted in DD, Javascript, Swell

We are making more & more progress with the native DnD API, and being native means fully taking advantage of Event Bubbling.

In essence this means that if you want to make for example a datatable with a lot of rows without attaching events to them (remember the flyweight pattern?) you’ll only need to set your draggable element at a higher level in the hierarchy to get the DnD behavior applied on all children nodes (marked with the draggable attribute), that’s powerful and of course, reduces a lot the memory footprint of your web application.

A lot of components could benefit of this approach, Treeview, Datatable, Listview and so on.

Another part of the example shows another level of interaction between the browser and desktop, and we are sure this one will get a lot of attention and excitement!

Swell drag&drop in actionAnd the code :)

var proxyElement = html.div(null, html.span({
    'cls' : 'dd-proxy-icon'
}), html.span('Moo'));
 
 
var draggableRows = new Swell.Lib.DD.Draggable('bleh', {
    'delegate' : true,
    'proxy'  : true,
    'proxyOverride'    : proxyElement,  
    'dataCallback' : function(dt) {
        var _currentEl = this.getDragEl().current(), _stdOut = [];
 
        for(var _n = 0, _l = _currentEl.childNodes.length; _n < _l; _n++) {
            if(_currentEl.childNodes[_n].nodeType === 1) {
                var _text = $(_currentEl.childNodes[_n]).text();
                _stdOut.push(Swell.Core.trim(_text));
            }
        }
        this.setData(dt, 'text/plain', _stdOut.join("\t"));
    }
});
 
var dropTarget = new Swell.Lib.DD.Droppable('moo');
 
dropTarget.ondrop = function(e, draggable) {
    if(!!draggable) {
        draggable.getDragEl().appendTo($('moo').current().tBodies[0]);
    }
}
SleepyCod
by SleepyCod

Swell update

Posted in Swell

We’ve been hard at work for almost two months now on the Drag&Drop Manager.

The Swell guys tries to set high standards in terms of code quality and usability, but first and foremost, always think about the future of web appps and how they can ease the process of using these features in your fav browser today.
That’s why we are working on the first native Drag & drop implementation in a Javascript library, just think about the possibilities of making the web interacting with your desktop…

We are also working on WebSockets implementation in Swell using XMLHttp Streaming, this will talk to Comet fans ;)

Butterfish
by Butterfish

Swell Widget example: ImageZoom

Posted in Javascript, Swell

As Beta release is around the corner, we are glad today to provide the first swell widget. This widgets makes intensive use of Core components and shows how much power you have at your fingertips…

This is a widget that ecommerce companies often look for, which enables to zoom on an image and view much more details than on a thumbnail, without having to display the entire image; providing better user experience.

imagezoom

SleepyCod
by SleepyCod

Trigger image loading with Javascript and Swell

Posted in Javascript, Swell

As we are seeing growing interest for Swell, we now want to show how to use it and how cool it is :D , this is according to the milestones on our Trac a necessity and this will as well open up the project to a larger public.

One of the Core component (Lazy loader) plays well with another (Element) in this example.

playground

Enjoy!

FlagBlenny
by FlagBlenny

Let’s start using Swell!

Posted in Swell

If you’ve been following this blog (or are going to read some previous posts), you’ll most likely want to try out Swell for yourself.

I posted a while ago about CDN technology allowing anyone to start using Swell while linking it on a Content Delivery Network, meaning visitors will always get the library from the closest point, and as the first milestone has been reached, I guess it’s time to do a little introduction on the way you will be able to make Swell-enabled applications.

At first, you need to determine which component you need. If you try to implement one of the examples in previous or future posts, you can get this information from the code snippet itself.

In our case, let’s say we want to use setStyle() to change our page’s background color. We want it black, the reason is irrelevant.

This will get our background black:

$(document.body).setStyle({backgroundColor : '#000'});

As setStyle() is part of the Core.Element Swell library, we’ll need it, but also its dependencies. “Core.Element” requires “Core.Hashtable” which requires “Core.CustomEvent” which requires “Core.Core”, who are all requiring the “Swell” namespace itself.
Dependencies are a pain, so we’ll just ignore them and include “Element” (Core.Element‘s alias name). The server-side system will automatically include everything we need in a very convenient way.

http://get.swl.fr/1.0/Element.js

Yep, that’s all. With this URL, I’ll include the Element lib from Swell, with all its dependencies, from the “1.0″ stable branch. If you feel adventurous, you can replace “1.0″ with “trunk” and get bleeding edge code.

<script type="text/javascript" src="http://get.swl.fr/1.0/Element.js"></script>
<script type="text/javascript">
$(document.body).setStyle({backgroundColor : '#000'});
</script>

Looks simple, try it too!

Finally, you might want to include more than one library. This is also possible, and is really easy. Let’s say we want Ajax and Event too, the URL would become: http://get.swl.fr/1.0/Element/Ajax/Event.js. The (obvious) goal is to include everything you need without including tons of different files.

Just a final note: using Swell only to change your page’s background color is called overkill. Try out the other examples on the blog and start building rich web applications!

Butterfish
by Butterfish

Swell’s current progress overview

Posted in Swell

1dotzero

We have recently completed the first milestone labelled under “alpha”, this first version is basically the framework itself, composed of:

  • Core, which contains the whole OOP logic including mixins, inheritance and the basic methods;
  • Browser, something you may need if you have no other choice but to rely on the user agent for building your application;
    • ran at load, this component identifies the browser family (trident, gecko, webkit, presto) and their version, the operating system, and if the site is accessed from a mobile device; every information is provided in multiple manners allowing boolean checks, or switch case dancing.
  • Event, splitted in three categories:
    • Event.js, provides a complete set of methods for Event manipulation in a cross-browser manner
    • CustomEvent.js, its name is self-explanatory: this class enables the use of custom events using the Dom Level 3 implementation when possible;
    • KeyListener.js, easy-to-use key listening abstraction for every class-A browser (including the troublemakers Opera and IE).
  • Ajax, ease the xhr process by providing a simple yet powerful API, a few highlights:
    • headers manipulation;
    • form serialization;
    • asynchronous file upload;
    • automated JSON parsing when the X-JSON header is spotted, using native JSON methods when available.
  • Hashtable, provides advanced key/value manipulation;
  • Asset, provides asynchronous loading for IMG/CSS/JS/JSONP components;
  • Element, the component which ties together numerous of the aforementionned components and ease their usage:
    • automated batch process, you may use one or more elements in a single instance and then call a method which will be executed on each element of the stack, this modus operandi drops drastically the line count;
    • the html builder, enables simple yet powerful element creation with hierarchy, events, custom attributes…

Well, that’s about all, to be honest we are frankly amazed by the work we’ve done so far in three months, although we were working/brainstorming on our spare-time we still managed to deliver the alpha two weeks before the estimated time with two extras (Asset/Hashtable weren’t planned for the alpha).

So, what’s coming?

And we’re already working on the beta, the second milestone estimated time is in six weeks, and includes:

  • Position, everything about position, size, areas… done; we’ll add some extra methods in there given enough time;
  • Drag & Drop, currently in brainstorming state, we plan on using the Firefox 3.5 HTML5 DD native API and simulate on the others (Trident/Webkit APIs are not really convincing);
  • Effects library, obviously necessary, as people tend to like what’s sparkling (and we do!);
  • History manager, a prerequisite for the RC (tabs and therefore, the feedreader application);
  • XML library, also a prerequisite, but we may finally not need it… wait & see!
FlagBlenny
by FlagBlenny

Empowering SwellJS adopters with CDN technology

Posted in Swell

One of our objectives is to make usage of SwellJS easy in order to maximize its adoption. Usually one of the major drawbacks is the installation.
Most software you want to use on your website will require you to download it, extract it, upload it, and keep it up to date.

One of the best ways we found on SwellJS to reduce installation hassle is to remove the installation process. We will instead provide the library via a CDN.

So, what will a “CDN” do, and how does it helps to avoid installation of the SwellJS library?

Read the rest of this entry »

SleepyCod
by SleepyCod

A simple yet versatile hashtable with swell

Posted in Javascript, Swell

Today we wanted to feature the hashtable object used internally by the core components and/or widgets in Swell.

At first don ‘t get me wrong, objects used as hash-tables  is to date the most convenient way of storing static properties associated to a key, I just complain that it’s sometimes (not always) missing features you would find in other languages such as PHP.

Here’s the code :

Swell.Core.Class({
    name        : 'Hashtable',
    namespace   : 'Swell.Core',
    inherits    : [Swell.Core.Enumerable, Swell.Core.CustomEventModel],
    functions   : function() {
 
        var _hash = {};
        var _updateLength = function() {
            var _l = 0, _n;
 
            if(_hash.__count__) {
                this.length = _hash.__count__;
            } else {
                for(_n in _hash) {
                    _l++;
                }
                this.length = _l;
            }
        }
 
        var _initEvents = function() {
            /**
             * @event onChange fires when an item is added/updated in the hashtable
            */
            this.createEvent('change');
            this.subscribe('change', _updateLength);
        }
 
        return {
 
            length : 0,
 
            /**
             * Constructor, initialize enumerable
             *
             * @function construct
             * @constructor
            */
            construct : function() {
                this.setEnumerable(_hash);
                _initEvents.call(this);
            },
 
            /**
             * Resets the hashtable
             *
             * @function dispose
            */
            empty : function() {
                _hash = {};
            },
 
            /**
             * Add/Update an entry in the hashtable
             *
             * @function set
             * @param {String} key Key name
             * @return {Swell.Core.Hashtable}
            */
            set : function(key, value) {
                if(arguments.length === 1) {
                    _hash[Swell.uniqueId()] = key;
                } else {
                    _hash[key] = value;
                }
                this.fireEvent('change', this);
                return this;
            },
 
            /**
             * Add an entry in the hashtable if the key does not exist
             *
             * @function set
             * @param {String} key Key name
             * @return {Swell.Core.Hashtable}
            */
            add : function(key, value) {
                if(!this.exists(key)) {
                    this.set(key, value);
                    return this;
                }
                return false;
            },
 
            /**
             * Update an entry in the hashtable if the key exists
             *
             * @function set
             * @param {String} key Key name
             * @return {Swell.Core.Hashtable}
            */
            update : function(key, value) {
                if(this.exists(key)) {
                    this.set(key, value);
                    return this;
                }
                return false;
            },
 
            /**
             * Get the value of the corresponding key in the hashtable
             *
             * @function get
             * @param {String} key Key name
             * @return {Mixed/Boolean} value
            */
            get : function(key) {
                if(_hash.hasOwnProperty(key)) {
                    return _hash[key];
                }
                return false;
            },
 
            /**
             * Exchanges all keys with their associated values in the hashtable
             *
             * @function flip
             * @return {Swell.Core.Hashtable}
            */
            flip : function() {
                var _k, _tmp = {};
 
                for( _k in _hash ) {
                    _tmp[_hash[_k]] = _k;
                }
                _hash = _tmp;
                return this;
            },
 
            /**
             * Returns the first item of the hashtable
             *
             * @function first
             * @param {Boolean} [extended] Returns an array with the first item as key and second one as val (optional)
             * @return {Mixed}
            */
            first : function(extended) {
                for(var _p in _hash) {
                    if(!Swell.Core.isUndefined(extended)) {
                        return [_p, _hash[_p]];
                    }
                    return _hash[_p];
                }
                return false;
            },
 
            /**
             * Returns the last item of the hashtable
             *
             * @function last
             * @param {Boolean} [extended] Returns an array with the last item as key and second one as val (optional)
             * @return {Mixed}
            */
            last : function(extended) {
                var _lastitem = false;
                for(var _p in _hash) {
                    _lastitem = _hash[_p];
                }
                if(!Swell.Core.isUndefined(extended)) {
                    return [_p, _lastitem];
                }
                return _lastitem;
            },
 
            /**
             * Unsets an item from the hashtable
             *
             * @function remove
             * @return {Swell.Core.Hashtable}
            */
            remove : function(key) {
                if(_hash.hasOwnProperty(key)) {
                    delete _hash[key];
                    this.fireEvent('change', this);
                }
                return this;
            },
 
            /**
             * Applies the callback to the elements of the hashtable
             *
             * @function map
             * @return {Swell.Core.Hashtable}
            */
            map : function(fn) {
                var _p, _tmp = {};
                if(Swell.Core.isFunction(fn)) {
                    for(_p in _hash) {
                        _tmp[_p] = fn.call(null, _hash[_p]);
                    }
                }
                return _tmp;
            },
 
            /**
             * Test if a property exists in the hash table
             *
             * @function exists
             * @return {Boolean}
            */
            exists : function(key) {
                return _hash.hasOwnProperty(key);
            },
 
            /**
             * Applies an user function on every member of the hashtable
             *
             * @function walk
             * @return {Swell.Core.Hashtable}
            */
            walk : function(fn) {
                var _p;
                if(Swell.Core.isFunction(fn)) {
                    for(_p in _hash) {
                        _hash[_p] = fn.call(null, _hash[_p]);
                    }
                }
                return this;
            },
 
            /**
             * Returns an array of keys
             *
             * @function keys
             * @return {Mixed[]} keys
            */
            keys : function() {
                var _k, _tmp = [];
                for(_k in _hash) {
                    _tmp.push(_k);
                }
                return _tmp;
            },
 
            /**
             * Pop the element off the end of array
             *
             * @function pop
             * @return {Mixed} value of the popped item
            */
            pop : function() {
                var _item = this.last(true);
                delete _item[0];
 
                return _item[1];
            },
 
            /**
             * Returns an array of values
             *
             * @function values
             * @return {Mixed[]} values
            */
            values : function() {
                var _k, _tmp = [];
                for(_k in _hash) {
                    _tmp.push(_hash[_k]);
                }
                return _tmp;
            },
 
            /**
             * Returns the wrapped native object
             *
             * @function toObject
             * @return {Object}
            */
            toObject : function() {
                return _hash;
            },
 
            /**
             * Returns a string representation of the wrapped native object
             *
             * @function toSource
             * @return {String}
            */
            toSource : function() {
                if(_hash.toSource) {
                    return _hash.toSource();
                } else {
                    var _stack = [];
                    for(var _n in _hash) {
                        _stack.push('"' + _n + '" : "' + _hash[_n] + '"');
                    }
                    return '({' + _stack.join(',') + '})';
                }
            }
        }
    }()
});

But how to use it ?

A Swell class can be instantiated just like you would do with a classic object.

    var ht = new Swell.Core.Hashtable();
 
    // Put some stuff into the hashtable
    ht.set('foo', 'bar');
    ht.set('baz','bleh');
 
    //Then walk every member of the hashtable to turn the value into uppercase
    h.walk(function(member) {
        return member.toUpperCase();
    });
 
    // Output the hash, this will give us an object like : {foo : "BAR", baz : "BLEH"}
    h.toObject();
Butterfish
by Butterfish

SVN post-commit hook, API doc autogeneration

Posted in Swell

Generating manually Swell’s API doc actually’s being a pain, we finally chose to generate it automatically through subversion’s repositories hooks.
These hooks once enabled, allows you to listen specific SVN-based events (pre/start/post commit/lock…) and therefore execute your home-made script.

In our case, we use JSDoc to generate the API doc and well, it took about 6mins with one core (2ghz) fully-loaded to parse/generate the documentation for only 4 files…
Let’s hope that we’ll not commit too often.

svn up /path/to/your/repository/api/src
java -jar /path/to/your/repository/api/jsdoc/jsrun.jar /path/to/your/repository/api/jsdoc/app/run.js -r=1 /path/to/your/repository/api/src -t=/path/to/your/repository/api/jsdoc/templates/jsdoc
SleepyCod
by SleepyCod

Swell makes javascript hot key event listeners a breeze…

Posted in Javascript, Swell

These days the trend is to have a seamless desktop experience in your browser, that means pushing the boundaries of the web applications by trying to mimic the natural behavior of desktop hosted solutions. One of the must-have is undoubtedly a robust and easy-to-use event toolkit. That was one of the heaviest task and probably, to date, one of the features we are most proud of.

We’ll try to make a bunch of articles on how to use the Event toolkit. Today we’ll talk about hot-keys, a hot-key is a key combination that you can use to trigger an action in your web-application, for example you are building a WYSIWYG editor and want to capture combination like Ctrl + B to turn the text in bold.

Here’s how you would create this keyboard event listener with Swell.

Swell.Core.Event.addKeyListener(document, 'ctrl+b', function(event, keys) {
 
    if(event.modifiers.ctrl) {
        if(keys.contains('b')) {
            Swell.Lib.Selection.getCurrent().wrap('<strong>$1</strong>');
        }
    }
 
}, null, null, true);