pipwerks SCORM Wrappers now available on GitHub

I’ve been considering adding my pipwerks SCORM wrappers to GitHub for a very long time, but my n00bness and general lack of free time were major obstacles. However, the time has finally come to buckle down and get these puppies OUT! So without further ado, I present:

https://github.com/pipwerks/scorm-api-wrapper

I should note that these are my original SCORM wrappers (JavaScript, ActionScript 2 and ActionScript 3); I’ve been (very slowly) working on a completely new SCORM support codebase that I plan to release separately. However, these oldies are still running like a champ, so don’t be afraid to use them.

Many people have contacted me over the last few years with suggestions for improvements, but due to my general busy-ness I haven’t really made any modifications for a long time; I recently made a few small tweaks, including updating the StringToBoolean function that caused problems in Plateau, but the bulk of the code remains largely the same.

If you’re one of those die-hards eager to tweak the source code, you’re in luck! This is a public repository, which means anyone and everyone is now free to fork and edit the code as they see fit. If you have any suggestions or ideas, please go to GitHub and show us what ya got!

And for the curious, I’m using Tower to handle my Git commits — command lines are not my cup of tea. Tower is a very nice Git GUI that integrates seamlessly with GitHub. I’m new to Tower, but so far I like it very much.

Instructional Technologist, Explained

I bill myself as an instructional technologist, which means I’m often met with blank or puzzled stares. I thought it might be useful to explain my rational for using this title.

Warning: this post may bore you to death, or cause you to get caught up in a tangled web of semantics.

In my opinion, an instructional technologist is a person who specializes in utilizing technology for instructional purposes. (Duh!) It’s a very broad title that can cover many different and often only tangentially-related duties.

When I was younger (so much younger than today), I worked in a number of educational and non-profit organizations in a technology support capacity, including print production, radio broadcasting, audio engineering and video production. With the dawn of the internet, I expanded my skill set to include web development. I relished working in a variety of mediums, and began to think of myself as a media generalist. Being a jack of all trades* was fun, and it felt good to know that most of my projects were educational or somehow helped the community.

When I decided to go to grad school, San Francisco State University’s Instructional Technologies (ITEC) program seemed like a perfect fit. I assumed that the program’s title meant that we would learn how to use technology in an educational capacity. Turns out I was only half right — technology was definitely involved, but I was also informed that “technologies” sometimes referred to adult learning theories and principles, not just just tools. Instructional design, which is completely independent from common notions of technology, was the primary focus of the program. I learned a lot about educational psychology and learning theories while in the ITEC program, and oddly didn’t really learn much about technology as I had traditionally defined it.

Once I graduated from the ITEC program, I jumped right into e-learning development, as both a content author, a course developer, and a course delivery systems programmer (SCORM, course development tools, etc… probably what pipwerks.com is most associated with).

As a content author, I often performed instructional design tasks, including needs assessments, research, writing, and content sequencing. For these tasks, instructional designer seemed most appropriate. However, because I also handled the media authoring and programming side of the courses, many people thought of me as a programmer, web developer or e-learning developer — all of which I felt were also too restrictive. I don’t want to be stereotyped or painted into a corner.

What to do? Well, I hearkened back to my grad school days and copped the title instructional technologist. It felt flexible enough to work for my needs, while still being accurate and even a tad mysterious. Mystery is fun, especially when most of your co-workers have bland titles like “analyst.”

Instructional technologist is also portable. Last week I left my old job and started a new one. While I used to focus on e-learning development and LMS administration, I now work with classroom support in a university setting, with a focus on administering a lecture capture system. Although I’m working in a completely different environment with very different technology, I’m still working with technology in an instructional or educational capacity. I was able to retain my working title of instructional technologist (kudos to my new bosses for agreeing to it).

Many people in universities use a title such as educational technology specialist. That’s a nice title, and very fitting for what they do. However, it also has the connotation of educational institution, such as university or even high school. Since my work has spanned corporate training as well as community and university work, I prefer the word instructional over educational.

So there you have it. Instructional technologist, explained. Think it’s great? Ridiculous? Have a better idea? I’d love to hear your thoughts.

