JavaScript – Global Eval Using Data URIs

WARNING:
This post is intended solely to educate and is not to by any means encourage that anyone use this method to globally evaluate JavaScript code. Most JavaScripters avoid eval(), especially globalEval() (like what is provided in libraries such as jQuery), as if it were the plague. Its use can be substantiated in some cases but it is of the utmost importance to consider the risks involved with the two functions.
SCRIPTER’S DISCRETION IS ADVISED. :lol:

Since many modern browsers now offer the ability to use Data URIs for more than just images, we could actually use them to essentially run a string of JS code on a page in the global namespace. How so? Here is the code for a simple globalEval() function that can be used in modern browsers such as Chrome and FireFox:

Conceivable Uses

As the jQuery docs mention, one good reason that this type of function exists is to provide a way to execute external scripts in the global namespace. It is important to reiterate that you must use this type of function sparingly, analyzing the reasons why you are using it in the first place.

Another conceivable use would be if you are developing a browser extension that really needs to execute a JavaScript snippet on certain pages. At this point though, if you decide that you want to publish your extension through Google or whichever other channel, that authority may deny your request in the interest to safeguard users from malicious intent. On the other hand, if you are simply creating something like a Chrome extension for private use, I believe you should be able to use this type of approach to execute additional code within pages visited by the user.

Final Words

Much more could be said of the uses of globalEval() and reasons not to use globalEval(), but I like to keep my posts short. If you do find yourself thinking you want to use globalEval(), be sure to calculate the risks (such as possibly running malicious code if it is coming from an external source). Also, this implementation, although very simple, will not work in older browsers such as IE7 (and hasn’t been tested in IE8 or IE9). If you really need a version that has been tested for almost all browsers, I suggest using jQuery’s implementation or perhaps this one. Be careful! :cool:

JavaScript – Creating A Downloadable File in the Browser

Let’s say that you have an array of arrays that is dynamically generated and you would like to provide a download link/button to download it as a CSV. How would you go about doing it? Ordinarily you would go about sending the data to the server which would then be able to make a downloadable version of the data. Believe it or not, there is also a way to do it in modern browsers without ever needing to make additional requests to a server. The following JSBin proves this by providing a large textarea that can be modified and a download link which when clicked (in modern browsers) will download a file with the specified contents:
JS Bin

How does it work? We basically just rely on data URIs. For instance, clicking here should result in downloading a file with text saying Hello World!!!. This an simply an anchor element (<a>) with an href of data:text/plain;charset=utf-8,Hello%20world!!!. In addition, some newer browsers (Chrome and FireFox) support the download attribute being set to specify the default file name when downloaded.

How do you get it to be dynamic? You can simply modify the href attribute when the link is clicked, by binding the necessary code to the click event of the link. Here is a simple version of the JSBin shown:

<!DOCTYPE html>
<html>
  <head>
    <style type="text/css">...</style>
    <script type="text/JavaScript">
    window.onload = function() {
      var txt = document.getElementById('txt');
      txt.value = window.onload + '';
      document.getElementById('link').onclick = function(code) {
        this.href = 'data:text/plain;charset=utf-8,'
          + encodeURIComponent(txt.value);
      };
    };

    main();
    </script>
  </head>
  <body>
    <div id="txtWrap">
      <textarea id="txt"></textarea>
    </div>
    <a href="" id="link" download="code.txt">Download Above Code</a>
  </body>
</html>

Ignoring the omitted CSS rules, you will notice that the concept is quite simple. The one thing you want to remember is that in order to make sure that all characters are downloaded correctly you will want to use encodeURIComponent(). I have seen implementations that use escape(), but that function is deprecated and doesn’t always encode the characters correctly.

Have fun making your quick custom download buttons :cool:

POW Answer – Circle, Square, Circle

