<p>The <a href="/MarkUp/">XHTML2 Working Group</a> has published a W3C Recommendation of <a href="/TR/2010/REC-xhtml-modularization-20100729/">XHTML Modularization 1.1 - Second Edition</a>. XHTML Modularization is a tool for people who design markup languages. XHTML Modularization helps people design and manage markup language schemas and DTDs; it explains how to write schemas that will plug together. Modules can be reused and recombined across different languages, which helps keep related languages in sync. This edition includes several minor updates to provide clarifications and address errors found in version 1.1. Learn more about the <a href="/MarkUp/Activity">HTML Activity</a>.</p> </content>
W3C
XHTML Modularization 1.1 - Second Edition is a W3C Recommendation
First Draft of Emotion Markup Language (EmotionML) 1.0 Published
<p>The <a href="/2002/mmi/">Multimodal Interaction Working Group</a> has published the First Public Working Draft of <a href="/TR/2010/WD-emotionml-20100729/">Emotion Markup Language (EmotionML) 1.0</a>. As the web is becoming ubiquitous, interactive, and multimodal, technology needs to deal increasingly with human factors, including emotions. The present draft specification of Emotion Markup Language 1.0 aims to strike a balance between practical applicability and basis in science. The language is conceived as a "plug-in" language suitable for use in three different areas: (1) manual annotation of data; (2) automatic recognition of emotion-related states from user behavior; and (3) generation of emotion-related system behavior. Learn more about the <a href="/2002/mmi/">Multimodal Interaction Activity</a>.</p> </content>
Privacy Workshop Participants to Study Data Usage and Handling
<p>W3C announces organization of a <a href="/2010/policy-ws/">Workshop on Privacy and Data Usage Control</a>, to take place in Cambridge, MA, UA on 4-5 October 2010. Users trust enormous amounts of personal information to a large variety of online services including social network sites, search engines, photo and video sharing services, and hosted email solutions. As those services become ever more tightly integrated, it becomes increasingly difficult to control the spread of information on the Web. Participants will represent a broad set of stakeholders, including researchers, database manufacturers, CRM-system manufacturers, and Social Networking Providers. Participants will study whether there is interest in further work on policy languages and data handling/data usage work within W3C. Anyone may participate in the Workshop; all participants must submit a short <a href="/2010/policy-ws/#paper">position paper</a>. More information about the Workshop is available in the <a href="/2010/policy-ws/">Call for Participation</a>. Learn more about W3C's <a href="/Privacy/">Privacy Activity</a>. </p> </content>
First Draft of WOFF File Format 1.0 Published
<p>The <a href="/Fonts/WG/">WebFonts Working Group</a> has published the First Public Working Draft of <a href="/TR/2010/WD-WOFF-20100727/">WOFF File Format 1.0</a>. This document specifies the WOFF font format. This format was designed to provide lightweight, easy-to-implement compression of the font data, suitable for use in conjunction with CSS. Any TrueType/OpenType/Open Font Format file can be losslessly converted to WOFF for Web use (subject to licensing of the font data); once decoded by a user agent, the WOFF font will display identically to the original desktop font from which it was created. Learn more about the <a href="/Fonts/">Fonts Activity</a>.</p> </content>
Last Call: Cascading Style Sheets (CSS) Snapshot 2007
<p>The <a href="/Style/CSS/members">Cascading Style Sheets (CSS) Working Group</a> has published a Last Call Working Draft of <a href="/TR/2010/WD-css-beijing-20100727/">Cascading Style Sheets (CSS) Snapshot 2007</a>. This document collects together into one definition all the specifications that together form the current state of Cascading Style Sheets (CSS) as of 2007. The primary audience is CSS implementors, not CSS authors, as this definition includes modules by specification stability, not Web browser adoption rate. Comments are welcome through 15 August. Learn more about the <a href="/Style/">Style Activity</a>.</p> </content>
Cross-Origin Resource Sharing Draft Published
<p>The <a href="/2008/webapps/">Web Applications Working Group</a> has published a Working Draft of <a href="/TR/2010/WD-cors-20100727/">Cross-Origin Resource Sharing</a>. User agents commonly apply same-origin restrictions to network requests. These restrictions prevent a client-side Web application running from one origin from obtaining data retrieved from another origin, and also limit unsafe HTTP requests that can be automatically launched toward destinations that differ from the running application's origin. In user agents that follow this pattern, network requests typically use ambient authentication and session management information, including HTTP authentication and cookie information. This specification extends this model in a number of ways.Learn more about the <a href="/2006/rwc/">Rich Web Client Activity</a>.</p> </content>
W3C Releases Unicorn, an All-in-One Validator
<p>W3C is pleased to announce the release of <a href="http://validator.w3.org/unicorn/">Unicorn</a>, a one-stop tool to help people improve the quality of their Web pages. Unicorn combines a number of popular tools in a single, easy interface, including the <a href="http://validator.w3.org/">Markup validator</a>, <a href="http://jigsaw.w3.org/css-validator/">CSS validator</a>, <a href="http://validator.w3.org/mobile/">mobileOk checker</a>, and <a href="http://validator.w3.org/feed/">Feed validator</a>, which remain available as individual services as well. W3C invites developers to enhance the service by <a href="http://code.w3.org/unicorn/wiki/Documentation/Observer">creating new modules</a> and testing them in our <a href="http://code.w3.org/unicorn/wiki#DevelopUnicornandValidationServices">online developer space</a> (or <a href="http://code.w3.org/unicorn/wiki/Documentation/Install">installing Unicorn locally</a>). W3C looks forward to code contributions from the community as well as <a href="http://code.w3.org/unicorn/wiki#Feedback">suggestions for new features</a>. W3C would like to thank the many people whose work has led up to this first release of Unicorn. This includes developers who started and improved the tool over the past few years, users who have provided feedback, <a href="http://code.w3.org/unicorn/wiki/Translators">translators</a> who have helped localize the interface with <a href="http://validator.w3.org/unicorn/translations">21 translations</a> so far, and sponsors HP and Mozilla and other individual donors. W3C welcomes <a href="http://code.w3.org/unicorn/wiki#Feedback">feedback</a> and <a href="http://www.w3.org/QA/Tools/Donate">donations</a> so that W3C can continue to expand this free service to the community. Learn more about <a href="http://www.w3.org/Status">W3C open source software</a>. </p> </content>
The Multilingual Web - Where Are We? Find out at the W3C Workshop
<p> <a class="imageLink" href="/International/multilingualweb/madrid/cfp"> <img width="98" height="98" src="http://www.w3.org/International/multilingualweb/madrid/mw3-small.png" alt="Multilingual Web logo"/> </a> W3C is organizing a Workshop: <a href="/International/multilingualweb/madrid/cfp">The Multilingual Web - Where Are We?</a>, to take place 26-27 October 2010 in Madrid, Spain. Workshop participants will survey and introduce currently available best practices and standards that help content creators, localizers, language technology developers, browser makers, and others meet the challenges of the multilingual Web. The Workshop also provides opportunities for networking that span the various communities involved in enabling the multilingual Web. <a href="/International/multilingualweb/madrid/cfp#participation">Participation</a> is free and open to anyone. However, space is limited and participants must send an <a href="/International/multilingualweb/madrid/cfp#eoi">expression of interest</a> to the program committee. People wishing to speak should also submit a presentation outline as soon as possible. </p> <p> This is the first of four Workshops being planned by W3C over the next two years as part of the <a href="http://www.multilingualweb.eu/">MultilingualWeb</a> European Project. The first Workshop is hosted by the Universidad Politécnica de Madrid. For more information, see the <a href="/International/multilingualweb/madrid/cfp">call for participation</a>. Learn more about W3C's <a href="/International/">Internationalization Activity</a>.</p> </content>
HTML Media Capture Draft Published
<p>The <a href="/2009/dap/">Device APIs and Policy Working Group</a> has published a Working Draft of <a href="/TR/2010/WD-html-media-capture-20100720/">HTML Media Capture</a>. This specification defines HTML form enhancements that provide access to the audio, image and video capture capabilities of the device. The title of the specification changed in this draft (from "The Capture API"). Learn more about the <a href="/2007/uwa/">Ubiquitous Web Applications Activity</a>.</p> </content>
Last Call: Web Services SOAP Assertions (WS-SOAPAssertions)
<p>The <a href="/2002/ws/ra/">Web Services Resource Access Working Group</a> has published a Last Call Working Draft of <a href="/TR/2010/WD-ws-soap-assertions-20100713/">Web Services SOAP Assertions (WS-SOAPAssertions)</a>. This specification defines two WS-Policy assertions that can be used to advertise the requirement to use a certain version of SOAP in message exchanges. Comments are welcome through 27 August. The group also published <a href="http://www.w3.org/TR/2010/NOTE-ws-resource-transfer-20100713/">Web Services Resource Transfer (WS-RT)</a> as a Note today. That specification defines extensions to WS-Transfer primarily to provide fragment-based access to resources. Learn more about the <a href="/2002/ws/">Web Services Activity</a>.</p> </content>
Last Call: Mobile Web Application Best Practices
<p>The <a href="/2005/MWI/BPWG/">Mobile Web Best Practices Working Group</a> has published a Last Call Working Draft of <a href="/TR/2010/WD-mwabp-20100713/">Mobile Web Application Best Practices</a>. The goal of this document is to aid the development of rich and dynamic mobile Web applications. It collects the most relevant engineering practices, promoting those that enable a better user experience and warning against those that are considered harmful. The Mobile Web Best Practices Working Group does not expect more substantive changes at this point and expects to be able to transition directly to Proposed Recommendation at the end of the Last Call review period. Last call comments welcome before Comments are welcome through 06 August 2010. Learn more about the <a href="/Mobile/">Mobile Web Initiative Activity</a>.</p> </content>
RDF Workshop Report Emphasizes Support for JSON, Turtle, Other Formats
<p>The last week of June, participants at the <a href="/2009/12/rdf-ws/">W3C RDF Next Steps Workshop</a> concluded that support for JSON, Turtle, and for "Named Graphs" are top priorities for any future work on RDF. Participants also highlighted the importance of compatibility with existing deployment. Read about these and other topics in the <a href="/2009/12/rdf-ws/Report.html">Workshop report</a>. To join the discussion about organizing future work on RDF, please share your thoughts on the <a href="mailto:semantic-web@w3.org">Semantic Web Interest Group</a> mailing list (with a copy to the separate <a href="mailto:www-rdf-comments@w3.org">RDF Comments list</a>). W3C thanks the <a href="http://bioontology.org/">National Center for Biomedical Ontology</a> at Stanford, Palo Alto, USA, for hosting the Workshop. Learn more about the <a href="/standards/semanticweb/">Semantic Web</a>.</p> </content>
Last Call: Authoring Tool Accessibility Guidelines (ATAG) 2.0, Implementing ATAG 2.0
<p>The <a href="http://www.w3.org/WAI/AU/">Authoring Tool Accessibility Guidelines Working Group</a> has published Last Call Working Drafts of <a href="/TR/2010/WD-ATAG20-20100708/">Authoring Tool Accessibility Guidelines (ATAG) 2.0</a> and the companion document <a href="/TR/2010/WD-IMPLEMENTING-ATAG20-20100708/">Implementing ATAG 2.0</a>. ATAG defines how authoring tools should help developers produce accessible web content that conforms to Web Content Accessibility Guidelines (WCAG) 2.0. The ATAG documents also describe how to make authoring tools accessible so that people with disabilities can use them. Comments are welcome through 2 September 2010. Read the <a href="http://lists.w3.org/Archives/Public/w3c-wai-ig/2010JulSep/0002.html">invitation to review the ATAG 2.0 Last Call Working Draft</a> and about the <a href="http://www.w3.org/WAI/">Web Accessibility Initiative (WAI)</a>.</p> </content>
For Review: Updated Techniques for Web Content Accessibility Guidelines (WCAG)
<p>The <a href="http://www.w3.org/WAI/GL/">Web Content Accessibility Guidelines Working Group</a> today requests review of draft updates to Notes that accompany WCAG 2.0: <a href="http://www.w3.org/WAI/GL/2010/WD-WCAG20-TECHS-20100708/">Techniques for WCAG 2.0 (Editors' Draft)</a> and <a href="http://www.w3.org/WAI/GL/2010/WD-UNDERSTANDING-WCAG20-20100708/">Understanding WCAG 2.0 (Editors' Draft)</a>. Comments are welcome through 9 August 2010. (This is not an update to WCAG 2.0, which is a stable document.) To learn more about the updates, see the <a href="http://lists.w3.org/Archives/Public/w3c-wai-ig/2010JulSep/0003.html">Call for Review: WCAG 2.0 Techniques Draft Updates e-mail</a>. Read about the <a href="http://www.w3.org/WAI/">Web Accessibility Initiative (WAI)</a>.</p> </content>
Contacts API Working Draft Published
<p>The <a href="http://www.w3.org/2009/dap/">Device APIs and Policy Working Group</a> has published a Working Draft of <a href="http://www.w3.org/TR/2010/WD-contacts-api-20100701/">Contacts API</a>. This document defines the high-level interfaces required to provide access to a user's unified address book, which may source address book data from several sources, both online and locally. Learn more about the <a href="http://www.w3.org/2007/uwa/">Ubiquitous Web Applications Activity</a>.</p> </content>
Vitamin
PHP Login Form Part 1 [Video Tutorial]
For our second free weekly helping from the Think Vitamin Membership video library we Jim looks at how to create the perfect login form using PHP.
Don’t forget to check out the video library for free videos as well as learning more about our new membership service.
QuirksMode
Four mobile links
Here are four interesting mobile articles that caught my eye in the past 24 hours:
- Your mobile app is spying on you. About the danger in free apps.
The study also found that a large proportion of apps contain third-party code with the capability to interact with sensitive data in a way that may not be apparent to users or the developers of the apps themselves. The third-party code is generally used for advertising or analytics. The project found that 47 percent of free Android apps included this third-party code, while 23 percent of free iPhone apps use it. Third-party code represents a security risk because it is difficult to update (and patch a vulnerability) on a global basis. Apple changed its terms of service for the iPhone recently because of its concerns about what third-party analytics and other companies were doing with private data.
- Nokia’s JavaScript Peformance Best Practices. Contains a lot that was taken from Steve Souders’s research and common knowledge, but also a few things I’ve never heard before. I’d really have to do an evaluation of some of the practices. Also contains a few ugly-but-necessary tricks for Symbian WebKit (S60).
- Also from Nokia: Introducing Ovi Browser Beta for Series 40. Nokia, too, has produced a mini-browser that relies on a server for the actual rendering and sends out the fully-rendered page, just as Opera Mini does. Now I need to lay my hands on an S40 device so that I can test it.
- From Bruce Lawson at Opera, finally, comes Mobile-friendly: The mobile web optimization guide with useful tips and tricks for making your website mobile-friendly.
[...] mobile users are in a hurry; they're on the go and want to perform one specific task and then finish. A common example cited is that of a restaurant site. The mobile user wants to find the location, the menu and the opening hours so, the argument goes, the mobile site should contain this and nothing else.
This is a good argument, but it's only half true. If it were 100% true, what would be on the "full" website? Presumably, a movie of the decor, some atmospheric music, animated representations of the house special dishes, and a downloadable menu in some fancy font. The fallacy here is that users of desktop computers are not task-focussed and have time to waste on an immersive branding experience.
Wisdump
Anorexic vs. obese layouts: you can't please everyone, but you should try
This comes as a surprise. Aux of Cogent Metal is vehemently against webpages that have narrow layout widths. And I thought web designers are now more worried about the opposite: the wide layouts that whip out the horizontal scrollbars in resolutions narrower than 1024×768.
This is another proof that you can’t guess every possible reaction to a design pattern. In this case Aux would rather have wide layouts because it would mean a larger area to present content. But what can you do about someone just like Aux, but who believes the complete opposite?
Elasticity is tricky
The ideal solution to please both lovers and haters of the narrow look would be to construct an elastic layout. But images are the number one obstacle. They have fixed dimensions and look horrible when resized using HTML or CSS attributes—please, don’t go there, it’s just atrocious. Other solutions are just for decorative purposes, not for every image on the page.
Ads, widgets, and plug-ins all tend to have fixed dimensions as well. It’s a chicken-and-egg thing: designers resort to fixed layouts because they can’t resize all those fixed objects, and all those objects are fixed because their creators assume they’ll be placed in fixed layouts anyway. That, and there hasn’t been a move towards flexible anything. Is it because we fear the unpredictability of flexibility? If it were possible to have webpage elements with flexible dimensions, would we use them, or still go for the fixed-dimension ones?
A completely flexible layout width isn’t that appealing, either. In larger screens the lines of text will be so long that it becomes difficult to read. Every layout option has its advantages and disadvantages. You have to pick one and accept that you’ll piss someone off one way or the other.
Custom-tailored user experience
However, you should try to please as many people as possible especially if your website is any of the following:
- Very popular (e.g., CNN)
- Text-heavy (e.g., Wikipedia)
- Requires registration (e.g., My Yahoo!)
Don’t stop with the layout width. The general ability to customize is important. See what MSNBC and BBC have done. Users can control the type of news that appears, the order in which the news sections appear, the complexity of the page layout, the text styles (from color to letter spacing), and so on. It’s the empowerment you bring to the audiences that tells them they are highly valued individuals.
Design is about presenting information in the best possible way. Unfortunately there is no single way that is considered the best as long as someone other than the designer is experiencing that design. Although more difficult to implement, websites can let users choose that experience. If you can help it, let them.
Related reading:
ajaxian
Canto.js: An Improved Canvas API
Javascript author extraordinaire David Flanagan released Canto.js recently, a lightweight wrapper API for canvas, introduced here and documented at the top of the source code. Example:
Notice three things:
- canto() returns an abstraction of the canvas - a "Canto" object.
- As with jQuery and similar libraries, there's method chaining; each method called on a Canto also returns the Canto.
- lineTo() has been extended to support multiple lines being drawn in a single call.
Instead of setting the ink properties and then painting it, you can do it all in one step:
And plenty more syntactic sugar - check out the API in the source code comments. Sweet!
Thanks @pkeane.
Vitamin
Around the Web: CSS3 Animations, Agile + UX, Processed Identity
Hey there!
It’s Wednesday, so this mid-week roundup is devoted to all things business and development.
Some links are newsworthy, some retweeted across Twitter, and others just meet our "awesomeness" requirement, and regardless we hope you'll enjoy them. Without further delay:
- Start Experimenting With CSS3 Animations (via@leemunroe)
- Arggggh! Subterfuge. Why Design Contests Are Bad (via Core77)
- Open Source Your Career (via Stefan Koopmanschap)
- Agile + UX, Remembering What a Team is Supposed to Be (via Thinking & Making)
- If you’ve ever worked on a brand identity or run into challenges you’ll enjoy “Processed Identity,” which s the story of how you got “there”
Wildcard: Get to Know an Internet Commenter (via McSweeny’s)
Please shoot me links to projects your working on or awesome things you’ve released! news@thinkvitamin.com
Handpicked by,
Chrissie (@tenaciouscb)
Vitamin
PHP Basics: Installation [Video Tutorial]
It’s Wednesday and time for our first free weekly helping from the Think Vitamin Membership video library.
Today Jim looks at getting started with the popular programming language PHP. In this 8 minute video he shows you how to install PHP and write your first lines of PHP code.
QuirksMode
Opera’s problems on mobile
In the mobile browser space all the advanced browsers are based on WebKit. That’s fine — WebKit is an excellent rendering engine — but if all browsers were based on WebKit I would start to worry about a monoculture. At least some browsers should be based on other rendering engines, as far as I’m concerned.
The only serious mobile candidate for “other rendering engine” is Opera. But I’m starting to wonder whether it can keep up with the WebKit browsers. With the recent release of Samsung Dolfin Opera Mobile has firmly dropped from third-best to fourth-best mobile browser on my list.
The problem is not that Opera isn’t innovating. It is. But I’m starting to wonder about the direction that innovation is taking.
Witness the recent release of Opera Mobile 10.1 beta for Symbian (on my 40th birthday; thanks, guys). I went through the press release, which highlights the following changes:
- Geolocation is now supported (although it doesn’t give the coordinates in my test page). That’s cool; it’s definitely something that’s extremely important on mobile.
- Vega graphics library and Carakan JavaScript engine. That’s fun to have, but I’m not sure if it’s the most important step Opera could have taken right now. I’ll get back to this.
- Various improvements to the user interface.
And that’s it, according to the press release. (border-radius is supported, maybe some other stuff too, and there will be some bug fixes here and there, but I haven’t yet studied it sufficiently to give you a full list.)
Relative importance
Nowadays all desktop browsers are innovating like mad in their JavaScript engines. For about a year and a half or so, significant improvements in JavaScript speed have been the Holy Grail of browser making, and every new release of every browser now routinely claims to be the fastest browser available.
(So routine has this claim become that I do not believe any of them any more. Besides, as far as I can tell they’re all testing JavaScript Core speed, while the biggest bottleneck is the speed with which DOM changes are made.)
Now on desktop this is a very important development. On mobile it’s also important, but I feel there are several other topics that are even more important than JavaScript speed, and that Opera is ignoring these topics.
Point is, a super-fast JavaScript engine is relatively worthless if you can’t properly set up a JavaScript-heavy interface. And the very first requirement for a JavaScript-heavy interface is that you always know exactly what the user is doing, so that you can react to his actions naturally and great UX is born.
It’s in the latter part of that equation that Opera Mobile has serious problems. I feel that, while innovating in JavaScript engines, Opera is forgetting basic mobile functionality without which a fast JavaScript engine is pointless.
Touch and viewport
There’s a reason I started my foray into mobile browsing by studying the touch events and the viewport dimensions. These two functionalities are absolutely vital to building compelling mobile interfaces.
The touch events allow us to follow exactly what the user is doing to the touchscreen. Without these events you can only detect whether the user clicks somewhere. That is enough for some interfaces, but others will definitely want to react to more subtle actions from the user.
The viewport dimensions are important for knowing how much of your site the user is currently seeing on his screen. An example will clarify why this is important.
I’m currently working on a little side project that involves writing the perfect JavaScript touch-scroll interface. This presupposes the touch events: without them it’s absolutely impossible to create a compelling UX.
However, I want several scrollable areas on the same page, and with that comes the problem of deciding when to allow a user to scroll. If the user has zoomed in and sees a little bit of one scrollable area on the edge of his screen, it makes sense not to scroll that area when he touches it, because it might confuse him. Instead, we should wait until the scrollable area covers most of the screen before allowing a scroll action. My prototype with this behaviour works pretty intuitively.
However, in order to know whether the scrollable area is on the screen I must be able to read out the dimensions of the visual viewport. I need to know which part of the page the user is currently viewing, compare it to the scrollable area, check their coordinates, and decide whether the user is allowed to scroll. That’s something that few browsers support right now.
Android and Samsung support the touch events, but not the visual viewport dimensions. Symbian, BlackBerry and IE support the visual viewport dimensions, but not the touch events. All other browsers, including Opera Mobile, support neither. So this script only works on the iPhone, which is the single browser to support both.
So this interface, which I feel is an example of a mobile-specific UX, will not work on Opera Mobile, regardless of the speed of its JavaScript engine. That’s what I mean when I say that I’m wondering about Opera’s direction of innovation.
Opera Mobile simply must support the touch events and the viewport dimensions.
Zooming
But Opera Mobile has an even larger problem, and that is zooming. Basically it has the worst zooming functionality of any mobile browser I tested. It seems Opera ignored the emerging standard for touch-based zooming, and instead created its own system. That’s fine, as long as the system works. But it doesn’t.
So what exactly is wrong with Opera’s zooming? Basically everything.
Two levels
Opera has only two zooming levels: in and out. Initially you see the entire page, just as on all other mobile browsers. When you zoom in, however, you go to one single pre-defined zooming level, and once you’ve arrived there your only option is to zoom out again.
This behaviour is not unique to Opera Mobile. Many other second-tier mobile browsers, such as Symbian WebKit on touchscreen Nokias, or IE, have only two zoom levels.
But there are two other characteristics that make the Opera zooming experience uniquely lousy.
Pre-emptive narrowing of text
Opera kind of pre-emptively narrows your text into columns that fit snugly in the screen when you zoom in. Although that’s excellent behaviour to display when the user actually zooms in (as Android does), doing this beforehand makes no sense and has the ability to destroy your page’s graphic design.
Here’s my compatibility master page as it should display on mobile (Dolfin on Samsung Wave). Note that the text in the table stretches all the way from left to right, as it should:
And here is the same page on Opera Mobile 10.10 (Nokia N97). Here the text in the table is narrowed to the width Opera is going to take later on, when you zoom in:
In this particular case I don’t mind much, but this feature has the ability to completely destroy a well-designed page. As far as I know you can’t do anything against this effect and will have to accept the damage it does to your page.
Single tap
But by far the worst feature of Opera’s zoom is the user interaction. On touchscreens an industry standard is emerging for zooming. You either pinch-zoom or you double-tap. Some browsers don’t support pinch-zoom, but the double-tap works pretty well, too.
However, Opera in its wisdom uses not a double-tap but a single-tap interface. Tap once when zoomed out and you will zoom in on roughly the area you tapped on.
This is terrible. In order to understand why, take a look at my Touch test page. It’s fully zoomed-out:
This is how I designed the page: I want it to be usable even fully zoomed-out. Thus I can load the page, hit Record, and record an event sequence of my choice.
But what happens in Opera Mobile when I hit Record with a single tap in order to start recording? It. Bloody. Zooms. In! That makes my test page much harder to use.
To be fair, Opera Mobile 10.10 does not zoom at all in pages that have a <meta viewport>, as my test page has. That solves this particular issue, but I feel it’s still a stop-gap solution. All other browsers do allow the user to zoom in on a <meta viewport>-enhanced page. (Some even allow you to zoom out.)
Opera’s problems
Concluding, Opera Mobile has a serious zoom problem that must be addressed in addition to the touch event and viewport dimension problem.
I feel that addressing these issues is more important than yet another faster JavaScript engine or yet another UX upgrade. Besides, as long as zoom remains lousy the UX can be upgraded only so much. Zooming is a fundamental part of the mobile UX; without it many other innovations just don’t make sense.
So in order to remain relevant on the highest tier of mobile browsing, Opera will have to concentrate on three things:
- Fix zooming: double-tap interaction, many more zoom levels, no pre-emptive narrowing of text columns.
- Support the touch events.
- Allow us to read out the viewport dimensions.
I more-or-less expect the busy engineers in Oslo to be working on these problems, and I assume that the next major Opera Mobile upgrade will bring significant improvements here.
If it doesn’t, I’m afraid Opera is out of the race for the top spot. That is not necessarily bad: it could always forget about the top tier and instead concentrate on the low-end smartphone market. Right now Opera Mobile is available only for Symbian and Windows Mobile, and on those operating systems it’s the best available browser.
Without a serious upgrade of mobile-specific functionality ruling this second tier is the best Opera can hope for. The top tier will be WebKit-only.
ajaxian
YUI 3.2.0 preview release 1 " touch events support, transitions and browser-specific loading
Over at the the YUI blog the team just announced the preview release of YUI 3.2.0. YUI3 now has some interesting new features that the team wants you to try and tell them if they work out for you. The changes to the already very powerful library are quite ambitious:
- Touch event support for mobile interfaces including flick and move gestures
- Browser capability loading - which means that every browser gets the least amount of code necessary to make it work
- Transition support for the animation module - meaning only browsers that don't support CSS3 transitions get the JavaScript animation fallback
- An update to the CSS grids to allow for more flexible layouts
- A ScrollView widget similar to the one in Apple iOS
- The uploader has been transitioned over from YUI2 to YUI3
So check out what is on offer and give the YUI team feedback on what would be nice to have and what is broken. In their own words:
The goal of a preview release is to make it as easy as possible for all of us in the community to evaluate progress of the upcoming release and provide feedback. Please take some time to test 3.2.0pr1 and let us know what you find by filing tickets in the YUI 3 bug database marked as "Observed in version" 3.2.0pr1. We'll do our best to address preview-release questions on the YUI 3 Forums, too.
There are three ways to get started with the preview release: YUI 3.2.0pr1 is available on the CDN via the 3.2.0pr1 version tag " so you can reference preview-release files like http://yui.yahooapis.com/combo?3.2.0pr1/build/yui/yui-min.js. If you switch to this seed file for the preview release, all subsequent use() statements will continue to load YUI 3.2.0pr1. Or You can download the full YUI 3.2.0pr1 from YUILibrary.com, including source code and examples for all components. Or you can simply explore the functioning examples roster.
Vitamin
Recurring Billing For Web Apps
Increasingly web application developers and entrepreneurs are turning to the “Software As A Service” (SaaS) model to monetize their products.
Together with this growth has come the need for reliable recurring billing systems and in turn a number of enterprising folks have built said solutions and fittingly used the SaaS model to monetize their efforts.
In this article we will look at how these services work, why you’d want to use them, the various options available, and how they differ from one another. Hopefully it should give you a better idea of which service is right for you and how you plan to use it.
Why do I Need this Service?
There are many tools that are making web application development easier and easier, whether that be development frameworks such as Rails and Django or services like Amazon Web Services and Google App Engine, recurring billing systems are no different.
Building a billing system can be a complicated process with issues such as how to handle failed transactions, when and how to recharge cards, and not to mention all the data protection issues surrounding storing financial information and PCI compliance etc. These services allow you to abstract these concerns and let you focus on building the software you care about.
How do They Work?
The services all have a number of core functions in common. They provide a web application interface where you can create different products and configure pricing options. The service then deals with taking and storing your customer’s credit card details (normally with a PCI compliant third-party).
The information about customers, products and subscriptions is then exposed via a secure API which allows you to hook your app into the service. A fairly simple, elegant and, in my experience, reliable solution to something that could potentially be a major headache for app developers.
Essentially as a developer you have two options:
Option One
You choose to forward paying customers to the service’s hosted payment pages. This is the quickest and simplest way to get started. These pages are secure and accept query string parameters to pre-populate fields such as name and email address.
Successful payments will then be forwarded to a callback URL and any change to a subscription’s status will be posted back to your app via a post-back URL.
Both of these URLs are specified by you in the product settings of the billing service. Obviously, you would be mad not to validate the callback with a API query and likewise you will also need to check the nature of the subscription status change upon post-back notification.
Option Two
The process is almost identical to option one, however, you do not send users to the service’s hosted page to take payment. Your application collects (but does not store) all payment details and that data is then delivered to the billing service via their API.
In this instance the onus is upon you to take the user’s credit card details securely and handle the API’s response appropriately. However, the obvious benefits of this option is that the user’s experience is seamless, you have complete control over user interface design and user’s are unaware you’re using an external billing service.
Billing Systems vs. Payment Gateways
Amidst these technical decisions it is also important remember that these billing services are not payment gateways, they do not carry out the card transitions. They purely deal with the business logic of charges, re-charges, charge backs and data storage. In order to charge the card and for the money to end up in your account the billing service provider hooks into the API of your payment gateway of choice.
This means that it is important to check which payment gateways these service providers support. Some support more than others and until recently some have had a very limited choice of gateways.
Some common payment gateways include:
There are also differences in these gateways and it is important to choose the right one for you and the billing service you choose.
Something to consider is that most of the gateways mentioned above require a merchant account which you would have to arrange with your bank. However, a lot of people avoid this by using Paypal Payments Pro where the money is transfered into a Paypal account ready for you to withdraw.
If you’d like to know more about merchant accounts hear what Ryan has to say about his experience in this arena on Think Vitamin Radio Episode 7.
What’s on Offer?
There are a good range of providers to choose from and unlike some services they do vary in their cost, features and pricing model. Here’s a breakdown of a few of the big players in the space.
Chargify
Chargify is seemingly the solution with the richest set of features and the lowest barrier to entry. They offer a free account which is limited to 50 paying customers plus 1,000 non-paying customers.
Their pricing model is clearly designed with the thought that those first 50 customers are the hardest to acquire and once you have those customers paying X amount per month you can afford to pay for their higher volume service.
These start from $49 a month for up to 500 customers and is graduated there on up to $2,499 per month for unlimited customers. As a result of these graduated monthly fees Chargify does not add any per-transaction cost, so within their pricing brackets your costs are fixed.
The people behind @chargify on Twitter are extremely helpful both in explaining their own service and in offering advice about merchant accounts and receptive banks in both the UK and USA.
This is unsurprising as Chargify is brought to you by the guys behind Grasshopper and if you’re a Rails person it is also worth noting that Chargify’s CEO and Founder is Lance Walley who was also Co-Founder of Rails hosting provider Engine Yard. Both these companies are known for their excellent software and, in my experience, great customer service which bodes well for Chargify.
Spreedly
Spreedly is a younger service and therefore less feature rich. For example, I expressed an interest in charging a set up fee. A one-off fee that is only charged upon sign up. This can be useful to those services that have a fixed overheads for each user who signs up and something that’s easy to set up on Chargify.
However, Spreedly don’t currently offer this feature, but they say it is something that they are keen to do in the future. Likewise, at this point they don’t seem to have the choice to create add-ons for customers to add to their purchase at point of sale. Again, this is very useful for SaaS businesses offering bolt-on services.
Spreedly also takes a slightly different approach to Chargify in terms of pricing. They have a flat-rate monthly charge of $19 but also take 20c or 2% (whichever is the lower amount) of each transaction.
As with Chargify this pricing model scales with your business and means that at times Spreedly could be considerable cheaper than Chargify. That said, there are also points of customer volume where Spreedly’s costs will exceed Chargify’s. Plus with Chargify the frequency of your payment transactions is not an issue, if you want to charge users every 14 days you can at no extra cost whereas this would prove an expensive exercise with Spreedly.
A great benefit of Spreedly is the quantity of payment gateways they support. They are clearly focusing on simplicity and their support for gateways which is by no means a bad thing. As with Chargify the folks behind @spreedly were extremely helpful via Twitter and found my questions about their service without the need for a direct @ message. They were happy to answer questions and offer alternative approaches to features that weren’t available yet. In short, Spreedly is definitely worth a look if your current needs are simple and you like the idea of a per-transaction cost.
CheddarGetter