* “Jack of all trades, master of none, though oftentimes better than master of one”
[ citation ]

IFrames and cross-domain security, part 3

In 2008 I posted a quick writeup on how I dealt with cross-domain security issues for some of my e-learning courseware. Since then, I’ve had a lot of people contact me with various questions and requests for a working example.

Tonight I decided to revisit the topic and whip up some quick example files. To my chagrin, I discovered a load of typos in my original post. Yikes! No wonder people wanted to see some working examples.

Well, ask no more, here they are:

The explanation provided in the previous post is still valid, just refer to these new sample files instead of the code in that post’s examples. (I will update that post with new code examples soon.)

Remember, the proxy.html file must reside on the same domain as the parent frame. This solution will not work if you don’t have FTP access to both domains, since you need to place support scripts on both domains.

Comparing and cloning objects in JavaScript

Here’s a handy way to determine if two JavaScript objects are identical without using a framework like jQuery or MooTools:


var compare_objects = function (obj1, obj2){

    var parameter_name;
    
    var compare = function(objA, objB, param){
        
        var param_objA = objA[param],
            param_objB = (typeof objB[param] === "undefined") ? false : objB[param];
        
        switch(typeof objA[param]){
            case "object": return (compare_objects(param_objA, param_objB));
            case "function": return (param_objA.toString() === param_objB.toString());
            default: return (param_objA === param_objB);
        }
        
    };
    
    for(parameter_name in obj1){
        if(typeof obj2[parameter_name] === "undefined" || !compare(obj1, obj2, parameter_name)){
            return false;
        }
    }

    for(parameter_name in obj2){
        if(typeof obj1[parameter_name] === "undefined" || !compare(obj1, obj2, parameter_name)){
            return false;
        }        
    }

    return true;

};

Here’s an easy way to clone a JavaScript object:


var clone_object = function (original_obj) {
    var new_obj = {};
    for(var param in original_obj) {
        if(original_obj.hasOwnProperty(param)){
            if(typeof(original_obj[param]) === "object"){
                new_obj[param] = clone_object(original_obj[param]);
            } else {
                new_obj[param] = original_obj[param];
            }
        }
    }
    return new_obj;
};

A real-world example of the two functions:


var object_1 = { fruit: "apple", tree: "dogwood", number: 3 };
var object_2 = { fruit: "apple", tree: "dogwood", number: 3, cartoons: { anime: "robotech", fantasy: "he-man" } };
var object_3 = clone_object(object_2);

console.log("objects 1 and 2 match? " +compare_objects(object_1, object_2));
//displays false;

console.log("objects 2 and 3 match? " +compare_objects(object_2, object_3));
//displays true

Bear in mind both of these functions are recursive, which means the larger the object, the slower the performance.

For Your Reading Pleasure: EasyCaptions

Introducing EasyCaptions: A simple system for adding captions and an interactive transcript to online videos. EasyCaptions uses progressive enhancement to provide the best possible experience for all visitors, regardless of their browser’s JavaScript, HTML5 or Flash support.
Demonstration

Background

I don’t produce much video these days, but as a web surfer I often encounter other people’s videos, and was recently impressed by two video implementations: a TED Talks video page, and an HTML5 video demo produced by Bruce Lawson.

The TED Talks page had a great feature I’d never really seen anywhere else: an interactive transcript of the video that you can read and click. For example, you can click the third sentence of the transcript and the video will jump to that point.

Bruce Lawson’s demo illustrated a dead-simple way to add captions to an HTML5 video using just a wee bit of HTML markup and JavaScript.

Both of these pages shared a unique attribute: they stored complete transcripts of the videos in the markup of the HTML page itself, NOT in an external XML file, as is most commonly seen. What’s the big deal about inline transcripts, you ask? Well, today’s most common captioning options require placing your caption text in an external XML file that loads via ActionScript or JavaScript/AJAX. Both the TED page and Bruce’s demo eschew that approach and place the full transcript in the HTML. This means the transcript is always available to the visitor, regardless of that browser’s support for HTML5, JavaScript or Flash Player.

