Introducing

Introducing debugger.html

debugger.html is a modern JavaScript debugger from Mozilla, built as a
web application with React and Redux. This project was started early
this year in an effort to replace the current debugger within the Firefox Developer Tools. Also, we wanted to make a debugger capable of debugging multiple targets and functioning in a standalone mode.

collage of debugger targets

Currently, debugger.html can connect to and debug Firefox, and also connects experimentally to Chrome and Node. The debugger connects to Firefox using the Mozilla’s Remote Debug Protocol (RDP) and communicates with Node and Chrome using Chrome’s RDP.

The debugger.html project is hosted on GitHub and uses modern frameworks and toolchains, making it readily available and attractive to a wide audience of developers.

debugger.html

The user interface is separated into three main regions: the sources panel, the editor panel and the right sidebar.

  • The sources panel displays a tree view of all the current sources for the
    application currently being debugged.
  • The editor panel is used to display various source files from the project and provides functionality for setting breakpoints and prettifying the source.
  • The right sidebar displays the current set of breakpoints, the current call stack, and scoped variables, when the debugger is paused.
    • The debugger supports controls for pausing, step over, step in, step out and play functions for debugging your JavaScript.
    • The call stack panel displays the call stack frames for a given pause condition and the scopes panel displays an expandable variable tree based on the selected frame.

debug demonstration Gif

Getting Started

To get started using the debugger you can check out the code from Github
and look through the Getting Started guide.

If you just want to dive straight in, run the following commands:

npm install - Install dependencies
npm start - Start development web server
open http://localhost:8000 - Open in any modern browser

Once you have opened the debugger in a browser on port 8000, the main
debugger page will be displayed, listing any debuggable targets that you can select. In order for the debugger to connect and debug a target it must be running with remote debugging turned on. This generally requires that you start the target with a couple of flags set. For example, you can start a Firefox instance on MacOS to enable remote debugging with the following command:

$ /Applications/Firefox.app/Contents/MacOS/firefox-bin
--start-debugger-server 6080 -P development

Other options for Chrome and Firefox are listed here.

Debugging Node requires that you have version v6.3.0 or higher installed. You will need to run Node with the inspect flag set. For example if you want to debug myserver.js you will need to use a command similar to the following.

$ node --inspect myserver.js

More information is available in the Getting Started guide

Firefox Developer Tools

We are integrating this debugger into our Developer Tools for Firefox. The first iteration has just landed in Nightly and you can try it out there.

example debugging jsfiddle

Getting Involved

As mentioned above, this project is still in development and we’d be grateful for your help in making the best debugger possible. If you are interested in joining us in this effort, please take a look the Contributing guide.

View full post on Mozilla Hacks – the Web developer blog

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

Introducing the WebVR 1.0 API Proposal

2016 is shaping up to be a banner year for Virtual Reality. Many consumer VR products will finally be available and many top software companies are ramping up to support these new devices. The new medium has also driven demand for web-enabled support from browser vendors. Growth in WebVR has centered on incredible viewing experiences and the tools used to create online VR content.

VR_images
The Mozilla VR team has been working hard to support the online creation and display of VR content in the browser. This week marks a WebVR milestone. Working closely with Brandon Jones of the Google Chrome team, the Mozilla team is excited to announce the version 1.0 release of the WebVR API proposal.

Recent VR technology advances and community feedback have allowed us to improve the API to address developer needs.

Some of the improvements include:

  • VR-specific handling of device rendering and display.
  • The ability to traverse links between WebVR pages.
  • An input handling scheme that can enumerate VR inputs, including six degrees of freedom (6DoF) motion controllers.
  • Accommodation of both sitting and standing experiences.
  • Suitability for both desktop and mobile usage.

We are excited to share these improvements to the API. Keep in mind the list above represents a small sample of what has changed. For all the details, take a look at the full API draft and check out Brandon’s blog post.

This article is focused on basic usage of the proposed API, which requires an understanding of some complex concepts like matrix math. As an alternative, you can get a quick start in WebVR by looking at A-Frame or the WebVR boilerplate, both built on top of the API.

Before we dive in, we’d like to give special thanks to Chris Van Wiemeersch (Mozilla), Kearwood “Kip” Gilbert (Mozilla), Brandon Jones (Google), and Justin Rogers (Microsoft) for contributing to the creation of this specification.

Implementation roadmap

We plan to land a stable implementation of the 1.0 APIs in Firefox Nightly in the first half of the year. You can follow along on Bugzilla for all the details, or see status updates on platform support on iswebvrready.org.

Want to get started today? Currently developers can experiment with a proof-of-concept implementation of the new API using Brandon Jones’ experimental builds of Chromium.

Both three.js and the WebVR Polyfill (used by the WebVR Boilerplate mentioned above) have open pull requests to support the latest APIs.

Components of a VR experience

Let’s take a look at the key components required for any VR experience:

  1. The VR display that we are rendering content to.
  2. The user’s pose. The orientation and positioning of the headset in space.
  3. Eye parameters that define stereo separation and field of view.

Here’s a look at the workflow sequence for getting content into the headset:

  1. navigator.getVRDisplays() to retrieve a VR Display.
  2. Create a <canvas> element which we will use to render content.
  3. Use VRDisplay.requestPresent() to pass in the canvas element.
  4. Create the VR device-specific animation loop in which we will perform content rendering.
    1. VRDisplay.getPose() to update the user’s pose.
    2. Perform calculations and rendering.
    3. Use VRDisplay.submitFrame() to indicate to the compositor when the canvas element content is ready to be presented in the VR display.

The following sections describe each of these actions in detail.

Working with VR displays

Devices that display VR content have very specific display requirements for frame rate, field of view, and content presentation that are handled separately from standard desktop displays.

Enumerating VR displays

To retrieve VR displays available to the browser, use the navigator.getVRDisplays() method, which returns a Promise that resolves with an array of VRDisplay objects:

navigator.getVRDisplays().then(function (displays) {
  if (!displays.length) {
    // WebVR is supported, no VRDisplays are found.
    return;
  }

  // Handle VRDisplay objects. (Exposing as a global variable for use elsewhere.)
  vrDisplay = displays.length[0];
}).catch(function (err) {
  console.error('Could not get VRDisplays', err.stack);
});

Keep in mind:

  • You must have your VR headset plugged in and powered on before any VR devices will be enumerated.
  • If you do not have a VR headset, you can simulate a device by opening about:config and setting dom.vr.cardboard.enabled to true.
  • Users of Firefox Nightly for Android or Firefox for iOS will enumerate a Cardboard VR device for use with Google Cardboard.

Creating a render target

To determine the render target size (i.e., your canvas size), create a render target large enough to hold both the left and right eye viewports. To find the size (in pixels) of each eye:

// Use 'left' or 'right'.
var eyeParameter = vrDisplay.getEyeParameters('left');

var width = eyeParameter.renderWidth;
var height = eyeParameter.renderHeight;

Presenting content into the headset

To present content into the headset, you’ll need to use the VRDisplay.requestPresent() method. This method takes a WebGL <canvas> element as a parameter which represents the viewing surface to be displayed.

To ensure that the API is not abused, the browser requires a user-initiated event in order for a first-time user to enter VR mode. In other words, a user must choose to enable VR, and so we wrap this into a click event handler on a button labeled “Enter VR”.

