Tag Archives: jPaq

YourJS – 1st Pass

I finally have the 1st pass of YourJS available to the public!!!

What is YourJS?

YourJS is a fully customizable JavaScript library which gives the developer more control than ever before.

Who controls the codebase?

Everyone does! All you have to do is sign up and you can start writing code that can be included in YourJS.

How do I design and download my own library?

As of right now there is a section called Snippets which is a repo of code that can be included in your custom JS library. You can browse the snippets, add the ones you like to the build and then go to the build page to build the library from the selected snippets. Finally, you will have the opportunity to name your library (this will be the variable name added to the global namespace for your utility library).

What development plans are there?

  • Port most functionality available in jPaq over to YourJS.
  • Add an examples section similar to the one that exists on jPaq.org.
  • Include a buildable version of the library which includes documentation.
  • A link share for all other JS sites.

I have a lot of ideas for YourJS so the sky is the limit! Let me know if you have any suggestions and perhaps I will be able to include them in the next iteration of changes. :cool:

JavaScript Snippet – getClass()

If you have been using JavaScript for a little bit you probably already know how to determine a variable’s class constructor, but just in case you are overthinking it here is a hint: variable.constructor. :-) Of course, many times I like to make functions that will spit my results for me so here is one that will take any variable and spit out its class constructor:

OK, yeah I know that JavaScript doesn’t really have classes but prototypes but most people think of them as classes so that is why this is called getClass(). The one thing you will notice is that if null or undefined is passed into the function, the same value will be passed back since those are the only two things in JavaScript that don’t have corresponding prototypes. Have fun! :cool:

JavaScript Snippet – String.prototype.after()

WARNING:
Extending native prototypes is frowned upon by many JS engineers but can be helpful as long as the extensions are properly documented in the codebase.
SCRIPTER’S DISCRETION IS ADVISED. :lol:

Yesterday I added a post about String.prototype.before(...). As is explained within the post, this function can be used to easily extract a substring before a given target. Of course, if you can get what comes before a target you should be able to get what comes after a target too, right? Here is a function that makes that possible:

As indicated in the comments, this function can take a target (string or regular expression) to key off of to extract the desired substring. It also takes an optional second argument used for indicating the occurrence of the target to key off of. For instance, if you wanted to get the string that comes after the second comma in "Uno, dos, tres, cuatro, y cinco" you could use the following code:

var str = "Uno, dos, tres, cuatro, y cinco";
var afterFirstTwo = str.after(',', 2);

Here are some other examples that I used to test this function:

As usual, feel free to use this function in your own projects. Have fun! :cool:

JavaScript Snippet – String.prototype.before()

WARNING:
Extending native prototypes is frowned upon by many JS engineers but can be helpful as long as the extensions are properly documented in the codebase.
SCRIPTER’S DISCRETION IS ADVISED. :lol:

Even though its NOT encouraged to extend native prototypes, at times you may find that doing so is pretty useful. One extension that you may find useful is String.prototype.before(...) which can be used to return the substring before a specified target. Here is the definition:

First I think its worth mentioning that depending on your preference you could choose to rename this function as String.prototype.leftOf(...) to clearly identify what it does. This function takes at least a target to find in the string which is either a string or a regexp. You may also optionally pass in a second argument which indicates the occurrence of the target to key off of. For example, if you wanted to extract the substring before the second comma in "one, two, three, and four" you could do something like the following:

var str = "one, two, three, and four";
var firstTwo = str.before(',', 2);

Of course, that is just one simple example of what you can do with this prototype extension. Check out some tests that exemplify how to use this helpful function:

Most likely if you like this function you will also want to check out the String.prototype.after(...) post. Enjoy using this helpful utility function. :cool:

JavaScript Snippet – Simple CSV Parser

As I mentioned in yesterday’s post, I was recently working on a quick way to parse CSVs into an array of arrays and alternatively into an array of dictionaries keyed on the values in the first row. I ended up landing on the following definition:

As you can see the function is annotated for anyone that may be interested in using. Let’s see example of how it could be used. Here is an example string that can be parsed:

