What’s

What’s happening with WCAG

I had the opportunity to speak with Glenda Sims (Deque) about all the activities happening with WCAG (Web Content Accessibility Guidelines) these days. In this 5 minute overview, she discusses those aspects important to web professionals everywhere. The full 22 minute discussion is available to our members (once you login, scroll down to find the link).

In a nutshell, there is a great need for those who have a solid background in making sites accessible. The demand far exceeds the available work force.

During our discussion, Glenda mentioned these resources. Interested parties may wish to check them further.

Best always,

Mark DuBois

Community Evangelist and Executive Director

The post What’s happening with WCAG appeared first on Web Professionals.

View full post on Web Professional Minute

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

What’s new in IndexedDB 2.0?

The draft of Indexed Database API 2.0 is almost complete, providing several new APIs for fine-grained access to IndexedDB.

The good news is that all these new APIs are implemented in Firefox and will be available in the release of Firefox 51 (currently available in Developer Edition, scheduled for general release in January 2017). In this article, we will share some examples of how to use these APIs to access IndexedDB in a better way.

Setters to IDBObjectStore.name and IDBIndex.name

In the previous version of the Indexed Database API, IndexedDB allowed developers to upgrade the schema of the indexedDB by adding/deleting object stores and indexes; but renaming existing object stores and indexes was not possible.

This made it impossible to properly name the index and object store, when the original name no longer accurately represented the new schema of the objects to be stored. In addition, it was a waste of time to move objects into a new object store just for renaming.

For example, let’s say there is an object store called “text messages,” to store plain text messages sent or received on a mobile network. Later, suppose the developer would like to provide richer content messages, that include attachments such as images, audio, and video —it would be better to give this object store a more generic name such as “mobile messages.” Additionally, imagine that there is an index in this object store named “recipient,” which represents the recipient address of a message, and now, the developer would like to support multiple recipients for messaging. Then, it would be nice to have this index renamed as “recipients” (plural).

let request = indexedDB.open("messageDB", 2);
request.onupgradeneeded = (event) => {
  let txn = event.target.transaction;
  let store = txn.objectStore("text messages");

  store.name = "mobile messages";
  let index = store.index("recipient");
  index.name = "recipients";
};

IDBDatabase.onclose()

A new onclose event handler is defined in the IDBDatabase interface to allow the developer to listen to the storage change of the indexedDB outside the scripts. Taking the Firefox browser as an example, the browser allows the user to clean up the storage used by a single site. With this handler, scripts can be notified that the database was closed forcibly outside the scripts to provide more responsive information or as a warning to the user.

let request = indexedDB.open("bookstore");
request.onsuccess = (event) => {
  let db = event.target.result;

  db.onclose = (event) => {
    alert("the database: " + db.name + "was closed outside the script!");
  };
};

Binary Key Indexing

Binary data types can be treated as indexed keys in the 2.0 implementation. More precisely, any properties of the stored object presented by Arraybuffer, typed array objects, and DataView can now be indexed. This benefits developers: now you can have binary signatures as keys directly, without serializing them into strings or array objects as required by the previous API version.

IDBTransaction.objectStoreNames[]

This handy new property gives developers an easier way to determine which object stores are involved in the current transaction:

let request = indexedDB.open("bookstore", 2);
request.onupgradeneeded = (event) => {
  let txn = event.target.transaction; // txn.mode == "versionchange"
  txn.objectStoreNames; // a list of objectstore names can be accessed in this txn.
};

IDBObjectStore.getKey(query)

getKey(query) is now provided in IDBObjectStore for performance reasons and the symmetry with IDBIndex. With this new API, you don’t have to adopt heuristics to check if an object key in a specific range is available in the store. For example, openCursor(query) might be an alternative approach, but you’ll still have the overhead cost of cursor creation and the serialization/deserialization of the object.

Let’s assume that there is an object store for the logging of the network activities and the timestamps are chosen as the object keys. Now, we’d like to know when the first activity occurred in the last 24 hours:

let openRequest = indexedDB.open("telemetry");
openRequest.onsuccess = (event) => {
  let db = event.target.result;
  let store = db.transaction("netlogs").objectStore("netlogs");

  let today = new Date();
  let yesterday = new Date(today);
  yesterday.setDate(today.getDate() - 1);
  let request = store.getKey(IDBKeyRange(yesterday, today));
  request.onsuccess = (event) => {
    let when = event.target.result;
    alert("The 1st activity in last 24 hours was occurred at " + when);
  };
};

IDBObjectStore.openKeyCursor(range, direction)

