Styles

Tuesday, July 14, 2015

Resetting CSS3 Transitions and Animations

Everyone gets excited whenever they get the opportunity to work with CSS3 and particularly the new transition and animation features. They work smoothly compared to Javascript animations, and the reason they do is because these visual interactions are managed by the browser itself and how it decides to interpret the movement of elements that it has rendered from markup. This is significantly more efficient than how Javascript tries manipulating DOM elements functionally by altering the rendered elements frame by frame.

With every great thing however, there are always shortfalls. Lets look specifically at animations and their keyframes.

.notify {
    animation: notify 5s;
}
@keyframes notify {
    from { height: 0; }
    20% { height: 60px; }
    80% { height: 60px; }
    to { height: 0; }
}

This is a very simple implementation of a keyframe animation to slide an element down for notifications. All that is needed is a div element that initially doesn't have a "notify" class.

<div id="tip" class="tip">message</div>

With a little Javascript we can add the "notify" class to the element so that the keyframe can be triggered. We can do this with JQuery.

$(".tip").addClass("notify");

There is one problem with this however. Once this keyframe has been executed, it can no longer be executed unless you refresh the page.

One way which should typically solve this problem would be to remove the class then re-add it again.

$(".tip").removeClass("notify");
$(".tip").addClass("notify");

That would be logical, unfortunately it doesn't work!
Amazingly, what is required is to set any property of the element, even if it is to the same value.

$(".tip").removeClass("notify");

$(".tip").position().top = $(".tip").position().top;

$(".tip").addClass("notify");


The reason for this is it helps trigger a "reflow" of the browser so as to listen for the next time the "notify" class has been added to the element, and the browser will do its magic all over again!


Friday, November 14, 2014

Regex for Unicode Variations

Ever had a spammer try to get around spam rules for a subject line like "Account Verification" which would otherwise be picked up by your regular spam? They would usually try something sneaky like "Acc0unt Verification" by replace o's with zeros (0) or have colons in between so your pattern matching wont pick up subject lines like "A:ccount Verification".

Worse they would even use subtle variations in vowels to substitute an e with a unicode variation like é to make pattern matching extremely difficult "Accøünt Vérificatiøn".

Regular expression can definitely make your life easier, but unicode would make things more interesting. First thing you will need is the basic pattern matching to catch out the characters in between that usually tries to through out whole word pattern matches:

^(?i).*(a.?c.?c.?o.?u.?n.?t.?[\s]*v.?e.?r.?i.?f.?i.?c.?a.?t.?i.?o.?n)+.*$

You will probably want to add some basic variations to the vowels which would catch any spammer trying to replace o's with zeros (0) or i's with ones (1) or a's with at symbols (@).
^(?i).*([a@].?c.?c.?[o0].?u.?n.?t.?[\s]*v.?[e3].?r.?[il1].?f.?[il1].?c.?[a@].?t.?[il1].?[o0].?n)+.*$

And if you really want to be pedantic, I've found a good table listing all the unicode characters and have provided them below so you can replace the vowel matching with the following unicode variations.

[a@À-Åà-åĀ-ąǍǎǞ-ǡǺǻȀ-ȃȦȧȺɑΆΑάαаӐ-ӓᗅᶏᶐḀḁẚẠ-ặἈ-ἏÅᾈ-ᾏᾸ-ᾼ₳]
[e3È-Ëè-ëĒ-ěȄ-ȇȨȩɆɇΈΕеѐёҼ-ҿӖӗᴇḔ-ḝẸ-ệⴹἘ-ἝῈΈ]
[il1Ì-Ïì-ïĨ-ıĺļľŀłƖƗǏǐȈ-ȋɨ-ɭΊΙіїӀḬ-ḯḷ-ḽỈ-ịἰ-Ἷὶίῐ-Ί]
[o0Ò-Øð-øŌ-őǑǒǪ-ǭǾǿȌ-ȏȪ-ȱɸɵΌΟθоѲѳӦ-ӫ০੦௦ᴏṌ-ṓỌ-ợὀ-Ὅὸό]
[uµÙ-Üù-üŨ-ųǓ-ǜȔ-ȗɄᴜṲ-ṻỤ-ựὐ-ὗὺύῠ-ΰ]

There are a few common consonants that also get used by spammers to avert the pattern matching:
[nŃ-ŋƝƞǸǹɳΝᶇṄ-ṋἠ-ἧ]
[tŢ-ŧƫ-ƮȚțȾᴛṪ-ṱ]
[y¥ÝýÿŶ-ŸƳƴȲȳɎɏΫγϒ-ϔўҮ-ұӮ-ӳẎẏẙỲ-ỹỾỿὙ-ὟⲨⲩ]
The end result of the regex pattern may seem long and complicated, but can definitely prevent many spam emails from slipping through the cracks

Tuesday, May 27, 2014

Javascript's Decorator Pattern using Require.js

While working at Mi9 I stumbled across a very interesting way to use the Javascript Decorator Pattern in order to separate the concerns of the html and the way it populates information using the require.js framework.

For those of you who are unfamiliar to require.js, I have provided an extremely simple example below. It is basically a simple lightweight framework that helps you load javascript files on demand. Each of these files provides a module that can introduce features to your javascript functionality.

A simple example of require.js is can be shown below when you specify a module in the require construct, which uses dependency injection to pass in the helper service and its members:

    require(['jquery', './helper'], function ($, helper) {
        var callSingleStoryService = function (url) {
            $.get(url, function (data) {
                helper.evaluateElapsedTime(data);
            });
        };
        return {
            decorate: function (data) {
                callSingleStoryService(data);
            }
        };
    });

This will locate the helper file located relatively in ./helper, and the actual helper module provides the functionality for evaluateElapsedTime(data); as shown below:

    define(['jquery'], function ($) {
        return {
            evaluateElapsedTime: function (element) {
                //do stuff...
            }
        };
    });

This is just a simple example of how to use require.js.

Now, to apply this to an html element in order to provide a decorator to its inner elements, you can provide the following attributes as follows in your view:

    <div class="module" data-module="./feedDecorator">
        <div class="block">
            <div class="grid">
                Some content...
            </div>
        </div>
    </div>


The above html tells the application to associate the feedDecorator.js file which has a decorate function in it to apply functionality to this specific element with a "module" class name. Your feedDecorator.js file will look like the following:

(function () {
    define(['jquery', './helper'], function ($, helper) {
        return {
            decorate: function ($target, data) {
                helper.evaluateElapsedTime($target, data);
            }
        };
    });
});

How does it all work? Your main.js (the only js file that you need to initially load) should implement the following functionality that will go through each element with the class name "module" and run its respective "decorate" function, which is simply associated by the module specified in the "data-module" html attribute.

(function() {
  define(['require', 'jquery'], function (require, $) {
    var decorator = function ($target) {
      var moduleName = $target.dataset['module'];
      require([moduleName], function (module) {
        var data;
        if ($.isFunction(module.decorate)) {
          data = $target.data();
          delete data.module;
          return module.decorate($target, data);
        }
      });
    };
    function () {
        $(".module").each(function () {
          return decorator($(this));
        });
    };
  });
});

And its as simple as that! Now for any specific html element, you can associate specific javascript functionality to apply to it without having to load large amounts of javascript files unnecessarily.