Last week’s problem involved using your geometry/trigonometry skills to find areas of shapes. We start off with a large (black) circle which has a (black) square inscribed in it which in turn has a (red) circle inscribed in it:
Circle Inscribed In A Square Inscribed In Another Circle

  1. Let’s start off with the equation for the area of a circle: A = π × r2 (where r is the radius)
  2. Now let’s think about the equation for area of a square: A = s2 (where s is the length of one of the sides)
  3. Next we can say that the radius of the inner circle is r1.
  4. After that let’s find the area of the red inner circle relative to r1: A1 = π × r12
  5. Now let’s find the length of the diagonal of the square (d) in which the red circle is inscribed relative to r1. This will also be the diameter of the outer circle
    1. s = r1 + r1 = 2 × r1
    2. The above is true because the red circle is inscribed in the square.
    3. d2 = s2 + s2
    4. d2 = 2 × s2
    5. d = (2 × s2)1/2
    6. d = s × 21/2
    7. d = 2 × r1 × 21/2
  6. Next we should find the area of the black circle (A2), in which the black square is inscribed, relative to r1.
    1. We will use r2 to represent the radius of the outer circle:
      1. r2 = d / 2
      2. r2 = (2 × r1 × 21/2) / 2
      3. r2 = r1 × 21/2
    2. A2 = π × r22
    3. A2 = π × (r1 × 21/2)2
    4. A2 = π × r12 × 2
  7. Lastly we should find the area of the black outer circle while excluding the area covered by the red inner circle:
    1. Let’s make the area of the black doughnut shape be represented by A3.
    2. A3 = A2 - A1
    3. A3 = (π × r12 × 2) - (π × r12)
    4. A3 = (π × r12) + (π × r12) - (π × r12)
    5. A3 = π × r12

So after doing all of the math by using a little geometry and a little algebra we end up with the A1 (red area) being equal to A3 (black area).
Filled Circles

Even though the image makes it look like there is more red than black, there really isn’t. Interesting stuff, huh? :cool:

POW – Circle, Square, Circle

Recently a friend asked why I haven’t put up any new POWs (Problems of the Week). Part of the reason is because I got lazy but the other part is because the show Numb3rs is what inspired me before and I haven’t been watching any reruns lately :razz: . Yesterday I started watching a new show called Scorpion which has a little math in it and the second episode got me thinking about inscribed shapes. Take the following three shapes for example:
Circle Inscribed In A Square Inscribed In Another Circle

Above is a picture of a circle inscribed in a square which itself is inscribed in another circle. Now if I make the inner circle red and the remaining area black the image ends up looking as follows:
Filled Circles

Using the information given, is the red area bigger or the black area? If you remember a few things from trigonometry/geometry I’m sure this math problem will be a breeze :cool: . As usual the answer to this problem of the week became available a week after the POW was published and can be found here.

Embedding Stylesheets in JavaScript

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 Snippet – Get Function Comments

Last year I wrote about having heredoc like strings available in JavaScript. Today I figured i’d briefly bring the topic back, providing a solution for returning an array of all comments found in a function:

Why is this useful? As you may know, writing multiline strings in JavaScript isn’t always the prettiest especially when you have to use \n or \r\n. On the other hand, let’s imagine that we have some multiline strings stored inside of a function as comments:

As you can see in the above jPaq Proof, by using the getComments function on a function which contains comments you can pull the comments out as if they were HEREDOC strings. Have fun! 8-)

NOTE: It is important to remember that if you are minifying your code, these comments will most-likely be stripped out. In this case you will want to find a different solution such as using the string escape characters (\r\n or \n).

Watch Anime & Cartoons Online for Free

Recently I have had the desire to provide more multimedia on my site. Due to the server requirements and the time it would take to keep everything up-to-date I decided to take the easy way out and simply link to the media providers such as Apple and WatchCartoonOnline. If you check out my home page at GoToChrisWest.com you will notice I have three new content sections with one of them for displaying anime/cartoon content. How did I get it to work? The following is the JSBin version of the content:
WatchCartoonOnline Links

As is the case with all JSBin content, you will be able to look through all of the HTML, CSS and JS code yourself, but it is important to note that with just a few tweaks here and there you could modify this code to work on your own site. I’d like to note that besides using the RSS feed provided by WatchCartoonOnline I am also using two different services provided by Google:

  1. Google Feed API (https://ajax.googleapis.com/ajax/services/feed/load?…):
    Used to convert the feed into JSON-P.
  2. Google Image Search API (https://ajax.googleapis.com/ajax/services/search/images?…):
    Used to search for a thumbnail to display next to each episode name. If you want to actually use this on your site it is suggested that you use the non-deprecated Custom Search API :-)

I’d also like to mention that the scripts added to handle the JSON-P calls are created by the function outlined here.

One way you could improve this code would be to avoid making a new JSON-P call for an image for a show that was already search for. There are most-likely other ways to improve this code as well, but I feel it’s a pretty good starting point for anyone that would like to provide similar links to WatchCartoonOnline content on their site. 8-)

JavaScript – Adding A Script Dynamically