As a lightweight version of openCursor() in IDBObjectStore, openKeyCursor() allows you to iterate object keys in a specified range without retrieving the entire object from the database. This reduces the overhead of serialization.

Let’s continue the previous example to retrieve the timestamps of the network activities that occurred in the last 24 hours:

let openRequest = indexedDB.open("telemetry");
openRequest.onsuccess = (event) => {
  let db = event.target.result;
  let store = db.transaction("netlogs").objectStore("netlogs");

  let today = new Date();
  let yesterday = new Date(today);
  yesterday.setDate(today.getDate() - 1);
  let request = store.openKeyCursor(IDBKeyRange(yesterday, today));
  let timestamps = [];
  request.onsuccess = (event) => {
    let cursor = event.target.result;
    if (!cursor) { return; }
    timestamps.push(cursor.key);
    cursor.continue();
  };
};

getAll/getAllKeys(range, count) from IDBObjectStore and IDBIndex

Instead of retrieving data one by one by iterating the cursor, getAll() and getAllKeys() allow us to retrieve all the data at once in ascending order from an IDBObjectStore or an IDBIndex. You can specify optional range and count to limit the number of results in the response. It’s very useful when the total size of data to be retrieved is not huge.

For example, if you would like to retrieve the first ten activities in the last 24 hours at once:

let openRequest = indexedDB.open("telemetry");
openRequest.onsuccess = (event) => {
  let db = event.target.result;
  let store = db.transaction("netlogs").objectStore("netlogs");

  let today = new Date();
  let yesterday = new Date(today);
  yesterday.setDate(today.getDate() - 1);
  let activities = null;
  let request = store.getAll(IDBKeyRange(yesterday, today), 10);
  request.onsuccess = (event) => {
    activities = event.target.result;
  };
};

Note: This is less useful if you want to retrieve data at once in descending order when count is specified.

IDBCursor.continuePrimaryKey(key, primaryKey)

In the design of IndexedDB, records in an IDBIndex tree are stored in ascending order of the index key followed by ascending order of the object key. With the help of continuePrimaryKey() to an opened IDBCursor of an IDBIndex, developers can immediately resume the iteration of a cursor that was closed in a previous iteration. You simply specify the index key and primary key recorded previously, instead of starting the iteration from the beginning and comparing the primary keys one by one.

For example, here’s how you can resume an iteration of all articles tagged with “javascript” since your last visit:

let request = articleStore.index("tag").openCursor();
let count = 0;
let unreadList = [];
request.onsuccess = (event) => {
    let cursor = event.target.result;
    if (!cursor) { return; }
    let lastPrimaryKey = getLastIteratedArticleId();
    if (lastPrimaryKey > cursor.primaryKey) {
      cursor.continuePrimaryKey("javascript", lastPrimaryKey);
      return;
    }
    // update lastIteratedArticleId
    setLastIteratedArticleId(cursor.primaryKey);
    // preload 5 articles into the unread list;
    unreadList.push(cursor.value);
    if (++count < 5) {
      cursor.continue();
    }
};

IDBKeyRange.includes(key)

This is a new helper function to check if a key is in the scope of an IDBKeyRange:

let openRange = IDBKeyRange.bound(5, 10, true, true);
openRange.includes(5);  // false;
openRange.includes(10); // false;
openRange.includes(7);  // true;

With the 2.0 changes and updates, it’s possible to accomplish entirely new things with IndexedDB. See where these new capabilities take you and let us know how it goes.

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)

What’s new in Web Audio?

The Web Audio API is still under development, which means there are new methods and properties being added, renamed, shuffled around or simply removed!

In this article, we look at what’s happened since our last update in early 2015, both in the Web Audio specification and in Firefox’s implementation. The demos all work in Firefox Nightly, but some of the latest changes might not be present in Firefox release or Developer Edition yet.

API changes

Breaking change

The reduction attribute in DynamicsCompressorNode is now a float instead of an AudioParam. You can read the value with compressor.reduction instead of compressor.reduction.value.

This value shows the amount of gain reduction that the compressor is applying to the signal, and it had been read-only anyway, so it makes sense to have it as a float and not an AudioParam (since no changes can be scheduled).

To detect whether the browser your code is running on supports the AudioParam or float data type, you can check for the existence of the .value attribute on reduction:

if(compressor.reduction.value !== undefined) {
  // old style
} else {
  // new style
}

Take a look at this example where the reduction attribute is accessed while a drum loop is playing. Notice how the value changes to react to the loudness in the track, and how we’re detecting which API version the browser supports before reading the attribute value.