In both cases, the transcript had been marked up as paragraphs, with extra markup denoting phrases that align with the video’s timecode. The TED site used a tags to mark each phrase, with inline JavaScript triggering the playback of the clicked link. This is functional when JavaScript is enabled, but fails when JavaScript is disabled, leaving you with a ton of bloated markup that doesn’t work:


<p>
<a href="#" class="transcriptLink" onclick="seekVideo(0); return false;">One way to change our genes is to make new ones,</a> 
<a href="#" class="transcriptLink" onclick="seekVideo(2000); return false;">as Craig Venter has so elegantly shown.</a>
</p>

Bruce’s span tags, on the other hand, are semantically sound — a span is a neutral, unobtrusive inline element meant to be a child of a block element such as p. Perfect. But wait, there’s more! Since this was an HTML5 demo, Bruce took advantage of the new data attribute that can be used on just about any HTML element. (The short version is: you can create any custom attribute you want, so long as the name begins with data-.) Bruce decided to create two attributes for each span: data-begin, which indicates (in seconds) when the phrase starts in the video, and data-end, which indicates when that phrase has ended in the video. Simple as can be, and extremely efficient:


<p>
<span data-begin=1 data-end=6>Hi, my name's Dr Archimedes Einstein 
and I'm a Dctor of Science at the University of Science</span>
</p>

Enter: EasyCaptions

I was incredibly inspired by these two pages and decided to combine their features, creating a new system I call EasyCaptions. The goal of EasyCaptions is to make it as simple as possible to add useful captions to your online videos. I want to eliminate the headaches of captioning as well as the excuses (too hard, confusing, etc.).

What EasyCaptions does:

  • Dynamically generates a div under your video that will display caption text (the div‘s style and positioning is completely configurable via CSS).
  • Dynamically makes each span in your transcript clickable, jumping to that point in the video. This is done via progressive enhancement and event delegation, leaving your markup clean and avoiding heavy-handed use of onclick.
  • Works out-of-the-box with HTML5.
  • Includes HTML5 video support detection, enabling you to use a Flash-based fallback if you desire.
  • Provides a hook for Flash-based fallback systems, enabling the captions and transcript to behave identically to the HTML5 version.

What you’ll need to do:

  • Type up the transcript of your video, using <span> tags to wrap each phrase, just like Bruce’s example above.
  • Place the transcript in a container element with a unique ID (such as div id="transcript").
  • Add a teeny bit of JavaScript (about 4 lines).

The final product. Successfully tested in Firefox, Safari, Opera, and Internet Explorer (IE and older versions of the other browsers all use a Flash Fallback if provided).

Peruse the test suite to get an idea of how flexible the system is.

The documentation and downloads are located on the EasyCaptions page.

Rules for Work and School

Lately I’ve been thinking a lot about the workplace and about my kids’ school endeavors. In both situations, some people are excellent role models and some people are perfect examples of what not to do. This has made me wonder “what’s ideal? What rules should we operate under?”

We give our kids rules to follow, yet I see these same rules violated in the workplace all the time. Some rules need to be broken; most rules won’t be considered valid until the person experiences the opposite behavior.

So with all this in mind, I thought I’d type up a quickie list of things I believe in, as it relates to my profession or my kids’ schooling; I’ll leave out politics, religion, the sad state of the music industry, Apple versus Adobe, and alien conspiracies.

