Posted by: digdug2k | July 30, 2014

Better tiles in Fennec

We recently reworked Firefox for Android‘s homescreen to look a little prettier on first-run by shipping “tile” icons and colors for the default sites. In Firefox 33, we’re allowing sites to designate their own tiles images by supporting  msApplication-Tile and Colors in Fennec. So, for example, you might start seeing tiles that look like:

appear as you browse. Sites can add these with just a little markup in the page:

<meta name="msapplication-TileImage" content="images/myimage.png"/>
<meta name="msapplication-TileColor" content="#d83434"/>

As you can see above in the Boston Globe tile, sometimes we don’t have much to work with. Firefox for Android already supports the sizes attribute on favicon links, and our fabulous intern Chris Kitching improved things even more last year. In the absence of a tile, we’ll show a screenshot. If you’ve designated that Firefox shouldn’t cache the content of your site for security reasons, we’ll use the most appropriate size we can find and pull colors out of it for the background. But if sites can provide us with this information directly its 1.) must faster and 2.) gives much better results.

AFAIK, there is no standard spec for these types of meta tags, and none in the works either. Its a bit of the wild wild west right now. For instance, Apple supports apple-mobile-web-app-status-bar-style for designating the color of the status bar in certain situations, as well as a host of images for use in different situations.

Opera at one point supported using a minimized media query to designate a stylesheet for thumbnails (sadly they’ve removed all of those docs, so instead you just get a github link to an html file there). Gecko doesn’t have view-mode media query support currently, and not many sites have implemented it anyway, but it might in the future provide a standards based alternative. That said, there are enough useful reasons to know a “color” or a few different “logos” for an app or site, that it might be useful to come up with some standards based ways to list these things in pages.

Posted by: digdug2k | December 20, 2013

Action modes for Android

Assuming all goes well, Firefox will soon be shipping with our first support for Android’s ActionModes for text selection. We previously allowed text selection via some special context menu options when people long pressed on selected text. This replaces that implementation with a nice new UI:

ImageIf you’ve got an add-on that adds something to the selected text context menu:

  1. You’re likely broken in Nightly and Aurora builds right now and
  2. you can easily update your add-on to show in this menu as well.

Some astute developers have already updated themselves, but adding support is pretty easy (updated MDN docs here). We’ve added two methods to the SelectionHandler

  1. let actionId = SelectionHandler.addAction({
        label: "My addon",
        id: "my_id",
        icon: "resource://myaddon/icon", // You MUST include an icon to be shown in the ActionBar,
    // otherwise you'll always be put into the overflow menu.     action: function(aElement) {         // do something when clicked     },     selector: {
    // Just because this is being shown, doesn't mean there is a selection.
    // We may just be showing the cursor handle to let you move the cursor position.
            matches: function(aElement) { return SelectionHandler.isSelectionActive(); }     } },
  2. SelectionHandler.remove(actionId);

Text selection has had an exciting life in Firefox for Android, and is likely going to go through another transition as we land better platform support for touch friendly handles for not just Android, but also Firefox OS, and Metro Firefox. But this is a good move for the UI. We implemented it as a compatibility layer, so it should be available for all Android versions from Froyo to the newest KitKat devices.

Posted by: digdug2k | August 21, 2013

Prompt.jsm in Fennec

I realized today that one of our newer add-on features in Fennec is in Firefox Beta at this point, and I’ve never done anything to blog about it! So here it is, Prompt.jsm!

Prompt.jsm is a module that can be used to show dialogs in Fennec. We use it pretty extensively in our UI for everything from Select popups, Context menus, HTML5 date and time input elements, Certificate dialogs, etc. Previously, those were all done via a similar messaging system, but Prompt.jsm makes it a little easier to deal with and less error prone.

The API is pretty simple. Like I always like to do, I wrote a little addon to show off what you could do. This one I called ReaderPlus and lets you easily add a bunch of articles to Firefox for Android’s ReadingList (i.e. cached offline to see in ReaderMode. You can access your ReadingList through Bookmarks). The code’s a bit more complex than some of my earlier demos, but you’re welcome to peruse it on github if you want (patches welcome!)