New properties and methods

New life cycle management methods in AudioContext

With AudioContexts being rather expensive, three new methods have been added: suspend(), resume() and close().

These allow developers to suspend the processing for some time until it is needed again, and to free some resources with close() when the AudioContext isn’t required anymore.

Essentially, when an AudioContext is suspended, no sounds will be played, and when it resumes, it will continue playing where it left off. The description for suspend() in the specification has all the details.

This example demonstrates the usage of these methods.

Precise AudioNode disconnect() methods

In the past, you could not disconnect nodes selectively: if you ran disconnect() on a given node, it would disconnect it from all other nodes.

Thankfully, the disconnect() method can now be overloaded to increase the type of disconnections you can perform:

  • disconnect() – disconnects a node from every node (this is the existing function)
  • disconnect(outputNumber) – disconnects all connections from the node’s outputNumber channel
  • disconnect(anotherNode) – disconnects all connections to anotherNode
  • disconnect(anotherNode, outputNumber) – disconnects all connections from outputNumber channel from node anotherNode
  • disconnect(anotherNode, outputNumber, inputNumber) – disconnects connections to anotherNode from outputNumber into inputNumber channels
  • disconnect(audioParam) – disconnects connections from this node to audioParam
  • disconnect(audioParam, outputNumber) – disconnects connections from this node’s outputNumber channel to audioParam

I strongly recommend you read the specification for AudioNode to understand all the details on the effects of these disconnections. You can also read the original discussion to find out about the motivation for this change.

New length attribute in OfflineAudioContext

This new attribute reflects the value that was passed to the constructor when the OfflineAudioContext was initialised, so developers don’t have to keep track of it on a separate variable:

var oac = new OfflineAudioContext(1, 1000, 44100);
console.log(oac.length);
>> 1000

Here’s an example that demonstrates using that attribute and also rendering a sound wave with a gain envelope.

New detune attribute in AudioBufferSourceNode

This is similar to the detune attribute in OscillatorNodes, but can now be used for fine-tuning samples with more accuracy than just using the existing playbackRate property.

New AudioParam-typed position and orientation attributes in PannerNode

These new attributes are AudioParams, which means you can use automation to modify them instead of continuously calling the setPosition() or setOrientation() methods in a loop.

The StereoPannerNode pan attribute was already an AudioParam, so all the nodes that let you pan sounds in space also allow you to automate their spatial properties. Great stuff for modular synthesis!

That said, we still lack the ability to automate the position and orientation properties in AudioListener, which means that if you want to update these periodically you have to use setPosition() and setOrientation() methods on the AudioListener for now. (Bug #1283029 tracks this).

Passing values to set initial parameters for PeriodicWave instances

You can now pass an options object when creating instances of PeriodicWave:

var wave = audioContext.createPeriodicWave(real, imag, { disableNormalization: false });

Compare with the previous syntax:

var wave = audioContext.createPeriodicWave(real, imag);
wave.disableNormalization = false;

In the future, all node creation methods will allow developers to pass objects to set their initial parameters, and will also be constructible, so we’ll be able to do things such as new GainNode(anAudioContext, {gain: 0.5});. This will make Web Audio code way more succinct than it actually can be when it comes to initialising nodes. Less code to maintain is always good news!

New node: IIRFilterNode

Building an IIRFilter with Digital Filter Design

If BiquadFilterNode is not enough for your needs, IIRFilterNode will allow you to build your own custom filter.

You can create instances calling the createIIRFilter() function on an AudioContext, and passing in two arrays of coefficients representing the feedforward and feedback values that define the filter:

var customFilter = audioContext.createIIRFilter([ 0.1, 0.2, ...], [0.4, 0.3, ...]);

This type of filter node is not automatable, which means that once created, you cannot change its parameters. If you want to use automation, you’ll have to keep using the existing BiquadFilter nodes, and alter their Q, detune, frequency and gain attributes which are all AudioParams.

The spec has more data on these differences, and you can use the Digital Filter Design resource to design and visualise filters and get ready-to-use Web Audio code with prepopulated feedforward and feedback arrays.

Chaining methods

Some more “syntactic sugar” to improve developers’ ergonomics:

The connect() methods return the node they connect to, so you can chain multiple nodes faster. Compare:

Before:

node0.connect(node1);
node1.connect(node2);
node2.connect(node3);

After:

node0.connect(node1).connect(node2).connect(node3);

And the AudioParam automation methods can be chained as well, as each method returns the object it was called on. For example, you could use it to define envelopes faster:

Before:

gain.setValueAtTime(0, ac.currentTime);
gain.linearRampToValueAtTime(1, ac.currentTime + attackTime);

After:

gain.setValueAtTime(0, ac.currentTime)
  .linearRampToValueAtTime(1, ac.currentTime + attackTime);

Coming up in the future

The Web Audio Working Group is almost finished writing the specification for AudioWorklets, which is the new name for AudioWorkers. These will replace the ScriptProcessorNode, which also lets you write your own nodes, but runs on the UI thread, so it’s not the best idea performance-wise.

The pull request defining AudioWorklets and associated objects on the specification must be merged first, and once that’s done vendors can start implementing support for AudioWorklets on their browsers.

Firefox changes: performance and debugging improvements

Three hard-working engineers (Karl Tomlinson, Daniel Minor and Paul Adenot) spent at least six months improving the performance of Web Audio in Firefox. What this means, in practical terms, is that audio code now takes less time to run and it’s faster than or as fast as Chrome is. The only exception is when working with AudioParams, where Firefox performance is not as good… yet.

Similarly, ScriptProcessorNodes are now less prone to introduce delay if the main thread is very busy. This is great for applications such as console emulators: low latency means a more faithful emulation, which in turns makes for lots of fun playing games!

Going even deeper, assembly level optimisations for computing DSP kernels have been introduced. These take advantage of SIMD instructions on ARM and x86 to compute multiple values in parallel, for simple features such as panning, adjusting gain, etc. This means faster and more efficient code, which uses less battery—especially important on mobile devices.

Additionally, cross-origin errors involving MediaElement nodes will now be reported to the developer tools console, instead of silently failing. This will help developers identify the exact issue, instead of wondering why are they getting only silence.

There were many more fixed bugs—probably too many to list here! But have a look at the bug list if you’re really curious.

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)

