Olivier Scherrer

Olivier is a Front End Developer at Lab49, London, a strategy, design and technology consulting firm that creates advanced solutions for the world’s leading investment banks, asset managers and exchanges. He has a strong experience in developing real-time HTML5 applications.
He's the author of Emily and Olives, two JavaScript frameworks that allow to easily create powerful web applications on top of node.js, with high UI performance and low memory footprint.View Olivier Scherrer on LinkedIn
  • ask me anything
  • GitHub podefr
  • Emily
  • Olives
  • rss
  • archive
  • Missing feature of the day: grouping DOM nodes

    Let’s say that you’re developing a JS Framework that has the concept of widgets. A widget is a JavaScript Object with a representation in the DOM. As you have one reference on the JS Object somewhere in your application, you’ll want to have one reference to its DOM structure, and unfortunately the only way is to wrap the template into one parent DOM element.

    For example, one of your widgets has the following template:

    <p>
        Text 
    </p>
    <ul>
        List items
    </ul>
    

    When converting this to dom nodes (how you do it doesn’t matter here) you may have a list of dom elements, one p tag, and one ul tag, or have a parent dom element wrapping them. Let’s call these two items a group. But when this group gets appended to the dom, you lose the notion of group, as they become two nodes among the others.

    To illustrate this, let’s imagine that after being attached (how you do it doesn’t matter here) we have the following structure:

    <div>
        <p>
            Text
        </p>
        <ul>
            List items
        </ul>
        <p>
            Another widget here
         </p>
    </div>
    

    As the notion of group is lost, there is no way now to distinguish them from the dom nodes of another widget. We can’t take them out and append them somewhere else.

    This problem is solved by wrapping them into a parent dom element, which creates the notion of groups. Usually a div is chosen. But the drawback here is that we have added an unnecessary dom element that could have been avoided. And unnecessary dom elements are one major cause of performance loss.

    One way of solving this issue would have been with using a document fragment. A documentFragment looks like a dom element though it can’t have a representation in the actual dom. Unfortunately, once appended to the dom, it loses its children.

    // this is our dom element that doesn't exist in the DOM
    var domFrag = document.createDocumentFragment();
    
    // We add it actual dom elements, they're part of our widget
    domFrag.appendChild(domElement1);
    domFrag.appendChild(domElement2);
    
    // It has two children
    domFrag.childNodes.length == 2; // true
    
    // We append our non-dom element somewhere into the DOM
    destinationDom.appendChild(domFrag);
    
    // Our documentFragment still exists, but has no more children
    // Of course, it doesn't exist in the DOM, though its child now do.
    domFrag.childNodes.length == 0; // true
    

    Another way of doing it would have been to have a grouping method in the DOM.

    // A real dom element without tag
    var domGroup = document.createDocumentGroup();
    
    // Let's call its innerHTML, it's fast and cross browser.
    domGroup.innerHTML = "<p>Text</p><ul>list items</ul>";
    
    // That's two items
    domGroup.childNodes.length == 2; // true
    
    // They get appended to destinationDom, no extra HTML tag added.
    destinationDom.appendChild(domGroup);
    
    // They're still part of the domGroup.
    domGroup.childNodes.length == 2; // true
    
    // So I can move them around
    otherDestinationDom.appendChild(domGroup)
    

    The domGroup would not have a representation in the dom, so its children could be direct children of the destinationDom, but can still be moved around by appending the group somewhere else. If ever a childNode gets appended somewhere else, it would simply leave the group.

    You may also have noticed that a documentFragment doesn’t have an innerHTML property, which is a shame as it’s a cool way for creating dom nodes out of strings, and it’s fast because it’s using the browser’s rendering engine.

    Fortunately, the domGroup would have this feature, which would become the number one tool for defining a widget’s view:

    var widget = {
        this.element: document.createDocumentGroup(),
    
        this.render: function (template) {
            if (template instanceof HTMLElement) {
                this.element.appendChild(template);
            } else if (typeof template == "string") {
                this.element.innerHTML = template;
            } else {
                throw new Error('template must be either a string a set of dom elements');
            }
        },
    
       this.place: function (destinationDom) {
            destinationDom.appendChild(this.element);
       }
    };
    

    How cool would that be?

    • 4 months ago
    • #html
    • #framework
    • #widgets
    • #missing feature
    • #feature request
  • Olives 1.1.5 supports SVG views

    Since version 1.1.5 Olives is officially supporting SVG. SVG and HTML are very similar and can be manipulated almost the same way. It’s all about creating xml tags, setting there attributes and styling them. The great news is that Olives was born to support SVG and only a few modifications were required to support them.

    In Olives, views are almost fully passive. They have no logic attached to them, let aside the data- attributes that describes the plugin calls. Considering that HTMLElement and SVGElement are almost similar, we should be able to treat SVG views just like we treat the HTML ones.

    As an example, I’ve create an SVG+Olives charting demo.

    Let’s see how the grid of the demo is built:

    We first create an SVG group that will group the horizontal lines:

    <g class="grid">
        <g data-gridy="foreach">
            <line x1="0" y1 x2="600" y2 data-gridy="bind: y1; bind: y2" />
        </g>
    </g>
    

    If you’re familiar with Olives, you’ll recognize the data- attributes that specify which plugin to use to manipulate the SVG. data-gridy will call the foreach method of the ‘gridy’ plugin on the Element, when bind will be called on the line method.

    The plugin is configured in the Grid UI and it binds the SVG with the gridY data store.

    grid.plugins.add("gridy", new ModelPlugin(gridY));
    

    The combination of the SVG and Olives will generate as many lines as specified in gridY, with y1 and y2 being replaced by the store’s values, as declared by data-gridy=”bind: y1; bind: y2”.

    Once the grid is generated, we can render the chart on top of it.

    The chart is a polyline:

    <g class="chart">
        <polyline points="" data-line="bind: drawLine, line" />
    </g>
    

    To add points to a polyline, we have to add them to the points=”” attribute. These points have a special formatting and can’t be simply extracted from an array of points. So we need to create a drawLine function that will handle this formatting. drawLine will then be added to the Model-plugin.

    points is a simple array with many points: [ 43, 65, 87, 83, 79, 101, 102, 95 ]

    chart.plugins.add("line", new ModelPlugin(model, {
        drawLine: function (points) {   
            var newPoints = [];
    
            // We populate the new array
            points.forEach(function (val, idx) {
    
                // 20px separate each point
                // the Y axis is "inverted" so subtract the value to 200
                newPoints.push([idx*20, 200-val]);
    
            });
    
            // It also has "terminating points"
            newPoints.unshift([0, 200]);
            newPoints.push([newPoints[newPoints.length-1][0], 200]);
    
            // Finally, we join all the points (x1,y1 x2,y2 x3,y3…)
            // And set the points attribute
            this.setAttribute("points", newPoints.join(" "));
        }
    }));
    

    Any kind of chart can be rendered using this technique, bar charts, pie charts, whatever. And we can even go further by connecting our models to a node.js server to have real-time charts!

    Source: podefr.github.com
    • 11 months ago
    • 1 notes
    • #SVG
    • #olives
    • #JS
    • #MVC
    • #Framework
  • Using CouchDB in a real-time web application

    CouchDB offers three distinct APIs for querying documents. It also comes up with an API to track changes happening in a database.

    I’ve written 3 articles to explain how to use these APIs in real-time web applications, using the _changes API that is available through a keep-alive socket. They describe the flow of requests needed to fetch the documents, keep them up-to-date with the database, and when available, update the database when changes happened on the client side:

    • Document API in a real-time application
    • Bulk Document API in a real-time application
    • View API in real-time a application

    Also note that these articles reflect how Emily CouchDBStore works, in combination with Transport

    • 1 year ago
    • #CouchDB
    • #real-time
    • #web application
    • #javascript
    • #framework
  • Emily + Olives first official release

    I’m really happy to announce that Emily and Olives have been officially released today.

    It’s hard to find the words to express what I’m feeling now. These two frameworks have consumed almost all my spare time since last September, and they’re the achievement of 2 years of trial and error, research and development, joy and fear. To be honest, had I known how hard it is to come up with what I’ve got today, I think I’d have given up on day 1.

    My first Pirates JS Framework attempt has failed, it was in 2010. Emily was born in July 2011 from the ashes of Pirates. Emily is runtime agnostic, it provides tools for manipulating data and common design patterns such as states and observable. Olives is more about creating UIs, connecting views to models and fetching data from the server.

    Running both frameworks allows to create incredible realtime applications on node.js with no effort. The API was designed to solve the developers’ problems, not mine.

    But allow me to talk about their features in forthcoming articles.

    For now, numbers:

    • ~1300 hours work since last september
    • 15 AMD/commonJS modules
    • 100% code coverage, 100% TDD
    • 408 tests and many, many more assertions
    • Emily: 1815 lines of code, 3499 lines of tests
    • Olives: 1301 lines of code, 2258 lines of tests
    • Emily is only 12,858b and Olives 8,264b
    • That’s 2.3 lines of working code per hour
    • And 4.4 lines of tests per hour
    • 0 regression. Never saw one.
    • And as of today, 3 happy developers using them and making feedback for improvements.

    There’s a working demo of Olives based on Addy Osmani’s todo app. There’s a suggestion application too that’s being developed, showing the full potential of Olives.

    And more to come!

    Also, I wanted to thank Olivier Wietrich @owietrich for his tremendous help. He’s brought lots of good ideas such as Olives plugins, he’s tested the frameworks, contributed to the code and was the first ever to actually develop on them. Many many thanks!

    Source: github.com
    • 1 year ago
    • #Emily
    • #Olives
    • #JavaScript
    • #Framework
    • #realtime
    • #CouchDB
    • #socket.io
© 2012–2013 Olivier Scherrer