The addon loads RSS feeds for a page, and lets you pick articles from them to add to your reading list. It adds a page action on pages where it finds feeds (I used a floppy disk here because you’re kinda “saving” the article, but I’d love something better). When you click the page action, we show a dialog listing all the feeds on the page:

ImageThe code to do something like this is pretty simple, we just import Prompt.jsm and create a new Prompt object:

Cu.import("resource://gre/modules/Prompt.jsm");
var p = new Prompt({ title: "Select a source" })
.setSingleChoiceItems(list.map(function(listItem) {
return { label: listItem.title }
})).show(function(data) {
readerPlus.showSelectArticles(list[data.button].list);
});

The prompt constructor takes an object that can give some basic details about the prompt (i.e. a title, message, and the buttons to show). For more complex prompts, it exposes a Fluent interface, so we can chain a call to setSingleChoiceItems, which shows a list of items. If we had added “selected: true” to one of those items, the dialog would also have shown checkboxes to the right. (You can’t add other inputs to prompts that have lists in them… yet).

Finally, we can call show on the prompt, and pass a callback to be called when its dismissed. The callback gets data bout what was tapped or selected, or the value of any inputs, checkboxes or any time/colorpickers (coming soon!).

The second prompt in the demo app is pretty similar, but uses setMultiChoiceItems to create a dialog where you can check multiple rows:

ImageThe code here is pretty similar:

    var p = new Prompt({
        title: list.title,
        buttons: ["OK", "Cancel"]
      }).setMultiChoiceItems(list.map(function(listItem) {
        return { label: listItem.title }
      })).show(function(data) {
        for (var i = 0; i < data.button.length; i++) {
          if (data.button[i]) {
            readerPlus.addToReadingList(list[i].link, list[i].title);
          }
        }
      });

In this case, we have to be careful to add some buttons to the prompt so that users have a way to close it. They get passed in in the constructor. Because its possible for some items to initially selected, the return has an array that’s the same length as the list and tells you the final state for each row.

Like I mentioned, you can do lots of other interesting things with prompts, adding input elements, labels (which support a subset of HTML if you need to do some advanced formatting),  I’ve tried to document them as well as I can on MDN, but feel free to ping me if you have questions! Happy add-on-ing.

Posted by: digdug2k | July 18, 2013

The new Pageactions are here!

Just this week one of our intern heros, Shilpan Bagat landed a fancy new addon API for people in Fennec that we’re calling “page actions”. Essentially, they’re clickable indicators in the urlbar, a lot like what Desktop Firefox already has.

The API is pretty simple, so I thought it would be funner to show an example add-on using it here instead. So this is a short tutorial on adding a refresh button to the urlbar in Fennec. To start, we just have to fork the awesome skeleton add-on put together by mfinkle a bit ago (we’re going to update the skeleton with an example of pageactions soon too).

Image Read More…

Posted by: digdug2k | April 29, 2013

Show Urls in Fennec

One common request we get in Fennec is the ability to show url’s in the titlebar. At one point I even wrote an addon to do it. Ignoring the arguments for and against, the feature is finally available built in to Nightly builds:

Image

To enable, just open Settings -> Privacy and change the “Title Bar” pref to “Show page address”. We’ve also set up domain highlighting like you see on desktop Firefox (for both regular and private tabs show above, with or without Personas enabled, although Personas are a nice security measure for our new scroll away urlbar too!). Enjoy!

Posted by: digdug2k | January 7, 2013

HTML5 Context menus in Fennec

Last Friday I landed a patch that enables HTML5 context menus in Firefox for Android nightly builds. That means that demos like this one will now work the same in both desktop Firefox and Firefox for Android now.

Posted by: digdug2k | November 28, 2012

Making great things on the mobile web

I love Firefox for Android, but find myself frustrated sometimes with the mobile web. I wanted to highlight some great things out there and point out ways you can work to make your (and others) mobile web better!