ID,First Name,Last Name,Address,Last Purchase Date,Purchase Amount,Comment,Return Customer
1,Don,Knots,"123 Main St.,
Duggietown, ET 12342",10/23/2013,23.43,"""Doesn't like cheese"" according to his mom.",Y
2,Cher,Vega,"92 Victor Ln.
Rutrow, DA 39252",01/12/2013,588.1,,N
3,Tina,Ray,"1111 Yomdip Circle
Bribloop, EV 92341",02/03/2013,234.2,,Y
4,Charlie,Bucket,"745 Caca Pl.
Hastiville, JS 92293",05/06/2013,345.4,,N

Below is an example of processing the above CSV first as an array of arrays, then as an array of dictionaries (objects), and lastly as an array of dictionaries with typed values:

As you can see from the jPaq Proof above, this parser works well with the majority of the CSVs that you would need to process. Still, in the case that you need a fully-fledged CSV parser, Papa Parse seems to be a pretty good solution. Have fun! 8-)

Embedding Stylesheets in JavaScript

Now Available in YourJS

One of the cool things about JS is that you can do almost anything with it! The only thing is that you need to have the tools to get that “anything” job done. Recently, I had the desire to embed HTML, CSS, and JS all in one file that would be loaded when a specific browser event fired. The common solution is to use a library such as jQuery to load an HTML snippet but I wanted a different solution. I was thinking it would be great to be able to do something like this:

css({
    'div.special-1, span.special-2': {
        fontFamily: 'Trebuchet MS',
        a: {
            textDecoration: null,
            '&:link, &:visited': { color: '#08F' },
            '&:hover, &:active': { color: 'red' }
        }
    }
});

Having this resulting in a stylesheet added to the HEAD with the following CSS:

div.special-1, span.special-2 {
    font-family: Trebuchet MS;
}
div.special-1 a, span.special-2 a {
    text-decoration: none;
}

div.special-1 a:link, span.special-2 a:link,
div.special-1 a:visited, span.special-2 a:visited {
    color: #08F;
}

div.special-1 a:hover, span.special-2 a:hover,
div.special-1 a:active, span.special-2 a:active {
    color: red;
}

After a bit of work to make a few Sass-like features work, I came up with the following JavaScript function:

Brief css(objStyles, opt_ancestors) Documentation

This function takes an object representing CSS rules and adds a stylesheet with those rules to the document.

Parameters

  1. objStyles
    An object representing the CSS rules to be inserted into the document.

    • Property names will be used as media queries if they start with "@media ".
    • Property names will be used as rule selectors if the value is an object.
    • If a property name is to be used as a selector, if any selectors don’t contain &, "& " will be prepended to it.
    • For all selectors, & will be replaced recursively with the selectors found in the parent.
    • CSS property names will be uncamelcased by inserting dashes before each uppercased character and lower casing all characters.
    • If a value is null or undefined, it will be turned into "none".
    • If a value is a number other than 0, "px" will be appended to it.
    • If a value is an array all of the items will be concatenated together, using "," to delimit the values.
    • If a value ends with ! it will be replaced with "!important".
  2. opt_ancestors
    Optional. This can be an element or an array of elements which will get another class added to target all rules to it and its children. This can alternatively be a CSS path (selector) specifying the root on which all CSS rules created should be based.

Returns

The stylesheet that is created and appended to the document is returned.

Future Development

I feel like this function turned out pretty well so I plan on incorporating it into YourJS (whenever I finish up with that :-D ). In the meantime, if I update the code, you will be able to see the updates here or in GitHub. One thing I would like to incorporate is the ability to have variables. Another nice-to-have thing would be the ability to supply more options such as where the stylesheet should be inserted (if it will be inserted at all), pretty-print, and helper functions (eg. darken). Feel free to leave a comment saying what other things may be nice to have. 8-)

JavaScript – String.prototype.toProperCase()

Now Available in YourJS

At times you may need to format a string so that it is more appealing. One function that does this is String#toProperCase() because it actually capitalizes the first character of each word. Even though I already had a simple version of this defined in jPaq v1 I thought it would be nice to add the option to lower-case the remaining characters. Here is the updated version of the function definition:

String.prototype.toProperCase = function(opt_lowerCaseTheRest) {
  return (opt_lowerCaseTheRest ? this.toLowerCase() : this)
    .replace(/(^|[\s\xA0])[^\s\xA0]/g, function(s){ return s.toUpperCase(); });
};

Examples of using this function are as follows:

var msg = "Where in the WORLD is Carmen Sandiego?";
alert(msg.toProperCase());  // Where In The WORLD Is Carmen Sandiego?
alert(msg.toProperCase(true));  // Where In The World Is Carmen Sandiego?