The following list is in no particular order. Feel free to add more in the comments.

  • Quality
    If you’re not going to do it right, why bother? Have pride in your work.
  • A sense of craftsmanship
    Your work is your craft, and you should continually strive to improve, no matter how small the improvement.
  • Helping people
    Treat everyone as if they’re a friend or cousin, and do your best (within reason) to help them. Unless, of course, they’re continually taking advantage of your generosity. In those cases, you should put their name on every telemarketing and fundraising list you can think of.
  • Respect
    The golden rule: treat others as you’d like to be treated. Better yet, follow the platinum rule: treat others they way they’d like to be treated.
  • Honesty
    If someone frequently lies, stretches the truth, or misrepresents things, how can you possibly trust them or feel comfortable working with them?
  • Responsibility
    Take care of your obligations, every time. If it isn’t possible for some reason, don’t cover it up — be open about it and look for alternative solutions.
  • Flexibility
    Being overly rigid and unwilling to listen to alternatives will bite you in the ass someday.
  • Communication
    Being clear is extremely important. So is listening to others (not just paying them lip service). If you’re not listening to others, how do you know you’re on the right track with a project or relationship? As we’ve all been told, communication is a two-way street: If you don’t inform others of your intentions, provide context for decisions, or give honest feedback, your relationship will sour.
  • Sharing knowledge
    Ignorance helps no one, except immoral politicians and businessmen. Raise the bar. Share what you’ve learned with others.
  • Don’t be afraid to ask for help
    We’re all n00bs at some point. It’s nothing to be embarrassed about.
  • Simplicity
    Do overdo it just because you can. Clutter isn’t just limited to your closet; websites and e-learning courses frequently suffer from visual and informational clutter, too. It takes restraint and discipline to keep things simple.
  • Equality/Accessibility
    Everyone should be treated equally and have access to the same resources. Building web sites and e-learning courses in an accessible manner is easier than ever. There is no excuse for an inaccessible product. (Note: accessible content does not always mean an equal user experience; for example, reading a transcript of a video may not be as fun as watching the video itself. Regardless, the content of the video is accessible to all.)
  • Don’t be greedy
    Money is a means to an end — no more, no less. Don’t become like all those Wall Street parasites we’ve read about.
  • Enjoy what you have
    We all suffer from daydreams about how much better things would be ‘if only I had thing X.’ Personally, I often forget that today I DO have the thing X I wanted 5 years ago. The problem is that the definition of thing X keeps changing, and I lose sight of what I’ve already accomplished. Many of us need to step back and realize that we probably have more than we realize and take some of it for granted every day.

TextAreaExpander Class for MooTools

I’ve had to create a slew of forms over the last few months, and have become fond of textareas that auto-expand when they become filled. There are a number of MooTools scripts on the interwebs that can handle this task, but none of them suited me, and I generally like to roll my own code as a learning experience.

So, without further ado, I present a very simple MooTools Class: TextAreaExpander. It does exactly what is says: expand textareas. No more, no less.

Details

Options

Defaults are shown.

  • textarea_selector: none
    • Uses CSS selector syntax, such as “#myId” or “textarea.expand-o-rama”
  • padding_bottom: 0
    • Only accepts pixels, no percentages or ems
  • fx_transition: Fx.Transitions.Expo.easeOut
  • fx_duration: 350

Returns

Array of textarea elements

Requires

MooTools 1.2.4 core

Demos

Sample implementation using defaults (grabs ALL textareas on the page):


window.addEvent("domready", function (){
    new TextAreaExpander();								  
});

View ‘simple’ demo

 

Sample implementation specifying all available parameters:


window.addEvent("domready", function (){
    new TextAreaExpander({
        textarea_selector: "#demo",
        padding_bottom: 12,
        fx_transition: Fx.Transitions.Quad.easeInOut,
        fx_duration: 500
    });
});

View ‘options’ demo

Download

License

MIT-style license. Completely free. Enjoy.

Dear Apple and Adobe

 

Update: Steve Jobs Responds! Well, not to my letter directly, but it hits on the major points and is a well-written explanation of Apple’s position.

Dear Apple and Adobe

I’m a long-time customer and have spent more money on your products than I have on just about any other aspect of my life. I’ve spent more money on your products than I’ve spent on my healthcare, vacations, kitchen appliances, children’s school supplies, or home entertainment system.

In return, you’ve increasingly shown a disregard for my needs and concerns, and have acted in ways that demonstrate all you want from me is my money.

For example, both of you have constantly forced me (or at a minimum pressured me) to buy updates to products I already paid for. For years I went along with it because I bought into the sales hype and assumed these updates would somehow make my life better.  In most cases, they did not.