Splendid Apps

Twitter has a pretty awesome web app that showcases a lot of what makes the web great. The webapp is designed to work well on small screen devices (needs some work on tablets), and makes use of indexedDB to store data and startup up quickly, as well as including visible throbbers (since webapps have no browser chrome to tell users what is happening) and heavy use of AJAX to load content in the background. They’ve used touch events to implement a nifty pull-to-refresh implementation, have a nice fixed position header to provide easy navigation for the site, and use history apis to make it easy to navigate back and forward between “screens” of the app. If you’ve enabled posting with your location, they’ll use Geolocation to identify where you’re tweeting from. The version of the site they send as their app currently is only lacking support for photo uploads, but they work well if you visit http://m.twitter.com in Fennec (i.e. I assume they just haven’t been uplifted to the webapp yet). In short, its pretty awesome, easy to install, updates faster and more often than apps, and its safe! I’d highly recommend it to any of our Aurora/Nightly users. You can install it straight from the Firefox Marketplace! Or just bookmark the website on your Android desktop by loading it in Firefox for Android, long tap on the urlbar, and select “Add to Homescreen”.

Exquisite Hacks

For those sites that are… lets say less enlightened… the great thing about Firefox for Android is you can make the web what you want it to be! Writing extensions that extend or change sites is not much different than writing the same extensions for Desktop! Not long ago, a version of Stylish was even written that works on Firefox for Android, and today I threw up a style on userstyles.org that adds a much needed fixed position header to Facebook.com.

Learning Stuff