At this point this change is scheduled to appear in the next version of jPaq but seeing as how I still don’t know when I will have time to release it I figured it would be a good idea to publicly release it here for everyone to use. Have fun. 8-)

JavaScript – Creating A JS Library with Optional Prototypes

One thing that I started working on last year, but unfortunately never released, was a version of jPaq which provides the ability to pick whether or not prototypal functions are created. The reason I started working on this was to somewhat satisfy the complaints of those who feel that native prototypes should not be modified. You may wonder how a JavaScript library could be written with the option of adding the corresponding prototypal functions. The following is an example of such a library:

// EXAMPLE JAVASCRIPT LIBRARY USING PROTO
(function(slice, undefined) {
    // Function that adds the specified function as a prototypal function to the
    // specified class with the specified name.
    function proto(theClass, fnName, fn) {
        return theClass.prototype[fnName] = function() {
            return fn.apply(undefined, [this].concat(slice.call(arguments, 0)));
        };
    }

    // Array of prototypal functions to add.
    var protosToAdd = [
        [String, 'lstrip', trimLeft],
        [String, 'rstrip', trimRight],
        [String, 'strip', trim]
    ];

    // Trim functions to be added to jPaq.
    function trimLeft(s) {
        return s.replace(/^\s+/, '');
    }
    function trimRight(s) {
        return s.replace(/\s+$/, '');
    }
    function trim(s) {
        return trimLeft(trimRight(s));
    }

    // Defining the library (in this case jPaq) in the global namespace.  The
    // library comes built-in with the trim functions but if the protoAll
    // function is called the trim function will be prototypalized.
    jPaq = {
        proto: proto,
        trimLeft: trimLeft,
        trimRight: trimRight,
        trim: trim,
        protoAll: function() {
            for (var i = protosToAdd.length; i--;) {
                proto.apply(0, protosToAdd[i]);
            }
        }
    };
})([].slice);

If you were to run the above code block, you would end up defining the scaled-down jPaq library object. On the other hand, at the point no prototypes were actually modified. So, how does this code actually help us? The power is in the proto function which is called by the protoAll function. If you are a developer who doesn’t mind a native prototype being updated (String.prototype in this case), you could execute the following:

jPaq.protoAll();

At this point, executing jPaq.protoAll is the equivalent of the following:

jPaq.proto(String, 'lstrip', jPaq.trimLeft);
jPaq.proto(String, 'rstrip', jPaq.trimRight);
jPaq.proto(String, 'strip', jPaq.trim);

Either one of the above code blocks results in definitions for String.prototype.lstrip, String.prototype.rstrip, and String.prototype.strip. These definitions use the corresponding trim functions defined in the first code block but the only difference is that the context object is passed as the first (and in this case only) argument to the corresponding function. As you may have guessed, this can be very useful, assuming that you design your non-prototypal functions to take the first argument that would be passed in as the context object in a prototypal environment.

Even though this proto function is currently something that I have defined for an example version of jPaq, this could be really be used for almost any JavaScript library. Therefore, if you are creating your own JS library and want to distribute it with the option to add prototypal functions, the following is the function snippet that you can add:

var proto = (function(slice, undefined) {
    return function(theClass, fnName, fn) {
        return theClass.prototype[fnName] = function() {
            return fn.apply(undefined, [this].concat(slice.call(arguments, 0)));
        };
    };
})([].slice);

I hope this helps. 8-)

JavaScript – Debounce

Recently I was working on an HTA which contained an element that I wanted to be resized when the window resized. The issue was that I only wanted the resizing to occur after 0.5 seconds elapsed in which the user was not resizing the window. For this reason the debounce function was born (or re-invented since it already is available in other JS libraries):

/**
 * @license Debounce - By Chris West - MIT License
 *
 * Creates a debounced copy of the function which when called will delay the
 * execution until the specified amount of milliseconds have elapsed since the
 * last time it ran.
 * @param {!Function} fnCallback  The function to debounce.  The context and
 *     parameters sent to the debounced function will be sent to this function.
 * @param {number} delay  The amount of milliseconds that must pass since the
 *     last call to this function before fnCallback will be invoked.
 * @param {boolean=} immediate  Optional.  Defaults to false.  Specify true if
 *     the debounce function should run immediately instead of initially waiting
 *     for the delay.  If true is specified, when the debounced function runs,
 *     if the delay has elapsed, the value returned from the debounced function
 *     will be that which was returned by fnCallback.
 * @return {!Function}  The debounced copy of fnCallback.
 */