Adobe, your constant tinkering with the Creative Suite has brought a few nifty tools to the world, but these new tools will not get me to overlook the incredible bloat you’ve unleashed on my computers — almost 6GB of program files on my Windows PC at work, and over 7GB of app files on my Mac at home. Your applications feel more unstable with every release, and your UI feels slow and unresponsive despite the extra RAM and other hardware upgrades on my machines. Some of the biggest security holes on my computers are due to your Acrobat software — the very same Acrobat software I’ve learned to hate because of how bloated, complicated, and unfriendly it has become. It feels like it gets worse with each release.

Apple, your innovation is refreshing. Adobe could learn a thing or two by examining your software: increased productivity through reduced feature sets and cleaner UI. Simple is usually best. However, despite your continued excellence in design, your behavior is repulsive. You’ve consistently screwed your early adoptors via your pricing schemes and forced millions of Americans to use a phone network they detest. (Why? Because AT&T was willing to give you a bigger cut of the revenue?) Worst of all, the totalitarianism displayed in your latest iPhone developer agreement is breathtaking. It appears your goal is to piss off everyone, even your staunchest allies… like Adobe.

Apple and Adobe, you used to play well together. You both benefited from your long-term relationship and grew into very large, very successful companies. I sincerely doubt either of you would have survived the 1990s intact if it weren’t for your partnership. Desktop publishing was the Mac’s forte and the one thing that kept it afloat when the buzzards were circling. And who provided the most popular DTP software? Adobe (and the companies Adobe acquired, like Aldus and Macromedia).

Adobe, I know you’re mad because Apple won’t let you put your Flash technology on the new iPhone platform (iPhone, iPod, iPad). Honestly, if I were controlling a platform, I would have major concerns, too. As I mentioned earlier, your track record for software quality seems to be in a steady decline. Your products have become infamous for security holes, bloat, and crashing. It didn’t used to be that way. Somewhere along the line you dropped the ball, and now it’s coming back to bite you. The good news is that it isn’t too late for you to reign things in and regain control of your software. Stop trying to please everyone by adding every conceivable feature under the sun, and really focus on the most important elements. Drop the cruft. Clean the cupboards. Get that lint out of your bellybutton. Once your software is respectable again, you’ll be in a much stronger position to complain about Apple.

Apple, I don’t know what happened to you. You went from being a popular underdog to being the class bully. You’re in danger of becoming as popular as Microsoft in the European court system. From where I sit, your biggest mistake has been the idea that you can take over the world, one industry at a time. Of course, many companies are aggressive and set big goals for themselves, but they don’t stab their partners in the back as quickly and viciously as you seem to do. Your hubris and eagerness to expand into your partners’ markets is going to be your downfall. People have liked you because of your design sensibilities and because you were the hip underdog. You are no longer the hip underdog, and with time, other companies will create products that will be (almost) as stylish but also cheaper and with equivalent or greater capabilities.

The bottom line is that neither of you are choir boys, and I’m fed up with your bickering.

Adobe, stop playing the sympathy card. It’s a complete turn-off because I know how crappy your software can be. Granted, it’s unfortunate that so many people depend on Flash and Flash doesn’t work on the iPhone platform, but Flash is not a web standard. For all its shortcomings, the iPhone platform has one excellent quality: a top-notch HTML5 browser. Standardistas have been warning people not to go all-in with Flash for years, and now we see why. If it isn’t part of a standard, it will not be incorporated into some products. It’s the vendor’s choice. Simple as that.

Apple, stop trying to take over the world. We’ve seen what happens to other companies who try it, and it never looks pretty. Focus on your core values and let your partners do their thing without stepping on their toes.

Oh, and ditch AT&T already, will ya?

Respectfully,

Philip

Providing the same UI across browsers

As a web designer and e-learning course developer, I often grapple with the notion of making my products appear the same in every browser. I’m not opposed to the idea that you should make your work look (almost) identical in every browser. After all, you’re promoting a specific design aesthetic and the last thing you want is for a browser to dictate what you can and can’t do, especially browsers you don’t even like. (I’m looking at you, IE6.)

But it’s never as simple as we’d like. Internet Explorer has that crazy CSS box model. Older versions of Firefox and Safari don’t support border-radius or RGBa.  Mac browsers use completely different scrollbars and form elements than Windows and Linux browsers. For that matter, scrollbars and form elements in Windows 2000 look completely different than XP, Vista, and Windows 7.