Unfortunately, Facebook users still can’t upload photos from the webapp. Facebook currently shows our users a message reading “Sorry, the browser you’re using doesn’t support uploading photos” along with a sell for their Android app. To be clear to our users, this isn’t true at all! To all the web developers out there who don’t know, Firefox for Android already supports taking photos right from web pages! All you have to do is add a file input with an accepts attribute set to “image/*”. i.e.

<input type=”file” accept=”image/*”>

You can also use “audio/*” or “video/*” for audio and video uploads respectively (I’m looking at you YouTube!).

GetUserMedia can also be enabled in some builds for photo uploads, and video support for getUserMedia is in the works, but for the simple, “upload a photo” case, HTML input’s are perfect (and will deprecate well in browsers that don’t support accept attributes).

I’ve looked into Facebook a bit and it looks like they’re depending on some proprietary api’s (opening a special fbrpc: url) they created for their native apps. Fixing this is definitely doable but is non-trivial hacking that would be fun for someone looking for a fun addon to write! Happy to help anyone interested.

I’ m hoping to keep this up for the next bit, calling out sites or apps that are doing a great job on mobile, and continue to point out things other authors can do to make their mobile pages better. If you know of any you’re especially impressed with, send ‘em my way.

Posted by: digdug2k | August 27, 2012

Testers rock!

To everyone who took time out last Friday or over the weekend to test out some webapps on Android goodness, a huge huge HUGE thanks. I wish I could bake you all cookies. We had a great turnout of testers and found a good number of bugs (more still trickling in this morning). Also, people weren’t shy about sending in the feedback! The MiniMart still exists (I moved it when Dropbox started to complain, so its available on my people.mozilla.org account now too) for anyone else who missed out or who wants to continue to test things!

One of the main things people really want (better integration with the Android launcher and Android app management stuff) is going to be tough to do. We’ve talked about doing things like dynamically building apk’s and even signing them on a Mozilla server somewhere. That opens up enough other cans of worms that we haven’t had time to chase yet. Stability and speed are our first priorities.

Thanks again!

Posted by: digdug2k | August 24, 2012

WebApps on Android are comin’!

I’ve been fairly heads down the past few weeks working hard to polish up WebApps on Android. And the good news is, its almost there! The next train leaving the beta station will be our first beta shipping with support for the Apps API turned on. You can visit any webapp store on the web and install apps directly from there. The apps you install will appear on your Android homescreen, and also be available to any app managers that you’ve given permission to. We have a default App Manager (look in the Android menu for “Apps”) we’re shipping to handle that for now.

WebApps run with their own profiles and in their own processes, like real native apps. They add desktop shortcuts. Show up in the Recent Apps lists. And they have access to pretty much everything you see on Desktop Firefox (including Canvas, CSS Transitions and Animations, and WebGL) + some shiny extras like orientation support. (Android security measures prevent putting them in your Android Launcher or modifying the correct App name/icon in the recent apps list.)

At this point, we need testers!

Testing:
Our teams eyes aren’t enough to hope to find all the problems or test all the devices out there. If you just love the open web and want to try these things out, testing is easy! File bugs (or yell in IRC, email me, reply here, or just tweet at me (DigDug2k)). Install. Start them. Quit them. Restart them. Switch between them. Uninstall them.

We need to know what works, what breaks, what you love and what you hate. There’s a Test Day tomorrow (8/24/2012) if you want to help. We’ll have an irc channel set up, or you can pop in to #mobile. BUT, you can test any time! In fact, I’d love users to keep using these things and to get some testing over more prolonged use. Some quick ways to install apps:

  1. The Mozilla marketplace isn’t quite open yet, but is available to registered Mozillians. You get their either by going to http://marketplace.mozilla.org in Firefox Beta for Android, or through the Apps Manager (Android Menu -> Apps -> Click the shopping bag in the top right).
  2. Since the market is still under active development, I put together something I call “Mini-Market” for testing as well. It contains a few curated apps that we consider ready for testing. If you’re interested you can play with it at http://bit.ly/minimart (WARNING: You will find bugs!). If you’ve got a great app you want me to add, drop me a line here. I’ll try to blog more about it in a bit.
  3. Alternatively, if you run a site that is a webapp, you can serve up an app the through the apps API all by yourself. Trust me, no one enjoys huge “Install our Android App!” banners thrown in their faces when they’re trying to view your site, but I wouldn’t be surprised to see users using a well placed (not intrusive) “One-Click Install” button!

Writing an app:

There’s a lot to write about WebApp development (Note we don’t have to write Mobile WebApp because its pretty easy to write a webapp that runs well on all sorts of devices!). That’s a different blog post But I have noticed a few tips from testing a lot of apps:

  1. Use metaviewport. It won’t affect your site on desktop. It makes things usable on mobile. Use it!
  2. Along with that, now that your site isn’t being rendered at desktop sizes on phones, you can use media queries for responsive design too! And Firefox has a pretty awesome Responsive Design tool built in. The mini market uses some really simple ones to give a two pane view on tablets/desktop and a one pane version on phones.
  3. Webapps have no chrome around them. You are responsible for showing progress if the user clicks a link or does something slow. Use XMLHttpRequest if you can. Plus, that should make it easier for you to build your own cache of responses and make your app super responsive. Desktop apps do it. Webapps need to start doing it too.
  4. If you do load content dynamically into a single page, use the history API! All Android phones have a back button, and this makes it work!
  5. Use App-Cache. I need to get some data here, but completely unscientific testing on my half with really bad mobile networks has shown apps taking 10-15 seconds to start, most of which is waiting on the network. The few (a.k.a. the one admittedly simple) app I’ve seen using App Cache is much faster.

Once you have a simple app built. Installing it is easy. You just to create an app manifest. There are some instructions and boilterplate for doing that here. The test manifest builder is also helpful if you want some boiler plate. Its mostly a simple JSON file you need to serve from the same host as your app. You can submit that manifest to the Mozilla Marketplace (or any other store’s that appear) if you want to use it for discoverability, or you can give users a link to install it from your site by simply calling

navigator.mozApps.install(“path/to/manifest.webapp”)

Thats about it. Happy testing! Once again, please provide us feedback however you can. We’re listening and we’re anxious to make the web a first class citizen for apps.

Posted by: digdug2k | July 10, 2012

Detecting taps using touch events

We recently shipped our first release of Firefox for Android with full multi-touch touchevents support, and I’d like to keep hearing from people if they find bugs or sites that don’t work. I recently had to debug and fix (for a second time) a bug involving Google maps, touch events, and tap detection. I thought it might be worth blogging here as well for future authors looking at this problem. Plus, Maps code is super obfuscated which made it tough to find the problem (both times).

Sidenote to try and avoid questions: Our users also don’t get some other nice Google Maps features like pinch-zoom and nice looking buttons. We fully support multitouch touch events in Firefox for Android, and pinch zoom works (last I checked) if you change your UA to match the stock browser or iPhone. The CSS problems are mostly due to the use of -webkit-background-size without other vendor prefixes. If someone wants to port Stylish to Fennec, it’d be a start to a prettier Google Maps experience for many of our users!

The Maps devs at some point realized they had all this nice code written to handle mouse events for their setup, and wanted to reuse it as much as possible. Ideally, touchevents and mouseevents would be interchangable and things would just work, but this is the system we’re kinda stuck with now. So the Maps team built functions that take touch events, convert them to mouse events, and rebroadcast them:

var sendConvertedTouch = function (eventType, touchEvent) {
  if (1 != b.changedTouches.length) return k;
    var mouseevent = document.createEvent("MouseEvents"),
             touch = b.changedTouches[0];
    c.initMouseEvent(eventType, true, true, window, true,
                     touch.screenX, touch.screenY,
                     touch.clientX, touch.clientY,
                     l, l, l, l, 0, null);
    c.translated = true;
    touch.target.dispatchEvent(mousevent);
  }
}

I doubt this is crazy performant, but it works! I’m guessing there are similar hacks all around the webs. This makes sending mouseup/down/move events simple.

It takes a bit more work to actually fire clicks when the user taps. There’s numerous tools and utilities out there to help with these things. But in this case the team decided to do their own thing. A super simplified version of the result looks something like:

var dragging = false;
document.addEventListener("touchmove", function(event) {
  dragging = true;
}, false);

document.addEventListener("touchend", function(event) {
  if (!dragging)
    sendConvertedTouch("click", event);
  dragging = false;
}, false);

(in their case, dragging actually holds a count of the number of taps).

This fails in current builds of Fennec. Why? Well essentially we don’t do a whole lot of filtering on the input we send to content. The system sends us a touch event, we send it on to content (we do some event coalescing if our internal event handling/drawing is slow the entire system doesn’t get backed up, but that’s about it). But touches on a screen actually jitter quite a bit especially on hdpi devices. Even when it feels like your finger is completely stationary, you’re probably still sending tons of touchmove events to the pages you’re viewing. So even though your finger hasn’t moved far, we send a touchmove event and maps refuses to click.

In addition, Fennec actually supports some of the Level 2 draft for touch events, which includes things like force and radius (NOTE: This spec is still in development and is likely to change, so use those with caution). So if a user presses on a single spot on the screen and then continues pressing harder and harder, we fire touchmove events for all those force/radius changes even though the users finger is still at (approximately) the same place.

All of that means the above code doesn’t actually work for us unless we filter out at least this very first touchmove event and don’t fire it until the user has actually moved their finger a significant distance on the screen. For now, that’s what we’ve done to make maps work for our users.

The correct code should check for some minimum distance after the initial touchstart event. If you get a touchmove that’s further away than that, you’re dragging! Ideally you’d have access to the device dpi here and you could use units of mm or something, but I can’t find a webapi for device dpi (yet?). This post is already getting too long, so I’ll leave that as an exercise to the reader.

“tap” events with some sort of number indicating how many taps have occurred in approximately the same place would probably be a useful addition to the touch events spec. (I noticed the other day that we actually have an internal MozGestureTap event that isn’t implemented in Fennec and isn’t exposed to web content (yet)). For now the EASIEST way to get around some of these problems is to use something like zepto, jquerymobile, or pointer.js which abstract this and other useful “gestures” for you.

Older Posts »

Categories

Follow

Get every new post delivered to your Inbox.