function debounce(fnCallback, delay, immediate) {
    var timeout, ready = 1;
    return function() {
        var args = arguments, context = this;
        clearTimeout(timeout);
        timeout = setTimeout(function() {
            if(!(ready = immediate)) {
                fnCallback.apply(context, args);
            }
        }, delay);
        if(immediate && ready) {
            return ready = 0, fnCallback.apply(context, args);
        }
    };
}

The above debounce function works the same way as Underscore.js’s debounce function. The only difference is that the code is just a tad bit shorter when minified. I will probably end up adding this function to the next version of jPaq, but until then feel free to use the above snippet yourself. 8)

JavaScript – Calling Functions Only Once

At times when dealing with functions that will be bound to an element you may need to prevent that function from being run multiple times. In order to do that you could use a JavaScript library such as jQuery and bind the function with the jQuery#one function. If that is the only other functionality you actually need though without adding a new library, you could using a function such as the following:

/**
 * Creates a new function which will call the original function only a limited
 * amount of times (defaulting to one time).
 * @param {!Function} fn  The function which should only be called a limited
 *     amount of times.
 * @param {number=} maxCalls  Optional.  Defaults to 1.  The maximum amount of
 *     times the specified function can be called.
 * @param {boolean=} throwErrors  Optional.  Defaults to false.  Specify true if
 *     once the limit is hit an error should be thrown instead of returned.
 * @return {!Function}  Returns a new wrapper function which will only call the
 *     specified function as many times as specified.  The data bound and passed
 *     into this function will be bound and passed onto the original function.
 *     After the limit has been reached an Error object will be returned with a
 *     message of "limit exceeded".
 */
function limit(fn, maxCalls, throwErrors) {
  maxCalls = maxCalls || 1;
  return function() {
    if(maxCalls-- > 0) {
      return fn.apply(this, arguments);
    }
    else {
      var err = new Error('limit exceeded');
      if(throwErrors) {
        throw err;
      }
      return err;
    }
  };
}

Example

Now that we have the definition for this limit function we can learn how to use it by example:

// Encapsulate data so the user cant cheat.
(function() {
  // Function to greet the user.
  var sayHello = limit(function(name) {
    alert('Hello ' + name + '!!!');
  });

  // Ask for the user's name.
  var userName = prompt('What is your name?', 'user');

  // Greet the user.
  sayHello(userName);

  // Try greeting the user again... this should fail.
  sayHello(userName);

  // Generate a random number from 1 to 10.
  var randomNumber = parseInt(Math.random() * 10) + 1;
  
  // A function which will only allow the user to make 3 guesses.  After
  // 3 guesses, subsequent calls will cause an error to be thrown.
  var makeGuess = limit(function(previousGuess) {
    return prompt('Guess a number between 1 and 10:', previousGuess);
  }, 3, true);
  
  // Play the guessing game.
  var guess = '';
  try {
    while(+(guess = makeGuess(guess)) != randomNumber) {
      if(guess < randomNumber) {
        alert('Nope, it is higher than that.');
      }
      else {
        alert('Nope, it is lower than that.');
      }
    }
    alert('You got it!!!');
  }
  catch(e) {
    alert('Unfortunately you hit your limit.\n'
      + 'The number I was thinking of was ' + randomNumber + '.');
  }
})();

You can click here to see the result of running the two preceeding blocks of code. Note that the greeting only appears once, even though it is in the code twice. Also notice that the try-catch clause is used to determine when the user tries to make another guess but the maximum amount of guesses have already been made.

Function Description

This limit function creates a new copy of the function passed in which can only be called a limited amount of times.

Parameters

  1. fn {Function}:
    The function which will only be called a limited amount of times.
  2. maxCalls {number}:
    Optional. Defaults to 1. The maximum amount of times the returned wrapper function can be called before producing an error.
  3. throwError {boolean}:
    Optional. Defaults to false. If true is specified an error will be thrown if the amount of calls is exceeded. Otherwise the error will simply be returned.

Returns

Returns a new wrapper function so that the context and the parameters passed to this wrapper function will be passed to fn iff maxCalls hasn’t been exceeded.

Final Notes

Personally I would think this is most useful for event handling but if you have anymore uses for it please let us know. 8)