First, I want to start off by saying that there are plenty of JS libraries that provide the ability to add scripts to the page such as jQuery. The purpose of this article is to present an alternative function whose sole purpose is to add scripts (JSON-P or otherwise) to a page.

The following is the code for an addScript function which can either add static scripts or server generated scripts such as those used for JSON-P:

/**
 * Adds a script to the page which pulls its code from the specified URL.
 * @param {string} url
 *     URL of the script to add.
 * @param {Object=} opt_params
 *     Optional extra parameters to be added to the URL.  If one of the
 *     parameters is a function, that function will be used as the JSON-P
 *     callback function.
 * @returns {!Element}
 *     The script element that was added to the head.
 */
function addScript(url, opt_params) {
  // The context can be changed from this frame's window to a different
  // frame's window by using the call or apply function.
  var context = this, document = context.document;

  // Construct the entire URL.
  var urlHasParams = url.indexOf('?') +  1;
  if (opt_params) {
    var keys = Object.keys(opt_params), i = keys.length;
    while (i--) {
      var key = keys[i], value = opt_params[key];
      if (Object.prototype.toString.call(value) == '[object Function]') {
        var callback = value;

        // Add a function to the global namespace that will be used for the
        // JSON-P callback.
        value = '_';
        do {
          value += +new Date;
        } while (value in context);
        context[value] = function() {
          delete context[value];
          callback.apply(this, arguments);
        };
      }
      url += (urlHasParams++ ? '&' : '?')
        + encodeURIComponent(key) + '=' + encodeURIComponent(value);
    }
  }

  // Add the script to the HEAD.
  var script = document.createElement('script');
  script.src = url;
  script.type = 'text/JavaScript';
  document.getElementsByTagName('head')[0].appendChild(script);
  return script;
}

Now if you wanted to use this function for a JSON-P call you could do something like the following:

addScript('http://example.com/service?callback=myFunction');

This will only work assuming that you have myFunction defined in the global namespace. Now let’s say you want to make the same call but you want the callback to be an anonymous function. Here’s how you can do it:

addScript('http://example.com/service', {
  callback: function() {
    // Do the stuff you want here
  }
);

Of course the name of the callback parameter doesn’t have to be `callback`; it can be arbitrary. If you check out the code you will see that this works by actually temporarily adding a function to the global namespace. As soon as the temporary function is called it is removed from the global namespace.

As a final note it is important to mention is that if you will be passing opt_params to this function you will want to ensure that Object.keys is available in the environment in which your code will run (most browsers natively support this function). If this function isn’t assured to be defined in the environment, it would be a good idea to use code which emulates it. 8-)

Upcoming Movie Trailers Thanks to Apple & YouTube

A little bit ago in this article I talked about being able to convert XML to JSON(P). I finally got around to making a page which shows upcoming movie trailers and information. First, I have to admit that the data is coming from both Apple and YouTube. You can check my trailers page by clicking here. One cool thing you’ll notice is that your given all of the summary data you may want to know about the upcoming movies (these are the same ones found on trailers.apple.com). It also provides a way to search and show any of the YouTube trailers without having to leave the page. The main link for each movie actually opens an IFRAME to the corresponding page on trailers.apple.com.

Even though having the trailers page worked out nicely I still wanted to trailers displayable on the GoToChrisWest.com home page. If you visit the page now you will see that they are available, but the following JSBin shows how this code actually works:
GoToChrisWest.com

Feel free to check out http://gotochriswest.com/trailers/index.js as well to see how i’m actually pulling the movie data in from Apple. 8-)

JavaScript Snippet – Fancy getKeys

Most of us know the simple way to get the keys from an object in JavaScript (~61 bytes after minified):

function getKeys(obj) {
    var k = [];
    for (var i in obj) {
        k.push(i);
    }
    return k;
}

But how many of us knew that array assignment within the for-in loop would work? (~58 bytes after minified)

function getKeys(obj) {
    var i = 0, k = [];
    for (k[i++] in obj) {}
    return k;
}

To be honest I cant take the credit for this because I actually found it here. Even though knowing this may rarely help you shorten your code, this is still a pretty cool capability! 8-)

WARNINGS:

  • The above defined getKeys function is really just to prove that you can do for(anArray[counter++] in anObject)....
  • If you can be certain that Object.keys will be defined in the environment in which your code will run, you should use that native function instead.
  • Using this function as is will include prototypal properties defined for the class of the object passed.
  • This function will not return properties that override prototypal properties (such as toString) in some environments.

JavaScript, Math, and much more.