First up – what a name – CheddarGetter definitely wins in the name game. However, how does it stand up against Chargify and Spreedly. Well, in terms of features CheddarGetter definitely rivals Chargify and exceeds Spreedly. However, their pricing structure is different again. Like Chargify they have graduated montlhy charges based on customer volume with no transaction fees.
As with both Spreedly and Chargify @cheddargetter offer phenomenal service via Twitter. Mention the name CheddarGetter in the context of a question and they will find you and offer support. This proactive approach seems to be the norm is this space but we shouldn’t forget how rare it is to get this kind of customer service.
The major downside of CheddarGetter right now is its lack of payment gateway integration. The limited list of gateways includes Network Merchants and Authorize.net but no Paypal Website Payments Pro for those of you who don’t want to deal with getting a merchant account with your bank. That said, with some more payment gateway integration CheddarGetter has real potential.
But How do I Choose?
As you can see the billing services spaces has quite a spread of different pricing models so they can be hard to compare in terms of price and work out features vs. cost per customer vs. potentially cost per transaction with Spreedly.
Chad Glendenin has an excellent comparison of the pricing of these services including graphs which map customer growth vs. cost of service for all these of the providers I’ve mentioned. These are extremely useful in demonstrating how these services actually compare in terms of price and highlights the customer volume markers where favour shifts from one service to another. He also provides his Python script for generating these figures so that you can run the numbers with your own payment frequencies and prices.
It’s clear that if you expect a very high quantity of subscribers, meaning 15,000+ customers paying monthly, then Chargify’s features and unlimited plan makes them the obvious choice.
However, if you’re expecting very low volume, or your only taking annual payments and this is something you’re setting up on the side of a day job, Spreedly’s per-transaction model and simplicity would suit your needs. However, these are both extreme ends of the spectrum.
Extremes aside, I think this decision is really about features and not price. The costs are marginal compared to whether the service can provide you with what you need. Integration with a billing system while a fairly straightforward process isn’t something that you want to have change after 18 months.
Conclusion
If you’re planning more complicated pricing models, add on products, short payment intervals, or want a metered service where customers pay for their usage then you need to hunt down each service’s feature list and ensure they offer what you need. You are buying simplicity, you’re buying the ability to focus on your own app and abstract the billing logic, make sure the service you choose offers you what you need not just the best price.
Finally, if you guys are using any of these services it would be great to hear from you in the comments about your experiences and your decision making when you chose the service.
QuirksMode
Mobile payments made easy
This is just in: Google seems to be taking steps to allow operator billing. If that’s true it’s huge news.
Note from the outset that the article doesn’t say in so many words that operator billing is coming, although it certainly gives that impression, and plenty of publications translate it as such.
The basic idea of operator billing is very simple: if you want to buy an app, or access to online content, the price is automatically added to your operator bill (or, I assume, deducted from your pre-paid account).
Now I’m not a mobile billing specialist by any means, but I still want to give you an idea of what we’re talking about. If I make any technical mistakes, please correct them in the comments.
The billing process
Just yesterday I made my first Android Market purchase, and although the process was relatively smooth, I still had to fill in all my credit card stuff, make mistakes, being told off, etc. Besides, when I tried to do the same a few months ago, the Android Market rejected my credit card. Why? Probably because the Dutch market wasn’t active yet — but I thought of that only much later. At the moment I was pretty pissed.
Now with operator billing I wouldn’t have all this hassle. I’d just click on whatever I want to buy, give a one-time confirmation “Yes, I do want to spend € 2.39 on this” and be done. When my next operator bill comes around, the € 2.39 will be added to it.
In addition, operators can verify your identity through your SIM card, without you having to do anything. No more hassle with credit card numbers. (In fact, the only parties that have a lot to lose from operator billing are the credit card companies. Expect resistance from them; they’ll probably say it’s unsafe or something.)
Thus operator billing is by far the most user-friendly way of making mobile purchases. That’s what makes it so important. Besides, it also opens up the mobile marketplace to those that do not have a credit card.
A question of identity
However, Google’s rather vague announcement does leave some questions unanswered. No doubt that’s because Google is still figuring out how to answer those questions. But let’s review them anyway:
- What do I have to do in order to make a purchase? A one-step system is within reach; I hope it will be implemented.
- How will my identity (and thus my bill) be verified?
- How will the various parties communicate?
The last question is probably the most important one. If I want to make a purchase through operator billing, there are three parties involved: me, the selling party, and the operator. Somehow, the selling party has to connect to the operator to figure out exactly who I am, and to make a request to put € 2.39 on my bill for my purchase. In addition, the operator has to pay that money (maybe minus a fee) to the selling party.
The JIL 1.2 API gives us some clues as to how this system is going to work. This API, that will eventually be implemented in Vodafone 360 phones as well as, one hopes, many others, has two properties that are meant specifically for operator billing (p. 16):
Widget.Device.AccountInfo.phoneUserUniqueId Widget.Device.AccountInfo.phoneOperatorName
Thus, when purchase times comes around, the store has some grip on your identity. It will have to send off a communication to the specified operator stating that user with unique ID X wants to make a € 2.39 purchase.
The operator will have to make some effort to verify this information; after all I might be able to hack a phone to send false unique IDs. Thus the operator will probably send me an SMS “Are you sure you want to purchase product X for € 2.39?“ Once I reply to that SMS the purchase is made and downloading can commence.
Still, I hope that the process will become even more user-friendly. The same JIL specification defines a way to send an SMS from a widget. Thus, if I want to purchase something the system could automatically generate an SMS for me and send it off to the operator. Thus the operator will be able to verify my intent by comparing my unique user ID with the SIM card through which the SMS was sent. If they match the purchase is made and downloading can commence.
That’s one step less, and thus more user-friendly. Hell, if it’s implemented correctly I don’t even have to switch to my SMS application. (The operator still has to tell the store “Purchase made, proceed with download.” But a proper system will not bother me with the details.)
Unfortunately the JIL 1.2 spec does not yet contain the methods that will be used for actual payments, nor the exact workflow. Besides, it’s unclear which operators Google is talking to right now. Probably US-based ones, and of those only Verizon is part of the JIL consortium. The others might use other APIs. (Come to think of it, so might Verizon. One never knows.)
Future expansion
Let’s close on a positive note and assume that a system roughly similar to what I describe above will actually be in place in two years or so. Apart from the increased user-friendliness of the purchasing process, what will it bring?
The basic answer is Long Tail. Increased user-friendliness and the scrapping of the requirement to own a credit card may entice more consumers to make a mobile purchase. That would be good.
The real benefit will lie with developers, though. In theory, the system could be set up so that individual developers who offer one or two apps for download on their own site can also use it.
Thus the requirement to offer your wares through one or more app stores might also be scrapped. That could be especially important to cross-platform apps such as W3C Widgets. Whichever phone with whichever operator ends up at the developer’s site, they can all make a purchase, provided they support widgets.
One more nail in the app stores’ coffin would be the opportunity to make in-app purchases; say some articles from a news site or a few new levels for your game. Operator billing is explicitly meant for such purchases, too. And if we can use operator billing in our apps, too, the app store infrastructure is basically not necessary any more.
Picture the following:
- I write a news reader app as a W3C Widget. Anyone can download it for free from my website.
- If you like my app you can share it with your friends. Just send over the widget via Bluetooth. No more complicated user-unfriendly Send-To-Friend systems necessary.
- But how do I make money? By selling access to the actual articles. Every article you want to read costs you, say € 0.02. Alternatively, you can buy a day of unlimited access for, I don’t know, € 0.99.
- All the billing is done in-app through the operator. My users never have to do anything beyond saying “Yes, I want to buy this article.”
Where’s the app store in this process? Nowhere. We don’t need it any more. Wouldn’t that be something?
(I should note that although sending widgets via Bluetooth is possible nowadays — I’ve done it — the process is not very user-friendly yet. But this functionality is definitely coming; it’s not a pipe dream.)
Waiting for Google
So I’m impatiently waiting for Google to announce more details. Exactly how will their system work? What does the user have to do? Which operators? Questions, questions.
Anyway, the future of mobile payments has come one step closer.
Vitamin
Around the Web: Inspiredology, Avatars in Motion, & Quite Strong
Hey there!
It’s Monday, so this roundup is devoted to all things web design (ux, photo, illustration, art, graphics, CSS, jQuery, tutorials, and more). Some links are newsworthy, some retweeted across Twitter, and others just meet our "awesomeness" requirement, and regardless we hope you'll enjoy them. Without further delay:
- Ever wonder what avatar development looks like when it gets really really good? Tiny Speck’s Glitch released a perfect & highly fun video about this very thing (via @playglitch)
- Inspiredology launches a fun redesign (anticipate some mad scientist quirk!)
- This might be the best read you read this week. “A Real Web Design Application” (via @jasonsantamaria)
- A fun find on Pinterest, Art & Design – Type & Love
- 5 creatives of the female variety, all based in Chicago, have united as @quite_strong (you’ll enjoy the quirktastic Twitter background) & indeed they are worth a follow, great things are ahead from this group
Wildcard: Trent Walton shared a little tip on how he and @yarcom design rounded avatars on Design-Swap, and a bonus? Dan Mall & Brian Hoff have swapped!
Please send me links to your projects, so we can help promote you and your work!
Handpicked by,
Chrissie @tenaciouscb
ajaxian
Canvas Color Cycling
Interest in Canvas, as well as mobile apps, has led to a renaissance of old-school 8-bit graphics. Joe Huckaby of Effect Games has been playing around with color cycling, leading to some stunning effects.
Anyone remember Color cycling from the 90s? This was a technology often used in 8-bit video games of the era, to achieve interesting visual effects by cycling (shifting) the color palette. Back then video cards could only render 256 colors at a time, so a palette of selected colors was used. But the programmer could change this palette at will, and all the onscreen colors would instantly change to match. It was fast, and took virtually no memory.
There's a neat optimization going on here too: instead of clearing and redrawing the entire scene with each frame, he only updates the pixels that change:
In order to achieve fast frame rates in the browser, I had to get a little crazy in the engine implementation. Rendering a 640x480 indexed image on a 32-bit RGB canvas means walking through and drawing 307,200 pixels per frame, in JavaScript. That's a very big array to traverse, and some browsers just couldn't keep up. To overcome this, I pre-process the images when they are first loaded, and grab the pixels that reference colors which are animated (i.e. are part of cycling sets in the palette). Those pixel X/Y offsets are stored in a separate, smaller array, and thus only the pixels that change are refreshed onscreen. This optimization trick works so well, that the thing actually runs at a pretty decent speed on my iPhone 3GS and iPad!
Vitamin
Exception Handling in PHP5
This article follows on from my earlier posts, introducing OOP in PHP, taking a closer look at OOP concepts in PHP, and also covering the various magic methods on offer in PHP 5. We’ll now move on to look at exceptions, which is how PHP 5 handles errors in an object-oriented way.
What are Exceptions?
Exceptions are the PHP 5 way of flagging up an unexpected event. They contain an information message, and can be extended just like any other object. Exceptions are thrown rather than warnings in newer PHP extensions, although you do still see extensions returning errors.
When an exception is thrown, we either catch it where it happens, or it causes the code to return to its calling context. If it isn’t caught there, it returns again, and so on. As usual it is easier to explain with examples than words!
Here is an example in which DateTimeZone objects are created, first with a valid timezone string of ‘Europe/Amsterdam’, then another with an invalid timezone ‘nonsense’:
1 2 3 4 | $timezone = new DateTimeZone('Europe/Amsterdam'); var_dump($timezone); $timezone2 = new DateTimeZone('nonsense'); |
As the documentation explains, DateTimeZone throws an exception when called with unexpected data. This indeed happens if you run the above script, and the exception appears as an error message from PHP, looking something like this:
Exception: DateTimeZone::__construct(): Unknown or bad timezone (nonsense) in /...../exception1.php on line 6
We don’t want our entire application to stop and spit out errors over a nonsense timezone, and working with exceptions means we can do so much more with these situations than we can with errors. We “catch” exceptions and can use the information in the exception itself and in the context of the current scope to decide how best to react.
This is a great improvement on the previous situation of having a few different error levels and only being able to choose whether to display, log or ignore each level as was the situation before PHP 5.
Handling Exceptions
We handle exceptions with a try/catch block like this:
1 2 3 4 5 6 7 | try { $timezone2 = new DateTimeZone('nonsense'); echo "time!"; } catch(Exception $e) { echo "Oops! Something bad happened!"; print_r($e); } |
The “try” bit goes around the code that you would normally write, but which contains operations which can cause an exception. The “catch” bit states what kind of exception to catch, and contains the code to execute if we do catch anything.
If you ran this script with a valid timezone as the argument to the DateTimeZone constructor, you would see the “time!” output and never enter the code inside the “catch” block. However in our example, an exception will be caused and so we jump straight into this block, without echoing “time!”.
This is a fairly key concept – the code in the try block actually stops and we jump into the catch block and start executing from there. Any code after the point at which the exception is throw simply isn’t run.
Inside an Exception
Exceptions can hold all sorts of information. If we inspect our Exception thrown by DateTimeZone’s constructor using print_r, we’d see something like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | Exception Object ( [message:protected] => DateTimeZone::__construct(): Unknown or bad timezone (nonsense) [string:private] => [code:protected] => 0 [file:protected] => /home/lorna/data/personal/publish/thinkvitamin/exceptions/exceptions2.php [line:protected] => 4 [trace:private] => Array ( [0] => Array ( [file] => /home/lorna/data/personal/publish/thinkvitamin/exceptions/exceptions2.php [line] => 4 [function] => __construct [class] => DateTimeZone [type] => -> [args] => Array ( [0] => nonsense ) ) ) [severity] => 2 ) |
Walking through the object, there are many useful elements here:
- message This contains a useful and relevant information message
- code By default this is zero but we can use this to include a numeric error code with our exception
- file Path to the file where this exception was thrown
- line Line number where the exception was thrown
- trace This is the stack trace, so you can see the stack of calls which were made before this exception was thrown
This is all valuable information and we can use it to inform how we handle errors in the catch block in our code. In addition we’ll take a look at how we can set these ourselves by making our own exceptions a little later on.
Throwing Exceptions
It isn’t only PHP itself that can throw exceptions, we can use exactly the same functionality in our own code. Here is a really simple example, taken directly from the PHP manual itself, of how to throw an exception manually.
1 2 3 4 5 6 | function inverse($x) { if (!$x) { throw new Exception('Division by zero.'); } else return 1/$x; } |
We simply throw a new Exception object, that we create as we need it. The string passed into the constructor becomes the object’s message property, and we can also pass a second argument to the constructor if we want to set the code property as well.
It is usual to throw exceptions in functions or methods, and then catch them from the location they are called – this lets the calling code decide what to do in the context of what it intended and is much more flexible than simple errors or having your methods return false and set an error string somewhere, which I’m sure is how I solved this before exceptions were introduced in PHP 5.
Extending Exceptions
The Exception object by itself is great, but we can extend it so that we can return additional information and different types of exceptions – so if one of a number of different scenarios actually happens, we can respond differently. Consider this script and in particular the takeTwoNumbers function:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | class BigNumberException extends Exception { } class FavouriteNumberException extends Exception { } function takeTwoNumbers($a, $b) { if($a > 15 || $b > 15 || ($a + $b) > 20) { throw new BigNumberException('Keep it simple with smaller numbers'); } elseif($a != 3 && $b != 3) { throw new FavouriteNumberException('But three is my favourite number!'); } else { return $a + $b; } } try { echo takeTwoNumbers(3,9) . "\n"; echo takeTwoNumbers(4,16) . "\n"; echo takeTwoNumbers(7,5) . "\n"; } catch(Exception $e) { echo $e->getMessage() . "\n"; } |
The function accepts two numbers, checks the values, and if there are any problems, throws a relevant exception. If the values are OK (and yes, this is a totally contrived example, in an effort to illustrate the concept without any complicating factors like the real world getting involved!) then the function simply adds them together and returns them.
Our calling script calls the function 3 times, with different number sets. The first one executes fine and the numbers get added together. However the second includes a large number and so an error is thrown, causing our code to jump to the “catch” block, and so the third function call is never made.
Although we declared empty classes to extend Exception here and so only the class name changed, you can do all sorts of things to help record the information you need. We would set custom error messages here (remember the helpful error message returned by DateTimeZone?), set error codes, or even set new properties of our own.
It depends on your application which of these is helpful but having the custom exception classes makes it very nice and tidy to do so. The differing class names let us detect what *kind* of a problem occured and what we want to do in response. When we catch an exception, we can state what kind of an exception we wanted to catch – so we can narrow ourselves down to only dealing with a known situation. We can also use multiple catch blocks, like this:
1 2 3 4 5 6 7 8 9 | try { echo takeTwoNumbers(3,9) . "\n"; echo takeTwoNumbers(4,16) . "\n"; echo takeTwoNumbers(7,5) . "\n"; } catch(BigNumberException $e) { echo "Big Number: " . $e->getMessage() . "\n"; } catch(FavouriteNumberException $e) { echo "Favourite Number: " . $e->getMessage() . "\n"; } |
In this example, we can handle the two types of exception differently. If any other type of exception were to occur, it wouldn’t be caught here, but instead would “bubble” up the stack, getting returned from the end of the second catch block to wherever this code was called from – in this very simple example we are in a simple PHP file but if we were nested in functions, the code would keep on returning until PHP caught the exception, or until it reached the top at which point it would show an error like the one we saw at the start of this post.
Uncaught Exceptions
So if an exception is thrown in a method, and not caught, it returns from the function to where that function is called from. If it isn’t caught here, it returns to where this code was called from, and so on until it reaches the top of the stack. If it gets to the top of the stack, uncaught, we’ll see the error we saw at the beginning of the post.
We can also give PHP instructions about how to handle any exceptions that get this far, using set_exception_handler. Many frameworks will do this and return nicely formatted messages, often logging the detail of the error so that users do not see it but developers can do so.
Here’s an example of a catch-all exception handling function:
1 2 3 4 5 6 7 | function my_exception_handler($exception) { error_log("Uncaught " . get_class($exception) . " exception: " . $exception->getMessage() . "\n"); } set_exception_handler('my_exception_handler'); throw new Exception('Oooops!'); |
All we need to do is declare our exception handling function and then tell PHP to use it for uncaught exceptions. This simple example simply passes a string to error_log function, which you can configure to behave however you need it to for your system. In a real-world application you might want to notify administrators of the problem or perhaps provide some nice feedback to the user in addition to logging the error.
Exceptions in Your Applications
Hopefully this has given some insight into what you can do with exceptions and how they interact with the rest of your object-oriented application. Even functional code needs awareness of exceptions since some core language elements now throw them, so it is worth making sure you have the exception handler declared alongside your existing error handler even if you don’t need to be extending or throwing exceptions yourself.
Are you extending the Exception class? What do you use this for? I’m really interested to hear about the various applications of this theory so let me know in the comments!
QuirksMode
New kid on the browser block: Samsung Dolfin
Back in early June I got a Samsung Wave that runs the brand-new bada OS and did some brief tests of the native Dolfin browser. In the past few days I’ve done some more extensive testing, and the verdict is in: good browser, well on the way to becoming excellent.
(Oh, and Dolfin ought not to be confused with Dolphin, which is a skin for Android WebKit.)
It’s Samsung’s philosophy that it will not compete in a market unless it belongs to the top three of that market. In the case of the mobile browsing market Samsung has succeeded: from nothing, Dolfin has become the third-best mobile browser in the world. Only iPhone and Android are better.
If you’re keeping track of the mobile browser landscape you should add Dolfin to your A-list. It’s easily good enough, and Samsung has big plans with the bada operating system. Somewhere in 2011 the installed base of Dolfin will pass that of Safari iPhone, and bada might even become a competitor to Android. (Samsung sure hopes so.)
I have updated my mobile pages with Dolfin data. (By the way, I also tested Android 2.2 while I was at it: few changes. There’s not a single difference with 2.1 in my great WebKit table.)
The good parts
Dolfin is only the third browser in the world to support the touch events, after iPhone and Android, and that’s a large part of the reason I count it as the third-best mobile browser.
Mobile browsers for touchscreen phones just must support these events by the end of the year, or they’re out of the race. (Opera, Firefox, Microsoft, NetFront, Nokia, BlackBerry, you have been warned.)
Dolfin’s implementation is even slightly better than Android’s. If I do a pinch-zoom test on my touch test page I use two fingers, and during replay I want the browser to show the position of both fingers. iPhone does so, Android doesn’t. Now Dolfin also shows both fingers’ position.
Unfortunately Dolfin is not quite up to iPhone quality: my multitouch drag-and-drop does not work. Still, the stuff it does support is quite impressive for a browser that didn’t exist at the start of this year.
Dolfin’s responsiveness to pinch-zooming is good. One friend who’s used to the iPhone even said it’s better than Apple’s implementation. I’m not quite prepared to go that far yet, but it easily gives Android a run for its money.
Dolfin incorporates a very modern WebKit version, and in my great WebKit table it is the best mobile browser, narrowly above Android 2.1/2.2 and comfortably above the iPhone 3.1 (4 not yet tested).
I’m currently working on a little side project: the perfect scrolling layer script for touchscreens. Obviously it should work in all three browsers that support the touch events. Of the three Android gives me the biggest problems right now, with Dolfin smoothly sailing along in the wake of the iPhone without any serious problems.
Dolfin is just a bloody good browser.
The buggy parts
Still, not all is rosy. I found a few bugs in Dolfin, and I’ll enumerate them here for the benefit of the Samsung team:
- The viewport dimension properties are an absolute mess. Not only do they generally give wrong data, but a few of them change meaning when a
<meta viewport>is present in the page. This must be addressed as soon as possible; it’s a show-stopper. - There’s a bug in the touchstart event. When you assign an event handler to it and execute it once, the event handler is removed. See this test page for the effect. Works fine on iPhone and Android, but fails in Dolfin the second time you want to drag the item.
The workaround, obviously, is setting the touchstart event handler again ontouchend. That works fine. - Dolfin is over-eager in firing the scroll and contextmenu events. Basically they always fire, even if an action does not result in a scroll or a contextmenu. (In fact, I haven’t yet discovered any contextmenu on Dolfin.)
These events should only fire if the scroll or contextmenu action actually take place. - The event coordinates are wrong:
clientX/YandscreenX/Ycopy the values ofpageX/Y, while they should report the coordinates relative to the visual viewport in CSS pixels and in device pixels, respectively. - A personal peeve: on the browser software keyboard the “Go” button is located on the left. A standard is emerging whereby it’s the right button that says “OK, do it,” while the left button says “Never mind.” I got confused by Samsung’s button placement more than once.
- Samsung bada is supposed to support W3C Widgets, but there is no way for developers to upload test widgets to the phone. In practice that means nobody will test on Samsung bada. This situation must be rectified.
Still, such bugs are only to be expected from a first release. In general Samsung has delivered a good browser that’s only a few small steps away from becoming excellent. I will follow Samsung’s next moves with interest.
ajaxian
Looking at JS emulator core for GameBoy
JavaScript as a general-purpose "Turing-complete language" is illustrated - the example discussed in the first part of a series: How a CPU can be emulated through JS, and how one might start building an emulation core for the GameBoy console. Looking forward: How a game image can be loaded into the emulator over the Web. For now: Hello, Z80! Check out Ice Station ImRannazar!
Powered by:
![]()
Hosted by: Keller Technologies Inc.