What’s new in Cordova 3.5.0 for Firefox OS

The Cordova community recently released version 3.5.0 of the tools. This version includes some exciting improvements to the Firefox OS development workflow. Before we dive into the new features, make sure you have the latest version by running:

$ sudo npm install -g cordova
$ sudo npm install -g plugman

Now that we’re all set up, let’s dive into the new features.

Improved manifest management

In previous versions of Cordova, developers had to manually edit the manifest.webapp file to add permissions and other app information. This file has crucial information that Firefox OS needs to interact with your app.

Cordova has a configuration file called config.xml that already contains the same information needed for the manifest file. Cordova will create and update the manifest based on your config.xml file. In the new version, plugins can add configuration specifying which permissions are necessary. Whenever you run a cordova prepare, the manifest is updated based on your configuration. Now you can have all your app’s information in one place.

Building packages with Cordova

Firefox OS uses web technologies that do not require a compilation step to generate binaries. The related Cordova commands build and compile were left unimplemented and would throw an exception when called. That behavior was confusing and left some people wondering what went wrong.

Now cordova build or Cordova compile will create a zip of your packaged app in the build folder inside the platform/firefoxos folder. A big thank you to the contributor Gert-Jan Braas for implementing this!

Plugins

A fresh batch of core plugins were released too. We added Firefox OS support to a few more plugins:

To update to the latest version of the plugins, you need to remove and add them again. For example, to use the latest version of the file plugin run:

$ cordova plugin rm org.apache.cordova.file
$ cordova plugin add org.apache.cordova.file

Replace the plugin name for the plugin you want to update. The geolocation and contacts plugins have been updated to support auto managing permissions, make sure you update them too.

Check our status page for updated information on plugin status.

What’s next

A highly requested feature is support for emulate and run Cordova commands. We are working with the Dev Tools team to create an awesome experience for debugging Cordova applications using Firefox’s App Manager. Here is a sneak preview of what’s coming!

Meanwhile you can debug your app by adding the platforms/firefoxos/www folder to the app manager in Firefox. For more information, check out Cordova for Firefox OS on MDN.

We are working on creating default icons for a newly created app. They will serve as placeholders that can be easily replaced with your app’s brand.

We also have a development status page where you can see up to the minute information on what is being worked on.

We’d love to hear your feedback and feature requests. You can reach us in the #cordova channel on IRC, or through email at mozilla-cordova@mozilla.org or log your issues and requests on the Apache Cordova issue site. Also if you are interested in helping out with the project let us know.

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)

Broken promises of HTML5 and what’s next? – a presentation at HTML5DevConf