// Select WebGL canvas element from document.
var webglCanvas = document.querySelector('#webglcanvas');
var enterVRBtn = document.querySelector('#entervr');

enterVRBtn.addEventListener('click', function () {
  // Request to present WebGL canvas into the VR display.
  vrDisplay.requestPresent({source: webglCanvas});
});

// To later discontinue presenting content into the headset.
vrDisplay.exitPresent();

Device-specific requestAnimationFrame

Now that we have our render target set up and the necessary parameters to render and present the correct view into the headset, we can create a render loop for the scene.

We will want to do this at an optimized refresh rate for the VR display. We use the VRDisplay.requestAnimationFrame callback:

var id = VRDisplay.requestAnimationFrame(onAnimationFrame);

function onAnimationFrame () {  
  // Render loop.
  id = VRDisplay.requestAnimationFrame(onAnimationFrame);
}

// To cancel the animation loop.
VRDisplay.cancelRequestAnimationFrame(id);

This usage is identical to the standard window.requestAnimationFrame() callback that you may already be familiar with. We use this callback to apply position and orientation pose updates to our content and to render to the VR display.

Retrieving pose information from a VR display

We will need to retrieve the orientation and position of the headset using the VRDisplay.getPose() method:

var pose = vrDisplay.getPose();

// Returns a quaternion.
var orientation = pose.orientation;

// Returns a three-component vector of absolute position.
var position = pose.position;

Please note:

  • Orientation and position return null if orientation and position cannot be determined.
  • See VRStageCapabilities and VRPose for details.

Projecting a scene to the VR display

For proper stereoscopic rendering of the scene in the headset, we need eye parameters such as the offset (based on interpupillary distance or IPD) and field of view (FOV).

// Pass in either 'left' or 'right' eye as parameter.
var eyeParameters = vrDisplay.getEyeParameters('left');

// After translating world coordinates based on VRPose, transform again by negative of the eye offset.
var eyeOffset = eyeParameters.offset;

// Project with a projection matrix.
var eyeMatrix = makeProjectionMatrix(vrDisplay, eyeParameters);


// Apply eyeMatrix to your view.
// ...

/**
 * Generates projection matrix
 * @param {object} display - VRDisplay
 * @param {number} eye - VREyeParameters
 * @returns {Float32Array} 4×4 projection matrix
 */
function makeProjectionMatrix (display, eye) {
  var d2r = Math.PI / 180.0;
  var upTan = Math.tan(eye.fieldOfView.upDegrees * d2r);
  var downTan = Math.tan(eye.fieldOfView.leftDegrees * d2r);
  var rightTan = Math.tan(eye.fieldOfView.rightDegrees * d2r);
  var leftTan = Math.tan(eye.fieldOfView.leftDegrees * d2r);
  var xScale = 2.0 / (leftTan + rightTan);
  var yScale = 2.0 / (upTan + downTan);

  var out = new Float32Array(16);
  out[0] = xScale;
  out[1] = 0.0;
  out[2] = 0.0;
  out[3] = 0.0;
  
  out[4] = 0.0;
  out[5] = yScale;
  out[6] = 0.0;
  out[7] = 0.0;
  
  out[8] = -((leftTan - rightTan) * xScale * 0.5);
  out[9] = (upTan - downTan) * yScale * 0.5;
  out[10] = -(display.depthNear + display.depthFar) / (display.depthFar - display.depthNear);

  out[12] = 0.0;
  out[13] = 0.0;
  out[14] = -(2.0 * display.depthFar * display.depthNear) / (display.depthFar - display.depthNear);
  out[15] = 0.0;

  return out;
}

Submitting frames to the headset

VR is optimized to minimize the discontinuity between the user’s movement and the content rendered into the headset. This is important for a comfortable (non-nauseating) experience. This is enabled by giving direct control of how this happens using the VRDisplay.getPose() and VRDisplay.submitFrame() methods:

// Rendering and calculations not dependent on pose.
// ...

var pose = vrDisplay.getPose();

// Rendering and calculations dependent on pose. Apply your generated eye matrix here to views.
// Try to minimize operations done here.
// ...

vrDisplay.submitFrame(pose);

// Any operations done to the frame after submission do not increase VR latency. This is a useful place to render another view (such as mirroring).
// ...

The general rule is to call VRDisplay.getPose() as late as possible and VRDisplay.submitFrame() as early as possible.

Demos, feedback and resources

Looking for ways to get started? Here’s a collection of example apps that use the WebVR 1.0 API. Also, check out the resources listed below.

And please keep sharing your feedback!

The development of this API proposal has been in direct response to evolving VR technology, and also from community feedback and discussion. We’re off to a good start, and your ongoing feedback can help us make it better.

We invite you to submit issues and pull requests to the WebVR API specification GitHub repository.

Resources

View full post on Mozilla Hacks – the Web developer blog

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

Introducing DevTools Reload

As a way to encourage more open source developers to contribute to the evolution of Firefox Developer Tools, the DevTools team has built DevTools Reload, an add-on that removes some common barriers to entry.

It’s not unusual for mature Open Source projects to have large code bases. This can act as a barrier to entry for new contributors. It might feel as though so much code is going to take a long time to learn, so even if the best way to get started is by fixing simple bugs, the task can seem overwhelming due to the size of the code base.

Another challenge with large code bases is that they often take a great deal of time to download and compile, which further discourages new contributors from taking part. Even if someone decides to dive in at this point, long recompile times after making simple changes can discourage even the most patient of developers.

DevTools Reload allows developers to make changes to the JavaScript and CSS source files, and by pressing a short-cut key combination, automatically reload the tools with all the new changes. Firefox thinks the tools should be hackable just like the Web.

This approach is convenient for making simple fixes to Firefox dev tools, and provides almost instant feedback to the developer who is making the change, allowing for quick iteration and experimentation on possible solutions.

Here’s a short screencast showing how to install the add-on on Firefox Nightly and demonstrating the feature. Or, if you prefer the written word, we also have some guidance on how to get started.

This feature is fairly new, and is still under development, so you might find rough edges and inconsistencies. Please file bugs if you find something doesn’t quite work as you expect it, or get in touch. You can follow the DevTools team (@firefoxdevtools) for more updates. Make sure to submit your contributions to the tools through bugzilla.

View full post on Mozilla Hacks – the Web developer blog

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

Introducing Blast.js

After releasing Velocity.js, a highly performant web animation engine, I wanted to leverage that power for typographic manipulation. The question soon arose, How could I animate one letter, one word, or one sentence at a time without bloating my HTML with wrapper elements?

If I could figure this out, I could create beautiful typographic animation sequences (the kind you see in movie titles), and perform real-time textual analysis.

After researching lower-level DOM methods and polishing my RegEx skills, I built Blast.js: a jQuery/Zepto plugin that breaks apart text to enable hassle-free text manipulation. Follow that link to see a few demos.

Let’s jump right into a code example. If we were to Blast an element using the following syntax…

$("div").blast({ delimiter: "word" });

…and if our element initially looked like this…

<div>
    Hello World
</div>

…our element would now look like this:

<div class="blast-root">
    <span class="blast">Hello</span>
    <span class="blast">World</span>
</div>

The div’s text was broken into individual span elements using the specified word delimiter. We could have used the character, sentence, or element delimiters instead.

For a breakdown of Blast’s API, refer to its documentation.

This article serves to explore the technical aspects that went into making Blast versatile and accurate: We’ll learn about very powerful, yet little-known, DOM traversal techniques plus how to maximally leverage RegEx for linguistic accuracy.

If you’re interested in the technical aspects of how rich motion design works or how to manipulate text, this article is for you.

Versatility

Most DOM elements are composed of descendant text nodes. Blast traverses the entirety of the HTML element that it is targeted on, descending recursively until it’s found every descendant text node.

For example, if you Blast the following HTML:

<div>Hello <span>World</span></div>

The containing div is an element node. This element node is composed of two children: 1) a text node (“Hello “) and 2) a span element node. The span element node contains one child: a text node of its own (“World”).

With each text node Blast finds, it executes the RegEx query associated with the chosen delimiter type (e.g. character, word, or sentence) in order to find submatches. For example, a text node of “World” blasted with the character delimiter will produce five submatches: “w”, “o”, “r”, “l”, and “d”. Blast wraps a new element node of a user-defined type (span is the default) around each of these submatches.

By traversing the DOM in this way, Blast can be applied safely to the entirety of an element without concern for breaking any of its descendant HTML or its associated event handlers. (Event handlers are never bound to text nodes, but rather to containing element nodes.)

In fact, let’s try just that — in real-time! Click here to see Blast used on a CodePen page with the word delimiter. Notice how the generated wrapper elements are filtered with alternating colors. Next, click around. You’ll see that the page continues to work perfectly; all buttons, event handlers, and interactions remain fully intact. Nothing has been compromised.

This versatility is crucial when blasting user-generated content, which, by its nature, is not necessarily predictably structured. It can be dirtied with HTML.

Reversal

When Blast generates wrappers around each of text node’s submatches, it assigns each wrapper a “blast” class. This class is later referenced when Blast is reversed.

Blast reversal is triggered by passing in false as Blast’s sole parameter. The reversal process works as follows: The DOM is traversed, but the elements it’s looking for are element nodes (not text nodes) that have been assigned the “blast” class. Each matched element node is then replaced with its inner HTML.

For example, reversing Blast on the following HTML…

<div id="helloWorld" class="blast-root">
    <span class="blast">Hello</span>
    <span class="blast">World</span>
</div>

… using the following syntax…

$("#helloWorld").blast(false);

…will result in Blast descending into #helloWorld, matching each element node individually, then substituting these element nodes with the text nodes that they contain — “Hello” and “World”, respectively.

After this process, our DOM is back to exactly where it was before we Blasted it. This ability to cleanly reverse allows us to jump into arbitrarily structured HTML, Blast it apart, run a series of typographic animations, then reverse Blast upon completion so that our markup remains clean and structured as originally intended.

Let’s do just that:

See the Pen Blast.js – Command: Reverse by Julian Shapiro (@julianshapiro) on CodePen.

Accuracy

We’ve established that Blast preserves HTML by touching only the relevant nodes (text nodes). Now let’s explore how Blast is able to pull off this next trick:

See the Pen Blast.js TypeKit Article – Accuracy by Julian Shapiro (@julianshapiro) on CodePen.

Remember, when a descendant text node is found in an element node targeted by Blast, the chosen delimiter’s RegEx is executed against it. Let’s examine each delimiter, starting with the simplest: character.

(Note that you can follow along with these examples by clicking the demo buttons under the Robustness Gallery section of Blast’s documentation. You can also visit RegEx101.com to test the following RegEx queries against your own bodies of text.)

The RegEx for the character delimiter is simply /(\S)/, which treats every non-space character as a submatch (a submatch is the part of the text node that gets wrapped by a newly-generated element). Simple enough.

Next, the word delimiter uses this RegEx: /\s*(\S+)\s*/. This matches any non-space character surrounded by either a space or nothing (nothing is the edge case where a word appears at the beginning or ending of a text node). Specifically, \s* means “optionally match a space character”, and the \S+ in the middle means “match as many non-space characters as possible.” Note that the word delimiter matches will include any punctuation that’s adjoined to the word, e.g. “Hey!” will be a full match. For the vast majority of use cases, this is more desirable than treating every adjoined punctuation as its own word.

Now things start to get more complex. It’s trivial to match characters and space-delimited words, but it’s tricky to robustly match sentences — especially in a multilingual manner. Blast’s sentence delimiter delimits phrases either 1) ending in Latin alphabet punctuation (linebreaks are not considered punctuation) or 2) located at the end of a body of text. The sentence delimiter’s RegEx looks like this:

(?=\S)(([.]{2,})?[^!?]+?([.…!?]+|(?=\s+$)|$)(\s*[?’'”?“")»]+)*)

Below is an expanded view (with spacing) for better legibility:

(?=\S) ( ([.]{2,})? [^!?]+? ([.…!?]+|(?=\s+$)|$) (\s*[?’'”?“")»]+)* )

Let’s break that down into its components:

  • (?=\S) The sentence must contain a non-space character.
  • ([.]{2,})? The sentence may begin with a group of periods, e.g. “… that was a bad idea, Tom!”
  • [^!?]+? Grab everything that isn’t an unequivocally-terminating punctuation character, but stop when the following condition is reached…
  • ([.…!?]+|(?=\s+$)|$) …match the last occurrence of sentence-final punctuation or the end of the text (optionally with trailing spaces).
  • (\s*[?’'”?“")»]+)* After the final punctuation is matched, also include any and all pairs of (optionally space-delimited) quotes and parentheses.

That’s quite a bit to to digest, but if you refer to those RegEx components while revisiting the sentence matching behavior from the top of this section (re-embedded below for convenience), you’ll start to see how the larger pieces come together.

See the Pen Blast.js TypeKit Article – Accuracy by Julian Shapiro (@julianshapiro) on CodePen.

(Click on the HTML tab to modify the HTML and see how Blast behaves on different bodies of text.)

We still haven’t explained why that embedded demo’s errant periods aren’t falsely triggering the end of a sentence match: The trick is to perform a pre-pass on each text node — prior to the primary RegEx execution — in which likely false positives are rendered inert by temporary encoding them into non-matching strings. Then, after the sentence RegEx is executed, the likely false positives are decoded back to their original characters.

The false positive encoding process consists of replacing a punctuation character with its ASCII equivalent inside double curly brackets. For example, a likely false positive period (e.g. one found in the title “Mr. Johnson”) will be turned into “Mr{{46}} Johnson”. Then, when the sentence delimiter’s RegEx is executed, it skips over the {{46}} block since curly braces aren’t considered Latin alphabet punctuation.

Here’s the logic behind this process:

text
/* Escape the following Latin abbreviations and English
   titles: e.g., i.e., Mr., Mrs., Ms., Dr., Sr., and Jr. */
.replace(RegEx.abbreviations, function(match) {
    return match.replace(/\./g, "{{46}}");
})
/* Escape inner-word (non-space-delimited) periods.
   For example, the period inside "Blast.js". */
.replace(RegEx.innerWordPeriod, function(match) {
   return match.replace(/\./g, "{{46}}");
});

So now you have an overview of Blast’s behavior, but you haven’t learned that much. Not to worry, the next two sections get super technical.

Deep dive: Regex

This section is optional. This is a technical deep dive into how Blast’s RegEx queries are designed.

This is the RegEx code block that you can find at the top of Blast’s source code:

var characterRanges = {
        latinLetters: "\\u0041-\\u005A\\u0061-\\u007A\\u00C0-\\u017F\\u0100-\\u01FF\\u0180-\\u027F",
    },
    Reg = {
        abbreviations: new RegExp("[^" + characterRanges.latinLetters + "](e\\.g\\.)|(i\\.e\\.)|(mr\\.)|(mrs\\.)|(ms\\.)|(dr\\.)|(prof\\.)|(esq\\.)|(sr\\.)|(jr\\.)[^" + characterRanges.latinLetters + "]", "ig"),
        innerWordPeriod: new RegExp("[" + characterRanges.latinLetters + "]\.[" + characterRanges.latinLetters + "]", "ig"),
    };

The first step is to define the UTF8 character ranges within which the letters used by all the Latin alphabet languages are contained. If that string looks like total gibberish to you, fear not: Character representation systems associate an ID with each of their displayable characters. RegEx simply allows us to define a range of ID’s (place a “-” between your first character’s ID and the last character’s ID). We take advantange of this by collating a bunch of ID ranges together in order to skip past ranges that contain characters that aren’t used in everyday language (e.g. emoticons, arrow symbols, etc.).

Once we know what all the acceptable characters are, we can use them to create RegEx queries:

The abbreviations RegEx looks for case-insensitive whitelisted abbreviations (e.g. Mr., Dr. Jr.) that are not immediately preceded by one of the accepted characters. In other words, it wants to find where these abbreviations are preceded by either nothing, a space, or a non-letter character. For example, we don’t want to match “ms.” in “grams.”, but we want to match “ms.” in “?Ms. Piggy”. Likewise, the RegEx query ensures that the abbreviation is also not immediately followed by a letter. For example, we don’t want to match “e.g.” in a corporation’s name abbreviation such as “E.G.G.S.”. But, we do want to match “e.g.” in “… farm animals, e.g. cows, bigs, etc.”

The inner-word period RegEx looks for any period that’s sandwiched immediately between a whitelisted Latin alphabet letters on either side. So, the period inside “Blast.js” successfully matches, but the period at the end of “This is is a short sentence.” successfully does not.

Deep dive: DOM traversal

This section is optional. This is a deep dive into how text node traversal works.

Let’s take a look at the recursive DOM traversal code:

if (node.nodeType === 1 && node.hasChildNodes()
    && !Reg.skippedElements.test(node.tagName)
    && !Reg.hasPluginClass.test(node.className)) {
    /* Note: We don't cache childNodes' length since it's a live nodeList (which changes dynamically with the use of splitText() above). */
    for (var i = 0; i < node.childNodes.length; i++) {
        Element.nodeBeginning = true;
 
        i += traverseDOM(node.childNodes[i], opts);
    }
}

Above, we check that the node…

  • Has a nodeType of 1 (which is the ID associated with an element node).
  • Has child nodes for us to crawl.
  • Is not one of the blacklisted element node tags (script, textarea, and select), which contain text nodes, but not that typical kind that users likely want to be blasted.
  • Isn’t already assigned the “blast” class, which Blast uses to keep track of which elements it’s currently being used on.

If the above conditions aren’t true and if the nodeType is instead returning a value of 3, then we know we’ve hit an actual text node. In this case, we proceed with submatch and element wrapping logic. Refer to the inlined comments for a thorough walkthrough:

/* Find what position in the text node that our
delimiter's RegEx returns a match. */
matchPosition = textNode.data.search(delimiterRegex);
 
/* If there's a RegEx match in this text node, proceed
   with element wrapping. */
if (matchPosition !== -1) {
    /* Return the match. */
    var match = node.data.match(delimiterRegex),
        /* Get the node's full text. */
        matchText = match[0],
        /* Get only the match's text. */
        subMatchText = match[1] || false;
 
    /* RegEx queries that can return empty strings (e.g ".*")
       produce an empty matchText which throws the entire
       traversal process into an infinite loop due to the
       position index not incrementing. Thus, we bump up
       the position index manually, resulting in a zero-width
       split at this location followed by the continuation
       of the traversal process. */
    if (matchText === "") {
        matchPosition++;
    /* If a RegEx submatch is produced that is not
       identical to the full string match, use the submatch's
       index position and text. This technique allows us to
       avoid writing multi-part RegEx queries for submatch finding. */
    } else if (subMatchText &amp;&amp; subMatchText !== matchText) {
        matchPosition += matchText.indexOf(subMatchText);
        matchText = subMatchText;
    }
 
    /* Split this text node into two separate nodes at the
       position of the match, returning the node that begins
       after the match position. */
    var middleBit = node.splitText(matchPosition);
 
    /* Split the newly-produced text node at the end of the
       match's text so that middleBit is a text node that
       consists solely of the matched text. The other
       newly-created text node, which begins at the end
       of the match's text, is what will be traversed in
       the subsequent loop (in order to find additional
       matches in the containing text node). */
    middleBit.splitText(matchText.length);
 
    /* Over-increment the loop counter so that we skip
       the extra node (middleBit) that we've just created
       (and already processed). */
    skipNodeBit = 1;
 
    /* Create the wrapped node. Note: wrapNode code
       is not shown, but it simply consists of creating
       a new element and assigning it an innerText value. */
    var wrappedNode = wrapNode(middleBit);
 
    /* Then replace the middleBit text node with its 
       wrapped version. */
    middleBit.parentNode.replaceChild(wrappedNode, middleBit);
}

This process isn’t tremendously performant when used on a large bodies of text with a delimiter that produces a lot of small matches (namely, the character delimiter), but it’s phenomenally robust and reliable.

Wrapping up

Go forth and blast shit up 😉 If you create something cool, please post it on CodePen and share it in the comments below.

Follow me on Twitter for tweets about UI manipulation.

View full post on Mozilla Hacks – the Web developer blog

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

Time to get hacking – Introducing Rec Room

It’s no secret that the best frameworks and tools are extracted, not created out of thin air. Since launching Firefox OS, Mozilla has been approached by countless app developers and web developers with a simple question: “How do I make apps for Firefox OS?” The answer: “It’s the web; use existing web technologies.” was—and still is—a good answer.

But if you don’t already have an existing toolchain as a web developer, I’ve been working on extracting something out of the way I’ve been creating web apps at Mozilla that you can use to write your next web app. From project creation to templating to deployment, Mozilla’s Rec Room will help you create awesome web apps in less time with more ease.

Rec Room is a Node.js utility belt you can wear to build client side web apps. It includes:

  • Brick to add components like appbars and buttons to your UI.
  • Ember for your app’s controllers, models, and views.
  • Handlebars to write your app’s templates.
  • Grunt to run the tasks for your app, including building for production.
  • I18n.js to localize your app.
  • Mocha to test your app.
  • Stylus to write your CSS.
  • Yeoman to scaffold new code for your app’s models and templates.

In this post I’ll walk through how to create a simple world clock web app with Rec Room, how to deploy it, and how you can try out Rec Room for yourself.

Where Does Rec Room Come From?

Much of Rec Room came from a recent rewrite of the HTML5 podcast app. I started working on this app well over a year ago, but its original version wasn’t as easy to work on; it had a lot of global state and a lot of by-hand data-binding. I liked the look of Ember for app development, but back when I started it didn’t quite feel mature enough. These days it’s much better, and I’ve tweaked it in Rec Room to work perfectly without a server.

I tried to take the best from that system and extract it into a set of tools and documentation that anyone can use.

Create your own Rec Room app

Rec Room has just recently been extracted from my experiences with Podcasts; it hasn’t been tested by more than a handful of developers. That said: we’d love your help trying to build your own app for Firefox OS using these tools. They integrate well with tools you probably already know and use–like Node.js and Firefox’s own Web IDE.

To get started, install Rec Room using Node.js:

npm install -g recroom

Clock App

We’ll create a simple clock app with (minimal) time zone support for our example. The app will let you have a clock and compare it with a few time zones.

The recroom binary is your entry point to all of the cool things Rec Room can do for you. First, create your app using recroom new world-clock. This creates the basic app structure. To see the basic app skeleton that Rec Room creates we can now enter that directory and run our app: cd world-clock and then type recroom run. The app will open in your default browser.

First, we’ll add the current time to the main tab. Rec Room supports Ember’s MVC app structure, but also offers simple “pages” for a controller without a 1:1 relationship to a model. We’ll generate a new page that will show our actual clock:

recroom generate page Clock

We can edit its template by opening app/templates/clock.hbs. Let’s change clock.hbs to include the variable that will output our local time:

<h2>Local Time: {{localTime}}</h2>

That won’t do much yet, so let’s add that variable to our ClockController, in app/scripts/controllers/clock_controller.js:

WorldClock.ClockController = Ember.ObjectController.extend({
    localTime: new Date().toLocaleTimeString()
});

You can see that any property inside the controller is accessible inside that controller’s template. We define the 1ocalTime property and it gets carried into our template context.

Now our clock app will show the current local time when we navigate to http://localhost:9000/#clock. Of course, it just shows the time it was when the controller was initialized; there is no live updating of the time. We should update the time every second inside the controller:

WorldClock.ClockController = Ember.ObjectController.extend({
    init: function() {
        // Update the time.
        this.updateTime();
 
    // Run other controller setup.
        this._super();
    },
 
    updateTime: function() {
        var _this = this;
 
        // Update the time every second.
        setTimeout(function() {
            _this.set('localTime', new Date().toLocaleTimeString());
            _this.updateTime();
        }, 1000);
    },
 
    localTime: new Date().toLocaleTimeString()
});

Now we can go to our clock URL and see our clock automatically updates every second. This is thanks to Ember’s data-binding between controllers and templates; if we change a value in a controller, model, or view that’s wired up to a template, the template will automatically change that data for us.

Adding Timezones

Next, we want to add a few timezones that the user can add to their own collection of timezones to compare against local time. This will help them schedule their meetings with friends in San Francisco, Buenos Aires, and London.

We can create a timezone model (and accompanying controllers/routes/templates) with the same generate command, but this time we’ll generate a model:

recroom generate model Timezone

We want each timezone we’re to include in our app to have a name and an offset value, so we should add them as model attributes. We use Ember Data for this, inside app/scripts/models/timezone_model.js:

WorldClock.Timezone = DS.Model.extend({
    name: DS.attr('string'),
    offset: DS.attr('number')
});

Next we’ll want a list of all timezones to offer the user. For this we’ll grab a copy of Moment Timezone. It’s an awesome JavaScript library for dealing with dates and times in JavaScript. We’ll install it with bower:

bower install moment-timezone --save

And then add it to our app inside app/index.html:

<!-- build:js(app) scripts/components.js -->
<!-- [Other script tags] -->
<script src="bower_components/moment/moment.js"></script>
<script src="bower_components/moment-timezone/builds/moment-timezone-with-data-2010-2020.js"></script>
<!-- endbuild -->

Adding that tag will automatically add moment-timezone-with-data-2010-2020.js to our built app. We’ll add a tab to the page that lets us edit our timezones, on a different screen than the clocks. To add a tab, we just need to open app/templates/application.hbs and add a tab. While we’re there, we’ll change the main tab from the useless {{#linkTo 'index'}} and point it to {{#linkTo 'clock'}}. The new application.hbs should look like this:

<x-layout>
  <header>
    <x-appbar>
      <h1>{{t app.title}}</h1>
    </x-appbar>
  </header>
  <section>
    {{outlet}}
  </section>
  <footer>
    <x-tabbar>
      <x-tabbar-tab>
        {{#link-to 'clock'}}Clock{{/link-to}}
      </x-tabbar-tab>
      <x-tabbar-tab>
        {{#link-to 'timezones'}}Timezones{{/link-to}}
      </x-tabbar-tab>
    </x-tabbar>
  </footer>
</x-layout>

Side note: notice the root URL points to a useless welcome page? We probably want the default route to be our ClockController, so we can set the index route to redirect to it. Let’s do that now, in app/scripts/routes/application_route.js:

WorldClock.ApplicationRoute = Ember.Route.extend({
    redirect: function() {
        this.transitionTo('clock');
    }
});

Interacting with Timezone models

We’ll keep things simple for our example and allow users to select a timezone from a <select> tag and add it with a button. It will show up in their list of timezones, and they can delete it if they want from there. The clock tab will show all times. First, we’ll add our timezone data from Moment.js into our TimezonesController in app/scripts/controllers/timezones_controller.js. We’re also going to implement two actions: “add” and “remove”. These will be used in our template:

WorldClock.TimezonesController = Ember.ObjectController.extend({
    init: function() {
        var timezones = [];
 
        for (var i in moment.tz._zones) {
          timezones.push({
              name: moment.tz._zones[i].name,
              offset: moment.tz._zones[i].offset[0]
          });
      }
 
      this.set('timezones', timezones);
 
      this._super();
  },
 
  selectedTimezone: null,
 
  actions: {
      add: function() {
          var timezone = this.store.createRecord('timezone', {
              name: this.get('selectedTimezone').name,
              offset: this.get('selectedTimezone').offset
          });
 
          timezone.save();
      },
 
      remove: function(timezone) {
          timezone.destroyRecord();
      }
  }
});

So we create a list of all available timezones with offsets. Then we add methods that allow us to add or remove timezones from our offline data store. Next we modify the timezones template in app/templates/timezones.hbs to use the actions and variables we created. All we need to utilize these variables is the Ember SelectView and the {{action}} helper to call our add and remove methods:

<h2>Add Timezone</h2>
 
<p>{{view Ember.Select content=timezones selection=selectedTimezone
       optionValuePath='content.offset' optionLabelPath='content.name'}}</p>
 
<p><button {{action add}}>Add Timezone</button></p>
 
<h2>My Timezones</h2>
 
<ul>
  {{#each model}}
    <li>{{name}} <button {{action remove this}}>Delete</button></li>
  {{/each}}
</ul>

Now we have a Timezones tab that allows us to add and remove Timezones we want to track. This data persists between app refreshes. The last thing we need to do is show these times relative to our local time in our clock tab. To do this we need to load all the Timezone models in the ClockRoute. They’re automatically loaded in the TimezonesRoute, but it’s easy to add them in the ClockRoute (in app/scripts/routes/clock_route.js):

WorldClock.ClockRoute = Ember.Route.extend({
    model: function() {
        return this.get('store').find('timezone');
    }
});

Because of the way our Ember app is wired up, we load all our models in the route and they are sent to the controller once the data store has asynchonously loaded all of the models. The request to find('timezone') actually returns a Promise object, but Ember’s router handles the Promise resolving for us automatically so we don’t have to manage callbacks or Promises ourselves.

Now we have access to all the user’s Timezones in the ClockController, so we can make times in each timezone the user has requested and show them in a list. First we’ll add each Timezone’s current time to our ClockController in app/scripts/controllers/clock_controller.js using Moment.js:

WorldClock.ClockController = Ember.ObjectController.extend({
    init: function() {
        // Update the time.
        this.updateTime();</p>
 
        // Run other controller setup.
        this._super();
    },
 
    updateTime: function() {
        var _this = this;
 
        // Update the time every second.
        setTimeout(function() {
            _this.set('localTime', moment().format('h:mm:ss a'));
 
            _this.get('model').forEach(function(model) {
                model.set('time',
                          moment().tz(model.get('name')).format('h:mm:ss a'));
            });
 
            _this.updateTime();
        }, 1000);
    },
 
    localTime: moment().format('h:mm:ss a')
});

Our final app/templates/clock.hbs should look like this:

<h2>Local Time: {{localTime}}</h2>
 
<p>{{#each model}}
  <h3>{{name}}: {{time}}</h3>
{{/each}}

And that’s it! Now we have an offline app that shows us time zones in various places, saves the data offline, and updates every second without us having to do much work!

Command Line Tools

The old Podcasts app used a (rather awful) Makefile. It wasn’t very useful, and I don’t think it ran on Windows without some serious effort. The new build system uses Node so it runs comfortably on Windows, Mac, and Linux. Commands are proxied via the recroom binary, also written in Node, so you don’t have to worry about the underlying system if you don’t need to modify build steps. recroom new my-app creates a new app; recroom serve serves up your new app, and recroom generate model Podcast creates a new model for you.

To build your app, you just need to run recroom build and a version with minified CSS, JS, and even HTML will be created for you in the dist/ folder. This version is ready to be packaged into a packaged app or uploaded to a server as a hosted app. You can even run recroom deploy to deploy directory to your git repository’s GitHub pages branch, if applicable.

See the app in action!

This entire sample app is available at worldclock.tofumatt.com and the source code is available on GitHub.

Try Using Rec Room for Your Next Web App

You can try out Rec Room on Github. Right now some docs and tools are still being abstracted and built, but you can start building apps today using it and filing bugs for missing features. We’d really love it if you could give it a try and let us know what’s missing. Together we can build a cohesive and polished solution to the all-too-common question: “How do I build a web app?”

View full post on Mozilla Hacks – the Web developer blog

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

Introducing the Web Audio Editor in Firefox Developer Tools

In Firefox 32, the Web Audio Editor joins the Shader Editor and Canvas Debugger in Firefox Developer Tools for debugging media-rich content on the web. When developing HTML5 games or fun synthesizers using web audio, the Web Audio Editor assists in visualizing and modifying all of the audio nodes within the web audio AudioContext.

Visualizing the Audio Context

When working with the Web Audio API‘s modular routing, it can be difficult to translate how all of the audio nodes are connected just by listening to the audio output. Often, it is challenging to debug our AudioContext just by listening to the output and looking at the imperative code that creates audio nodes. With the Web Audio Editor, all of the AudioNodes are rendered in a directed graph, illustrating the hierarchy and connections of all audio nodes. With the rendered graph, a developer can ensure that all of the nodes are connected in a way that they expect. This can be especially useful when the context becomes complex, with a network of nodes dedicated to manipulating audio and another for analyzing the data, and we’ve seen some pretty impressive uses of Web Audio resulting in such graphs!

To enable the Web Audio Editor, open up the options in the Developer Tools, and check the “Web Audio Editor” option. Once enabled, open up the tool and reload the page so that all web audio activity can be monitored by the tool. When new audio nodes are created, or when nodes are connected and disconnected from one another, the graph will update with the latest representation of the context.

Modifying AudioNode Properties

Once the graph is rendered, individual audio nodes can be inspected. Clicking on an AudioNode in the graph opens up the audio node inspector where AudioParam‘s and specific properties on the node can be viewed and modified.

Future Work

This is just our first shippable release of the Web Audio Editor, and we are looking forward to making this tool more powerful for all of our audio developers.

  • Visual feedback for nodes that are playing, and time/frequency domain visualizations.
  • Ability to create, connect and disconnect audio nodes from the editor.
  • Tools for debugging onaudioprocess events and audio glitches.
  • Display additional AudioContext information and support multiple contexts.
  • Modify more than just primitives in the node inspector, like adding an AudioBuffer.

We have many dream features and ideas that we’re excited about, and you can view all open bugs for the Web Audio Editor or submit new bugs. Be sure to check out the MDN documentation on the Web Audio Editor and we would also love feedback and thoughts at our UserVoice feedback channel and on Twitter @firefoxdevtools.

View full post on Mozilla Hacks – the Web developer blog

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

Introducing webcompat.com

For the past few months a small group of contributors inside and outside of Mozilla have been working on webcompat.com. We just recently celebrated moving past the “too broken to share” milestone to the “functional-under-construction.gif” milestone of the project and are eager to share what we’ve been up to.

There’s a more elaborate description of web compatibility and the site over at http://webcompat.com/about, but the basic premise of this project is: what if you could “file a bug on the internet” in a public space where developers, users and browser vendors could be made aware of compatibility issues?

You can report issues to browser vendors today, through bug trackers or other feedback mechanisms, some public and some not. But frequently you cannot see the results of such a report—or see what related issues others have reported. It can feel like a black hole experience.

This is where webcompat.com comes in. We want to provide a simple, open interface to web compatibility issues that affect us all as users of the web, regardless of our browsers or devices of choice. Perhaps more importantly, we hope to foster and enable a community of people who are passionate about a web for everyone to help out.

So is this a Mozilla-only effort?

Not at all. Mozilla kindly allows me to work on this project as a part of my full-time responsibilities on the Mozilla Mobile Web Compatibility team—but the project’s goal has always been to create an open resource for all people who use and build things on the internet. We’ve had some positive conversations with some of our browser vendor colleagues that have motivated us to start initial plans around future collaborations. It’s clear to us that Mozilla isn’t the only entity invested in a compatible web.

OK Neat. What can I do?

There’s actually quite a bit to do if this type of work is interesting to you.

Reporting Issues

Do you happen to notice sites that block you, nag you to install a different browser, or are just plain broken or buggy? Instead of just tweeting sad emoticons or #fail hashtags, you can help make a difference by creating a record of these issues with the form at webcompat.com.

We’ve also created some browser extensions to make reporting easier—just click the added UI button to open a new tab with some bug report info pre-filled for you. You can grab that for Firefox Desktop, Firefox for Android, Chrome, Opera, and Safari. There’s also a bookmarklet you can install in your bookmark or favorites bar. These are all open source, so feel free to hack away and port them to new platforms.

Diagnosing Compatibility Issues

Do you have a knack for figuring out why things are broken and want to hone your internet CSI skills? Have you considered getting a “TypeError: ‘undefined’ is not a function” tattoo? Do you love reading minified code and debugging the entire web stack? We could use your help confirming and diagnosing issues (tattoos not required).

Site Outreach

Are you more interested in doing outreach and making sites and developers aware of issues? We need your help too. Stay tuned for better tooling around this role—or hop into the #webcompat irc channel on the Mozilla IRC network and say hi.

Development

Do you know or want to get better at JavaScript, Python, CSS, UX, design, GitHub, browser extensions, testing, and more? We’ve got a pile of issues we’re working on over at GitHub and welcome patches, opinions, issues, and feedback.

What’s coming next?

Right now two of our biggest priorities are being able to view and interact with issues in the site itself, and creating tools that will enable importing existing web compatibility issues from bug trackers (both open and closed) and exporting compatibility issues on webcompat.com to browser vendors (when the bug lies with the browser, not the site).

Our project is still in its infancy, but we look forward to your compatibility bug reports and comments!

View full post on Mozilla Hacks – the Web developer blog

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

Introducing TranslationTester and localization support for Open Web Apps

When building Open Web Apps, one important factor is to make your content available to as many possible, and one way to do that is to make it available in more than one language. Therefore we want to make it as easy as possible for you, both with a complete code repository to get started and updated documentation and possibilities to get translations for your apps.

We are now also offering a way to have your app set up and to get connected to localizers directly!

Presenting TranslationTester

Based on the great work and content by Jason in Localizing Firefox OS Apps and Christie in Localizing the Firefox OS Boilerplate App, I’ve been working on simplifying the set-up for localization.

Above articles describe many facets and possibilities available, and to complement that, I wanted to be able to offer the most basic code and structure for most use cases: basically, just add translations and you’re good to go!

This lead to the creation of the TranslationTester code repository, available on GitHub.

From no translation to localized app in less than 4 minutes!

Based on the TranslationTester, Will Bamberg has put together a nice and short screencast showing the exact process of going from no translations to having support in just a few minutes!

In the app-l10n-example repository you have versions of the before and after stages in this screencast, and all of the localization process is described on MDN.

How to localize an app

These are the things needed to localize an app. All of them are included in the TranslationTester repository, but included here to show easy it is to get started, or continue to build on the TranslationTester platform for your app.

Mark up the HTML

For any element that you want to have its text localized, add a data-l10n-id attribute to the desired element. For example:

<p data-l10n-id="winter-for-real">Winter for real</p>

Create translations

In the locales directory, you have a directory for each language, and can just add new ones for new languages. In each language directoy you create an app.properties file which will contain all your translations for that language (optionally you can also create a manifest.properties file for the name and description of the app, unless you edit it in the main manifest.webapp for your app).

Include l10n.js

By including the l10n.js file, the translations for respective language’s app.properties file will be applied to element with the corresponding data-l10n-id attribute.

Add “name” and “description” translations

The translations for the name and description for your app could be added to the main manifest.webapp file, or in an optional manifest.properties under each locale’s directory.

How to view different locales

To view your app with a different locale, change the language in Firefox/App Manager:

All platforms
Set the desired locale to test in JavaScript, e.g:

document.webL10n.setLanguage("es");
App Manager/Firefox OS
Language setting in the Settings app
Firefox
Choose language under Preferences > Content > Languages. More information in Set content language in Firefox

Get help with translations

We have a Mozilla localization app pilot offered through the Transifex service. As part of that, we’re offering you to add your apps as part of this pilot, to be connected to localizers and quickly offer your app in more languages, to more people.

Please apply in the Localize My Firefox App form to get started!

View full post on Mozilla Hacks – the Web developer blog

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

Introducing PredictionIO

PredictionIO is an open source machine learning server for software developers to create predictive features, such as personalization, recommendation and content discovery. Building a production-grade engine to predict users’ preferences and personalize content for them used to be time-consuming. Not anymore with PredictionIO’s latest v0.7 release.

We are going to show you how PredictionIO streamlines the data process and make it friendly for developers and production deployment. A movie recommendation case will be used for illustration purpose. We want to offer “Top 10 Personalized Movie Recommendation” for each user. In addition, we also offer “If you like this movie, you may also like these 10 other movies….”.

Prerequisite

First, let’s explain a few terms we use in PredictionIO.

Apps

Apps in PredictionIO are not apps with program code. Instead, they correspond to the software application that is using PredictionIO. Apps can be treated as a logical separation between different sets of data. An App can have many Engines, but each Engine can only be associated with one App.

Engines

Engines are logical identities that an external application can interact with via the API. There are two types of Engines as of writing: item-recommendation, and item-similarity. Each Engine provide unique settings to meet different needs. An Engine may have only one deployed Algorithm at any time.

Algorithms

Algorithms are actual computation code that generates prediction models. Each Engine comes with a default, general purpose Algorithm. If you have any specific needs, you can swap the Algorithm with another one, and even fine tune its parameters.

Getting Hands-on

Preparing the Environment

Assuming a recent 64-bit Ubuntu Linux is installed, the first step is to install Java 7 and MongoDB. Java 7 can be installed by sudo apt-get install openjdk-7-jdk. MongoDB can be installed by following the steps described in Install MongoDB on Ubuntu.

Note: any recent 64-bit Linux should work. Distributions such as ArchLinux, CentOS, Debian, Fedora, Gentoo, Slackware, etc should all work fine with PredictionIO. Mac OS X is also supported.

Java 7 is required to run PredictionIO and its component Apache Hadoop. Apache Hadoop is optional since PredictionIO 0.7.0.

MongoDB 2.4.x is required for PredictionIO to read and write behavioral data and prediction model respectively.

Installing PredictionIO and its Components

To install PredictionIO, simply download a binary distribution and extract it. In this article, we assume that PredictionIO 0.7.0 has been installed at /opt/PredictionIO-0.7.0. When relative paths are used later in this article, they will be relative to this installation path unless otherwise stated.

The installation procedure is outlined in Installing PredictionIO on Linux.

To start and stop PredictionIO, you can use bin/start-all.sh and bin/stop-all.sh respectively.

Fine Tuning Apache Hadoop (Optional)

PredictionIO relies on Apache Hadoop for distributed data processing and storage. It is installed at vendors/hadoop-1.2.1. The following outlines some optimization opportunities.

vendors/hadoop-1.2.1/conf/hdfs-site.xml

dfs.name.dir and dfs.data.dir can be set to point at a big and persistent storage. Default values usually point at a temporary storage (usually /tmp), which could be pruned by the OS periodically.

vendors/hadoop-1.2.1/conf/mapred-site.xml

mapred.tasktracker.map.tasks.maximum and mapred.tasktracker.reduce.tasks.maximum control the maximum number of mapper and reducer jobs (data processing jobs). It is a good start to set the first value to be the number of CPU cores, and the second value to be half the first value. These should be reduced slightly to provide margin when you serve prediction in production settings if you do not run Hadoop on a separate machine.

mapred.child.java.opts controls the Java Virtual Machine options for each mapper and reducer job. It usually is a good idea to reserve a good amount of memory even when all mapper and reducer jobs are running. If you have a maximum of 4 mappers and 2 reducers, a 1GB heap space (-Xmx1g) for each of them (a total of 6GB max) would be reasonable if your machine has more than 10GB of RAM.

io.sort.mb controls the size of the internal sort buffer and is usually set to half of the child’s heap space. If you have set to 1GB above, this could be set to 512MB.

Creating an App in PredictionIO

This can be done by logging in PredictionIO’s web UI located at port 9000 on the server.

The following is the first screen after logging in and clicking on the “Add an App” button. To add an app, simply input the app’s name and click “Add”.

Importing Data to PredictionIO

Before importing data, the app key of the target app must be obtained. This was done by clicking on “Develop” next to an app. The screen below is what can be seen afterwards.

The app key for the “ml100k” app is NO5FpSnGh1F3PUi7xiSGc910q63z6rxZ4BcYe039Jjf2sTrqyjOc1PmQ3MJowNwM, as shown above. The app key is unique and your app key should be different.

To parse the MovieLens 100k data set and import to PredictionIO, one can use the import_ml.rb Gist. It requires the PredictionIO Ruby gem, which can be installed by sudo gem install predictionio.

Importing the whole set of data is simple:

ruby import_ml.rb NO5FpSnGh1F3PUi7xiSGc910q63z6rxZ4BcYe039Jjf2sTrqyjOc1PmQ3MJowNwM u.data

u.data is a file from the MovieLens 100k data set, which can be obtained from the GroupLens web site.

Adding Engines

Two engines can be added by simply clicking on the “Add an Engine” button. In our case, we have added “itemrec” and “itemsim” engines. Once they are added, they will commence training automatically with a default hourly schedule.

Getting Prediction Results

At the moment, you may access prediction results from these two sample URLs (API server at port 8000):

“Top 10 Personalized Movie Recommendation”:

http://localhost:8000/engines/itemrec/itemrec/topn.json?pio_appkey=NO5FpSnGh1F3PUi7xiSGc910q63z6rxZ4BcYe039Jjf2sTrqyjOc1PmQ3MJowNwM&pio_n=10&pio_uid=1

“If you like this movie, you may also like these 10 other movies….”:

http://localhost:8000/engines/itemsim/itemsim/topn.json?pio_appkey=NO5FpSnGh1F3PUi7xiSGc910q63z6rxZ4BcYe039Jjf2sTrqyjOc1PmQ3MJowNwM&pio_n=10&pio_iid=1

You may change the pio_uid and pio_iid parameters above to see results for other users/items. You are encouraged to take advantage of these endpoints to verify these results. You can also take advantage of our official and community-powered SDKs to simplify this process. Contributed SDKs are also available.

What’s News in PredictionIO v0.7

With the new extended support to GraphChi – a disk-based large-scale graph computation framework, developers can now evaluate and deploy algorithms in both GraphChi and Apache Mahout on one single platform!

Enjoy!

View full post on Mozilla Hacks – the Web developer blog

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

Introducing the getBoxQuads API

Web developers often need to determine where an element has been placed in the page, or more generally, where it is relative to another element. Existing APIs for doing this have significant limitations. The new GeometryUtils interface and its supporting interfaces DOMPoint, DOMRect and DOMQuad provide Web-standard APIs to address these problems. Firefox is the first browser to implement these APIs; they are available in Firefox 31 Nightly builds.

Current best standardized APIs for retrieving element geometry

Currently the best standardized DOM APIs for retrieving element geometry are element.getBoundingClientRect() and element.getClientRects(). These return the border-box rectangle(s) for an element relative to the viewport of the containing document. These APIs are supported cross-browser but have several limitations:

  • When complex CSS transforms are present, they return the smallest axis-aligned rectangle enclosing the transformed border-box. This loses information.
  • There is no way to obtain the coordinates of the content-box, padding-box or border-box. In simple cases you can add or subtract computed style values from the results of getBoundingClientRect()/getClientRects() but this is clumsy and difficult to get right. For example, when a <span> breaks into several fragments, its left border is only added to one of the fragments — either the first or the last, depending on the directionality of the text.
  • There is no way to obtain box geometry relative to another element.

Introducing getBoxQuads()

The GeometryUtils.getBoxQuads() method, implemented on Document, Element and TextNode, solves these problems. It returns a list of DOMQuads, one for each CSS fragment of the object (normally this list would just have a single
DOMQuad).

Example:

<div id="d" 
  style="position:absolute; left:100px; top:100px; width:100px; height:100px;">
</div>
var quads = d.getBoxQuads();
// quads.length == 1
// quads[0].p1.x == 100
// quads[0].p1.y == 100
// quads[0].p3.x == 200
// quads[0].p3.y == 200
p1
p2
p3
p4

Using bounds

A DOMQuad is a collection of four DOMPoints defining the corners of an arbitrary quadrilateral. Returning DOMQuads lets getBoxQuads() return accurate information even when arbitrary 2D or 3D transforms are present. It has a handy bounds attribute returning a DOMRectReadOnly for those cases where you just want an axis-aligned bounding rectangle.

For example:

<div id="d" 
  style="transform:rotate(45deg); position:absolute; left:100px; top:100px; width:100px; height:100px;">
</div>
var quads = d.getBoxQuads();
// quads[0].p1.x == 150
// quads[0].p1.y == 150 - 50*sqrt(2) (approx)
// quads[0].p3.x == 150
// quads[0].p3.y == 150 + 50*sqrt(2) (approx)
// quads[0].bounds.width == 100*sqrt(2) (approx)
p1
p2
p3
p4
bounds

Passing in options

By default getBoxQuads() returns border-boxes relative to the node’s document viewport, but this can be customized by passing in an optional
options dictionary with the following (optional) members:

  • box: one of "content", "padding", "border" or "margin", selecting which CSS box type to return.
  • relativeTo: a Document, Element or TextNode; getBoxQuads() returns coordinates relative to the top-left of the border-box of that node (the border-box of the first fragment, if there’s more than one fragment). For documents, the origin of the document’s viewport is used.

Example:

<div id="d" 
  style="position:absolute; left:100px; top:100px; width:150px; height:150px;">
    <div id="e" 
      style="position:absolute; padding:20px; left:0; top:0; width:100px; height:100px;">
    </div>
</div>
var quads = e.getBoxQuads({relativeTo:d});
// quads[0].p1.x == 0
// quads[0].p1.y == 0
quads = e.getBoxQuads({relativeTo:d, box:"content"});
// quads[0].p1.x == 20
// quads[0].p1.y == 20
d
e content-box
e border-box

The relativeTo node need not be an ancestor of the node receiving getBoxQuads(). The nodes can even be in different documents, although they must be in the same toplevel browsing context (i.e. browser tab).

Scratching the surface

If you’ve read this far, you’re probably observant enough to have noticed additional methods in GeometryUtils — methods for coordinate conversion. These will be covered in a future blog post.

View full post on Mozilla Hacks – the Web developer blog

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)