This is one of the reasons Flash has become so popular — it allows designers to standardize their RIA‘s UI elements across browsers.

The latest salvo in the war for controlling your browser’s look and feel is Jilion’s SublimeVideo, an HTML5 video playback system that ensures your video has the same controller across browsers. It bypasses the browser’s built-in controller in favor of Jilion’s (very slick) custom controller. Jilion’s blog states (emphasis mine):

We aim at delivering a modern and simple video-embedding solution for web developers that provides the same user experience and uniform UI across browsers.

Jilion’s work comes from the same school of thought that led designers/developers to change the look and feel of other built-in browser components such as radio buttons and checkboxes. (Guilty!)

While looking at Jilion’s fine handiwork, I was struck by a thought: If a person uses a particular browser regularly, they will be accustomed to that browser’s native controls — whether it’s for video or drop-down menus in forms — and might be thrown off by the custom controls. Maybe it isn’t such a good idea to create a homogeneous video controller for all browsers.

After all, why does a Firefox user need to have the same experience as a Chrome user? Why does an Opera user need to have the same experience as an Internet Explorer or Safari user? These people have probably never seen what a webpage looks like in a different browser, anyway. What benefit do site visitors really receive from “a uniform UI across browsers”?

If you change the default controls to match the look and feel of something your visitor has never seen before, you run the risk of creating confusion, distrust, or alienation. Even worse, if the controls are poorly made or conceived — and many are — you might make your site less usable. A cardinal sin.

The more I think about it, the real beneficiaries of a uniform UI across browsers aren’t the site visitors, but rather the designers who demand artistic control and the clients who insist the product looks the same everywhere, without understanding that it’s okay (even expected) to have some differences.

Personally, I realized 100% uniformity is an unnecessary hardship when I began adopting HTML5 and CSS3 features into pipwerks.com last year. These new features are still not supported in all browsers, and essentially forced me to give up IE6 support. (pipwerks.com uses Andy Clarke’s handy Universal IE6 stylesheet for IE6.)

I’ve come to grips with the notion that my site’s design won’t look the same in Opera 9 or IE7/8 because those browsers don’t support border-radius. My design is simple enough that the general impression is preserved across browsers, but people who use certain browsers will see a slightly less refined product. This is a-ok with me.

It should also be noted that growth in the mobile market appears to be shifting perceptions about consistency between browsers, too. Most major sites have a “mobile edition” which will look quite different than the standard website, and is most likely geared to look great on an iPhone and so-so in all other mobile devices.

Rounded corners on images using CSS3

Most browsers do not allow images to be cropped using CSS3’s border-radius. Tim Van Damme recently posted a workaround for this issue. It’s a nice trick, and doesn’t require JavaScript.

It does, however, require an extra span to be added to the page’s markup, which is quite a pain to manually apply to each image. Bram Van Damme (no relation to Tim) posted a simple jQuery script that automate’s Tim’s workaround with minimal effort. It’s a perfect example of using JavaScript for progressive enhancement purposes, as the page is still usable when JavaScript and/or CSS is disabled.

Being a MooTools kind of guy, I decided to whip up a MooTools-flavored version. Enjoy!


window.addEvent("domready", function (){
    $$("img").each(function(img){
        new Element("span", {
            "class": "rounded",
            styles: {
                "background-image": "url(" + img.getProperty('src') + ")",
                height: img.getProperty('height') + "px",
                width: img.getProperty('width') + "px"
            }
        }).wraps(img);
    });
});

Bear in mind this JavaScript relies on your page having some pre-defined CSS:


.rounded {
    -webkit-border-radius: 25px;
    -moz-border-radius: 25px;
    border-radius: 25px;
    display: block;
}
.rounded img { opacity: 0; }

View demo

Notes:

  • The demo page has the code wrapped in a function, which makes the code reusable; it accepts any CSS selector, such as “img”, “#myid img”, “p img”, “img.rounded”, etc.
  • This will only work in browsers that support CSS3 border-radius, which means no IE6/7/8 or older versions of Safari, Firefox, or Opera.