Yesterday Mozilla attended the HTML5 Developer Conference in San Francisco, California to give a keynote presentation. The very packed schedule of the conference already covered a lot of topics around the subject matter, which is why we considered it worth while to contribute with a talk that told tales from the trenches of advocating HTML5 instead of going into technical details. Under the title of “Broken Promises of HTML5 and what’s next?” we reported some of the findings we had when talking to press and people outside the web enthusiast sphere.

Keynote audience

The Slides of the talk are available online and there is a screencast of the live presentation on YouTube.

The organisers of HTML5DevConf promised to release the video recording in the next few weeks.

Here are a few of the points covered to make it more interesting for you to check the 50 minute talk, in case you need more incentive:

Following the press around HTML5 lately we get more and more the impression that we are on the downward slope of the hype cycle about the cool new tech HTML5. The honeymoon period where every shiny HTML5 demo was heralded as the coolest thing and the future of the internet is over and business analysts and developers start feeling disappointed by what HTML5 is portrayed as. A lot of the things that get us as developers excited have been done in Flash years ago and performed better – even on the hardware of the day. The main mistake we seem to make when advocating HTML5 is not think about what makes it unique and how it is different than other approaches to bring higher fidelity to the web.

This talk covers a few ideas we can follow to turn the disappointment around. We will soon deliver a more in-depth article about this and are in talks with business analysts to make that message clearer. Some of the points mentioned here are allowing for re-use of existing knowledge with tools to get Flash developers to create HTML5 content, convert C++ to HTML5 for games using Emscripten (with Bananabread as the flagship demo) and in general not to think about what we can add but instead concentrate on what we can not remove to make our products web products and apps instead of simulating native and mobile apps.

It is up to us to move HTML5 from a flash in the pan to a productive platform, and we can do that by re-using existing knowledge and merge it with the web ideals and the basic principles of HTML5. We will not succeed by trying to replace other platforms that have a lot of knowledge and perform very well indeed.

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)

Mozilla and Games: Pushing the Limits of What’s Possible

At Mozilla, we believe in the power and potential of the Web and want to see it thrive for everyone, everywhere.

What We’ve Done

We’re committed to building the infrastructure needed to keep the Web the most robust platform on the planet. Although its roots have been around for some time, Mozilla’s focus on games is a relatively new initative. We are focused on making Firefox the best game development platform possible.

Check out BananaBread.

The latest Firefox release includes all of the JavaScript and WebGL updates needed to produce this demo.

BananaBread was developed by Mozilla to show our progress in action. We ported a complete C++ game engine to JavaScript using Emscripten. The original opensource engine is called Cube 2. It was designed to support first person shooters. Few believed porting a full, highly responsive game to JavaScript was an achievable goal. (We had our own doubts.) To our amazement, we found that we were able to build a demo that surpassed our highest expectations.

The project required very few code modifications to the original game, which demonstrates that porting games to the Web does not have to be difficult.

Learn more about Emscripten.

New technologies for HTML5 games

Here are a few technologies that have landed this year to advance our support for HTML5 games:

  • Game focused performance improvements to JavaScript, many inspired by games and demos that we saw on the Web or that developers sent to us for testing
  • Wide range of WebGL performance improvements
  • High precision timing
  • Compressed texture support on desktop
  • Smoother JavaScript execution on large code bases
  • Hardware acceleration of 2D canvas on desktop
  • FullScreen API
  • PointerLock API (special thanks to David Humphrey and students at Seneca College)
  • OrientationLock

Firefox for desktops has come a long way in a short time. But there is still more to come. We are working on features that will improve performance and make development easier. We are also investigating options for porting to JavaScript from languages such as C# and Java.

What’s Next

Our focus for the first half of 2012 was Firefox for Windows, Mac and Linux, and while we continue to make improvements there, our focus for the second half of the year will include Firefox for Android and Firefox OS. There are hard challenges ahead but we are excited to deliver the maximum potential HTML5 has to offer, both in features and performance.

One of the main goals of the Mozilla Community working on games is to not only drive game development on Firefox but across all browsers. Any browser that has implemented the necessary modern Web standards used by the BananaBread demo can run it. These efforts help us stay in touch with how HTML5 is coming together and see opportunities where we can make developers’ lives easier. Hearing directly from the HTML5 game developer community is a key part of how we learn what needs to be done.

I hope you’ll come and join us in raising the bar on what’s possible!

You can join the conversation on our IRC server at irc.mozilla.org, channel #games.

Or sign up for the mailing list at https://lists.mozilla.org/listinfo/community-games

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)