Widget/Gadget Containers: What are they good for?

Ajax, AjaxPatterns, Gadgets, OpenSocial, Shindig, Web, Web 2.0, Widgets

Background

Widgets are small “mini websites”, typically self-contained blocks of content, on a larger web page (with Ajax Design Patterns, I referred to them by the nom du jour Portlets). They are used in a couple of ways:

  • Embedded in a normal web page. For example, my blog currently contains a BBC weather widget and a “Twitter Badge” showing my latest tweets. Widgets embedded in this way are combined by the publisher, often with some manual HTML coding (script tags), and are usually a sideshow affair.
  • Combined within a widget container (aka “widget portal”, “Ajax homepage”). Websites such as iGoogle and NetVibes are primarily designed as widget aggregators, allowing an end-user to construct a personalised page for themselves. They are the Ajax/Web 2.0 successors of the “My <whatever>” hype (My Yahoo!, My Excite!, etc.) of the mid-to-late ’90s. To some extent, a social networks like Facebook fits into this category too, with the proliferation of applications available to users to embed on their homepages. And as Facebook in particular illustrates, widget containers are not always private “productivity tools”, but may also be available to a user’s friends or the general public. Indeed, the more conventional widget containers have recently started allowing users to make their public portals, which starts to move them in the territories of CMS and social networking.

Well, this is an article is about widget containers. Specifically, I’m currently compiling a list of typical features you’d expect to see in widget containers, so if this post sounds stream-of-consciousness, well, it sort of is.

Anatomy of a Widget (well, Gadget and OpenSocial) Container

A good place to start is the breakdown of functionality for Shindig, the new Google-supported Apache project to build a reference implementation for the OpenSocial standard. OpenSocial is heavily intertwined with the whole idea of widgets and widget containers, since it’s basically Google Gadgets + standardised social networking APIs. Hence, Shindig is essentially the high-profile open-source project involving a widget container. Shindig has been broken into four parts:

  • Gadget Container JavaScript — core JavaScript foundation for general gadget functionality (read more about gadget functionality). This JavaScript manages security, communication, UI layout, and feature extensions, such as the OpenSocial API.
  • Gadget Server — an open source version of gmodules.com, which is used to render the gadget xml into JavaScript and HTML for the container to expose via the container JavaScript.
  • OpenSocial Container JavaScript — JavaScript environment that sits on top of the Gadget Container JS and provides OpenSocial specific functionality (profiles, friends, activities).
  • OpenSocial Gateway Server — an open source implementation of the server interface to container-specific information, including the OpenSocial REST APIs, with clear extension points so others can connect it to their own backends.

That’s a very useful overview, though I’m looking more at specific features which generally cut across at least some of these parts. For example, gadget preferences. These are part of the container Javascript because there is a UI to change the preferences, they are part of the gadget server because it must initialise the gadget according to preferences, and they are part of the server because they must be persisted.

Feature List

First cut at a feature list (# indicates not directly available in iGoogle)

Gadget Preferences

  • Preference defaults
  • User can set preferences
  • Publisher can set preferences when embedding widget on a page
  • Preference variable types: string, enumerable (set by dropdown, set by combobox), boolean, list, location, etc
  • Preference persistence: by database against session vs. in cookie
  • Preferences persisted for anonymous user (Lazy Registration)
  • Gadgets can access preferences via API, consistent access regardless of content type and embedding model
  • # Gadget can be notified of preference changes, so that it’s not necessary to reload the entire gadget/page after each change

Gadget Appearance

  • Gadget appearance customisable by publisher
  • Gadget appearance customisable by user
  • # Round corners, shadows, background images (e.g. Schmedley has all of these)

Gadget Content Type

See Widget Content Type article * HTML – from container provider’s domain * URL – from gadget provider’s own domain * # Inlined – embedded on container. This implies a security model, e.g. Caja

Container Appearance

  • User can change gadget skin, header, footer, background, widget preferences via constrained mechanism (ie can’t change everything; e.g. config file or UI)
  • Publisher can change look and feel via HTML/CSS
  • Gadget themes available, with gallery, for pre-defined configurations
  • Animation used for features such as preference setting and expand/collapse of widgets
  • Drag-and-drop shows preview of page appearance after drop

Container Layout

  • Multi-column (usually 3) vs. freestyle
  • Gadgets can be dragged around the page, displacing other gadgets
  • Tabs allow for multiple layouts
    • Tabs can be renamed
    • Gadgets can be dragged into tabs

Gadget Manipulation

  • Gadgets can be added
    • by URL (with security warnings etc)
    • from Gallery (see Gallery below)
    • by cloning a gadget on user’s page or someone else’s public page or external page
  • Gadgets can be removed
  • Can limit singleton gadgets to one instance per container

Gadget Gallery

  • Gadgets displayed and rendered with metadata embedded in gadget spec, e.g. thumbnail image, author, etc.
  • Gadgets can be browsed by category, date added, etc.
  • # Users can tag gadgets and gadgets can be browsed by tags; tag cloud; etc
  • Users can rate gadgets
  • # Users can recommend gadgets to their friends
  • Users can comment on gadgets

Gadget-To-Gadget Communication

  • Gadgets can communicate with each other (Google PubSub)

Gadget Size

  • # Gadget content can be expanded and collapsed (BBC Beta Homepage)
  • Gadgets can be dynamically resized

Content Sharing

  • Container can be made public (what happens to personalised widgets?)
  • Container can be shared with “friends” (how are friends decided)
  • Users can invite/permit/disallow friends to use their container

Gadget Services

  • Proxying service
  • Caching service (extends proxying service)
  • OpenSocial (or generic social networking) service
  • # Advertising service – Gadgets can serve as ads with revenue model
  • # Financial service – Gadgets can charge for services (subscription, one-off, etc.)

Admin Functions

  • Admin function to tweak gadget/theme rankings, scrutinise/moderate/eliminate gadget/theme submissions, etc
  • Admin function to view metrics, e.g. number of page views, popularity of gadgets, back-end service usage (e.g. proxying and OpenSocial calls)
  • Admin function to manage users (provide support, ban, etc.)

Where Do Widgets Come From? A Look at Widget/Gadget Content Types

Ajax, AjaxPatterns, Gadgets, Google, Web, Web 2.0, Widgets

Background

A while back, I walked through a Google Gadget I made called Digg Roundup, which simply shows Digg headlines and can be customised on topic and popularity. In my quest for an uber-simple tutorial, one thing I skipped on was content type, the subject of the present muttering. There are several content types possible, each with distinct implications for the page architecture and where the gadget sits within it. Below I’ll explain the options and help you understand how to decide between them.

A gadget is always expressed as some XML sitting at a URL somewhere on the net. When a developer uploads a gadget to Google, all they do is indicate their server location where the gadget is hosted. So a user’s iGoogle homepage is really just a bag of URLs (with layout and preferences for each). Anyways, the gadget is really a mini web page, and inside the gadget XML is a content tag that describes the HTML, CSS, and Javascript that makes up this page. The tag has a type attribute (i.e. <content type="xxx">) and there are three types available…

Three Content Types

html (<content type=”html”>)

All the page content is included in the XML file. It’s just like your standard web page HTML; it contains the (initial) HTML body from top to tail (sans enclosing <body> </body> tags), and CSS and Javascript, which can be inlined or linked, just like a normal web page. The content will be served in an iframe and Google will wrap its own html content around it. In particular, Google will look at other info in your XML file and output html code at the top, such as pulling in libraries and setting up preference data. Incidentally, Google won’t add any visual wrap around the widget at this stage; that is the responsibility of the container, which could be iGoogle, Ning, or any standalone web page that chooses to render the gadget.

Although the XML is held on your own server, the iframe will ultimately be served from a Google subdomain as its source. e.g. gmodules.com/blahblah. If you look at iGoogle, you’ll see the source is actually something like 50.gmodules.com/blahblah. The point of the “50” is that each gadget on a page comes from a different subdomain, thus isolating gadgets on the same page from each other for security reasons (there are ways around that restriction for consenting gadgets).

The main differences between a <htm> gadget and a normal web page is that your content must be static – the XML file cannot be generated on the fly by your server, because Google will cache it. Think of this kind of gadget as a single file that describes your gadget in isolation, which you could mail around or stick on a USB key. The dynamic behaviour comes from the fact that you can link to external CSS and Javascript (which could be generated on the fly) and, moreover, you will typically be making remote calls once the application is running (either on startup, due to a timer, or in response to system events).

url (<content type=”url” href=”myserver.example.com/…”>)

url. This could alternatively be called “external” or “hosted”. You simply provide a URL on your own web server and deliver up the gadget content from there. Specify “example.com” and the user will see an iframe pointing to “example.com”. The content for url gadgets must be dynamically generated, the exact opposite of html gadgets, which are always static. This is due to the way these gadgets use

html-inline.

This is no longer supported, but it’s worth knowing because (a) the contrasting model helps you understand the other models; (b) older gadgets, as well as Google’s own gadgets, are still able to use this model; (c) Google says they might allow special cases through in the future; (d) other containers do support this model (NetVibes anyway). In contrast to the previous types, inlined gadgets are not contained in an iframe; they are served as plain old HTML embedded into the fabric of the page. Just some content in a div.

A Note on Preferences

Persistent preferences are a key feature of widgets. Just a quick note that preferences work slightly differently on html vs url widgets (and inline, but I didn’t look into it).

With html widgets, the preferences are set as part of the HTML wrap around your widget’s HTML. ie some Javascript variables are set up.

With url widgets, the iframe source URL includes some CGI parameters expressing the preferences (e.g. up_storyAmount=5).

Either way, though, Google’s preference library abstracts this detail. As long as you declare a dependency on the library, it will be included and will let you access preferences the same way.

Decisions, Decisions: Which content type to use?

So that’s the definitions. Let’s look at the capabilities of each and understand how we might make decisions on which model to use.

Inline or IFrame (content-type=html/url)?

Firstly, inlined (html-inline) versus iframed (html and url), assuming inlined is an option for you. Living in the same DOM means that inlined gadgets can talk to each other; dead simple cross-gadget communication is a key benefit of the inlined model. Furthermore, gadgets and the main portal page can talk to each other. You can change the Google logo, for example, or put up a lightbox effect across the entire page.

Not too surprising that raw inlined gadgets were banned; the security risks are high. e.g. An inlined gadget that asks for your gmail credentials would end up storing username and password in global page space, which means a second gadget could simply read that data and upload it somewhere. You could also screw with iGoogle’s branding, which Google PR probably didn’t appreciate and could lead to phishing attacks. Google could rely on code reviews to minimise the risk of inlined gadgets, but that’s a very manual, unscaleable, approach, and users can in fact add gadgets from any URL (although they made it a lot harder to do that a few months ago; AFAICT you need to use the developer gadget in order to add a gadget that’s not in the catalogue). Maybe inlined gadgets will come back if a product like Caja proves itself worthy of automatically sanitising web apps. It’s a hard problem, but there are some good benefits to be had if widgets can live safely together on the same page and domain.

In summary, choose inlined only if you need the extra functionality available and only if you have assessed the risks of tampering from third-party widgets.

IFrame from widget server (content-type=html) vs IFrame from your own server (content-type=url)

Second and really the key decision you have to make with Google Gadgets today, html versus url. Reason to choose “html” content type over “url” content type:

  • Javascript API. You can use the full Gadget Javascript API with no effort – you don’t even have to include a script tag because iGoogle injects it for you. With the “url” type, using the Gadget Javascript API is a hassle – you have to dynamically generate the script tag, which is not only a bit of scripting effort, but forces you to generate your iframe from a script. Furthermore, cross-domain restriction means that even if you do pull in the API, you can’t use the remoting support (the _IG_Fetch* functions for proxying and caching).
  • Cross-gadget communication. You can run cross-gadget communication using the Pub-Sub framework.
  • Resources. Google serves it for you, which saves bandwidth and maintenance costs. In fact, you will have zero bandwidth costs if your widget functionality is either self-contained (e.g. a calculator) or only hits third-party services (as opposed to your own servers’ services).
  • Popularity. Pure speculation, but you’re probably more likely to be featured in Google’s gadget gallery as they can inspect everything about your application’s workings (except for any remote calls back to your server).
  • Inline-like. If inlined widgets do make a comback, you’ll have an easier migration path.

Reasons to choose “url” content type over “html” content type:

  • Full page refreshes. Because it’s coming from an external iframe, you can do traditional, non-Ajax, programming. ie. User clicks on link to see a new page. User submits a form. Page auto-refreshes. With this type of widget, you could write a perfectly working gadget without knowing a button of Javascript.
  • Personalisation and Security. You can make XHR calls from the widget directly to your own server and make use of any cookies that have been set up. e.g. If the user has already logged into your main web app, then you widgets will be able to present personalised data. With “html” widgets, you would only be able to make use of cookies using cross-domain JSON, and cross-domain JSON is unsafe. You could possibly do it more safely using the cross-domain iframe fragment identifier hackFacebook’s new JS lib works that way – but I haven’t investigated it.
  • You can easily host the widget as a standalone web page (though it’s largely pointless and will look silly unless you pull some CSS madness).

Want to Learn More?

Dynamic Favicon Library Updated

Ajax, AjaxPatterns, Favicon, HTML, Javascript, Web, Web 2.0

I updated the favicon library a while ago, for a couple of projects I haven’t released for various reasons. Anyway, Phil asked me about it, so I thought it’s a good time to package it up and release it properly. And in the process wrote up Taking Browser Tabs Seriously which has also been on the backburner.

The main point of this library is to update the favicon via Javascript, but at a higher level, its main objective is to provide some support for notifying the user of events in another tab. For example, if you start playing music in another tab, you can make a one-liner call to change the favicon to a sound. Or if you really need to alert the user, you can start animating it.

See the original post for more info. The new features are:

  • Scrolling title. The window/tab title scrolls. (Title blink is coming. No, really!)
  • Stop functions. unanimate() and unscroll() will stop animation and scrolling, respectively. Previously you had to do stop animation indirectly, by calling change().
  • Rails/Scriptaculous style options Changed config to be fn(mainarg, optionalHash). Read the library or demo source to see the details.

Demos:

API (also in the code):

javascript

  1. favicon.change("/icon/active.ico", "new title"); // Cancels any animation/scrolling
  2.     favicon.change("/icon/active.ico"); // leaves title alone. Cancels any animation.
  3.     favicon.change(null, "new title"); // leaves icon alone. Cancels any scrolling.
  4.  
  5.     favicon.animate(["icon1.ico", "icon2.ico", ...]);
  6.     favicon.animate(["icon1.ico", "icon2.ico", ...], {delay: 500} );
  7.       // Tip: Use "" as the last element to make an empty icon between cycles.
  8.       // Default delay is 2000ms
  9.     // animate() cancels any previous animation
  10.  
  11.     favicon.scrollTitle("new title");
  12.     favicon.scrollTitle("new title", { delay: 200, gap: "------"} )
  13.       // delay is delay between each scroll unit
  14.       // gap is string appended to title (default: "      ")
  15.     // scrollTitle() cancels any previous scrolling
  16.  
  17.     favicon.unscroll();
  18.  
  19.     favicon.unanimate();

Maybe in another two years, I’ll update it again. The main enhancement would be to combine it with audio notifications (with or without Flash, depending on the browser). So you could make a single call that (a) changes favicon; (b) scrolls the title; (c) plays a sound. Now that will get their attention!!!

Taking Browser Tabs Seriously

I’ve just updated my favicon library, which I first wrote about here. I’ll explain more about the update in a separate post. For now, I want to talk about browser tabs.

Browser tabs were introduced by Opera. Then Firefox adopted them a few years later, as did Safari. Then Microsoft stepped into the ’90s with their own IE tabs. Meanwhile, tabs became teh coolness and Kevin and Alex joked on Diggnation about how you could get brownie points by saying it’s a tabbed interface. And so you get tabbed terminals among other things, and fortunately there is some consistency on keyboard shortcuts (typically ctrl-t to make a new tab and ctrl-w to close it, or option-t/w on mac).

We’ve outgrown the rudimentary functionality that is available for managing tabs.

The browser is the new operating system, the tab is the new system process, the tab bar is the new taskbar.

Power users struggle to keep up with 20+ browser tabs and grasp what’s inside them. The Firefox Tab Mix extension is a superb addition and should be part of the core. But there is a lot more that could be done, for instance:

  • Notifications. The whole issue of attention and notifications needs re-thinking in light of the new world of rich web apps. Quintessential example is web chat – how do you inform the user someone has sent a message, in another window? The favicon library helps here, and the update in my next post, helps a bit more. Playing a sound is also possible. Still, I would like to see API support for ambient dialogs, like Growl/Snarl and the Windows “sunrise” notfier that emerges from the taskbar (what’s it called officially?). And sound. It’s 2008, why can’t browsers issue a single beep like a good 1970s PC, without requiring flash or unreliable hacks!!! Speaking of sound …
  • Where’s that sound coming from? There’s a sound in my browser, but I don’t know where! Tabs should provide a visual indication if a sound is emerging from them.
  • Default/Custom Favicons. If a site doesn’t have a favicon, browsers show nothing. Bzzzt!!! They should provide more sensible defaults, e.g. at least show the site’s background colour or a thumbnail of the first image. Something to make them all different from each other.
  • Provide a Summary List. Like clicking on Ctrl-Alt-Delete in Windows to get a task list or “ps” in Unix. You’d be able to see how long each tab has been open, memory usage, other excitement.
  • Hover info Similar to the previous point, let web developers provide tooltip info which will be displayed as the user hovers over the tab.
  • Popup menus Why even open up a web page? Sometimes, you want to do something quickly without having to switch tabs. Let web developers create site-specific popup menus that emerge from the tab. For example, you could use this mechanism to record simple events as they occur. Or start and stop a timer. Or to switch channels on a music website.
  • COLOUR AND STUFF!!! Browser tabs are pretty dull – just an icon and some text. Using cues such as colour and font styles, the browser could say a lot more about what’s happening in the other tabs. Perhaps it could be set by the programmer or perhaps it could be set by the user (e.g. create a heatmap highlighting the least used tabs).
  • Javascript events. Javascript onEntered()/onExited() events to let the application know if it’s active or not. (Similar to what desktop apps receive.) This would be absolutely brilliant for when you are notifying the user about something they need to see (e.g. a new chat message) – once they re-enter the tab, you can switch off the notification.
  • Open Forms. What about when I start writing something in a form, then switch tabs, and forget which tab has the form, or forget that it’s there at all. The browser should indicate when there’s a form open that you’ve been writing to. (Though in some cases auto-backup features may mean that’s not necessary.)
  • Search. No-brainer. Browser search should work across all tabs, not just the one currently open. This would not only help you find some text, but also pinpoint one of the fifty tabs you have open.
  • Virtual Desktop. Maybe it sounds mad, but I’d like something similar to virtual desktop (“Spaces” for Mac-heads). ie Switch from “work” tabset to “social” tabset, etc.
  • Auto-remove. Instead of forcing me to close all windows, or some random subset, or restart the browser altogether, provide some support for removing the tabs that matter least. e.g. the tabs that I haven’t used for the longest and which I appear not to have interacted with (ie started editing a form), and/or the tabs that are taking up the most resources.

I’m sure there’s a lot more. The main point is to take inspiration from the way operating systems let users deal with open applications, and then some. The dynamic favicon library is a small part of the solution, but there’s only so much libraries and even browser add-ons can do…it needs to become a core feature of the browsers. Just as Opera and then Firefox owe a big chunk of their initial popularity to their the cult of the tab, so too do the manufacturers today have a similar opportunity to take it to the next level.

CSS Coding Style and the Unbearable Tendency for People to Adore Whitespace in their Source Code

CSS coding style doesn’t get a lot of play. Most people are happy to stick with the convention of one property per line, like this:

  1. #score {
  2.   background: yellow;
  3.   width: 12em;
  4.   border: 1px solid orange
  5.   padding: 2em;
  6.   margin: 3em 0;
  7.   display: none;
  8. }

I, for one, can’t stand that style. I’m heavily biased towards information-dense coding styles, which don’t have much whitespace. People mechanically argue “oh but whitespace is so important etc” as if we were designing a modern art installation. Well, whitespace is indeed essential, but you have to discriminate between a touch of elegant whitespacing for the sake of clarity, and “oh dear! My 80-column row seems to have just 12 characters on it. Come to think of it, every row on my 30-inch Cinema Display has 12 characters on it.” Seriously, I don’t know why anyone would use an 80-column terminal anymore, unless they enjoy coding on their iPhone. I tend to think 120 or 160 is ideal; any more than that and most people won’t be able to see the whole thing without moving their head. Anyway, I’ll be conservative and assume 80 columns. The average end column in the above code snippet is roughly 15, which means in your scrawny 1975 80-column terminal, you’re filling 20% of it with information and 80% with whitespace.

There’s an old figure that says the average programmer codes 10 lines per day. It’s obviously not a very accurate figure and maybe it was meant to include all the non-programmers on the project or something, but the point is interesting, as there’s probably some reasonably consistent LOC per developer figure (obligatory mutatis mutandis caveat). Seizing on this historical figure, Bruce Eckel said a while ago (paraphrasing) “if I only get 10 lines a day, I want them to be good ones”.

That’s why I favour information-dense coding styles. As a programmer, you’re supposed to be an expert user who spends all day in front of the same system. This is a typical example of a situation which demands a “Sovereign Posture”. It’s an expert system. When people long for glorious pastures of whitespace, they’re ignoring the fact that with sufficient practice, they’ll be virtually as proficient at reading and writing a more information-dense style, and vastly more efficient by having so much more code available at any time. It’s the same reason why Real Programmers commit to learning Unix and Vi or Emacs; if you’re going to spend decades working in this environment, why wouldn’t you spend a few days committing to the most efficient tools available?

For the record, I still have plenty of whitespace in my programs, but when there is a decision to be made between one popular convention and another, I almost always go for the one which reduces whitespace. I have enough faith in programmers’ pattern-detection skills to know that in time, they will be fine with either style, but the one with less whitespace will always give them more bang for their Cinema Display buck.

Back to CSS. Here’s how I’d format the above snippet:

  1. #score { background: yellow;  border: 1px solid orange;
  2.              width: 12em;  padding: 2em;  margin: 3em 0;
  3.              display: none;
  4. }

What I do is group similar attributes on each line. I’m pragmatic about the precise rules. If it’s just a handful of properties, I’ll stick them all on the same line. If there’s more than that, then typically I’ll have one line for appearance (colour, fonts, etc.), another for layout, and possibly more for other things like display settings or detailed positioning. You also don’t need whitespace between each rule either, so you can often end up with a whole sequence of related one-liner rules:

  1. /******************************************************************************
  2.    SCOREBOARD
  3.  *****************************************************************************/
  4. #scoreboard { background: black; color: white; }
  5. #homeTeam, #awayTeam { color: pink; text-align: right; position: absolute; }
  6. #homeTeam { top:20px; left: 120px; font-size: 8em; }
  7. #awayTeam { top:80px; right: 120px; font-size: 5em; }
  8. ...
  9.  
  10. /******************************************************************************
  11.    ARENA
  12.  *****************************************************************************/
  13. .player { color: #f99; }
  14. .runner { color: #99a; }
  15. ...

This format is not only denser but also easier to comprehend as related properties are grouped together. The typical one-line-per-property format tends to include a random jumble of properties; rarely does any thought go to the order in which the properties appear.

Another thing that helps with CSS brevity is learning shorthand formats. Use “border: 1px solid orange” instead of “border-width: 1px; border-style: solid; border-color: orange”. Use “margin: 3em 0;” instead of “margin-left: 3em; margin-right: 3em;”, and so on.

The Little Bug that Could: Firebug Book Chapter

<gush> Firebug is awesome. Joe Hewitt is a legend.

As I’ve said before, Firebug is among the most usable software tools ever developed. I don’t just mean compared to other software development tools. I mean against all user-facing software. It’s single-handedly improved my Ajax productivity by at least 100% (that’s my estimate when making changes to larger Ajax code bases). It’s made Ajax development much easier to get into for newbies and a much more pleasurable place to be for all developers. </gush>

So I’m pleased to announce I’m writing a chapter about the bug in the upcoming Sitepoint text, The Art & Science of JavaScript”. To be published by Sitepoint and with coauthors Simon Willison, Christian Heilmann, Ara Pehlivanian, Dan Webb, Cameron Adams, James Edwards, and others. I can’t talk about timelines, but you’ll notice the Amazon entry above is stating January ’08.

Would you like to review the chapter? Drop me a line – [email protected]

As well as explaining the various parts, I’ll be sharing tips on when to use different features and how to get the most value out of them. Here’s an outline:

* Meet the Bug
  What is Firebug, when to use it, overview of functionality, how it has
    impacted modern web development.·
  What's missing at time of writing (other browsers, cookies)

  • Installing Firebug

    Downloading and installing the plugin, opening it up and enabling it for certain sites. Windowed vs docked mode

  • Firebug Anatomy and Idioms

    Overview of sections in the Firebug window

    Idioms - point out that most things are cross-linked, searchable, and editable. Options menu.

  • The Console

    Introduces a sample application used throughout the chapter, then introduces the console (logging, errors, running JS commands).

  • Viewing and Editing Your App on the Fly

    • HTML
    • Including Layout and Style
    • Mention Inspect option in popup menus.
    • CSS
    • Javascript
    • DOM
  • Debugging Your App

    • Breakpoints and tracing
    • Watches
    • Stack trace in the console
  • Performance Tuning Your App

    • "Net" tab
    • Profile button
    • YSlow
    • Reference Related Tools below
  • Related Tools

    • Firebug Lite

    • YSlow

    • Microsoft Script Debugger

    • Other Firefox Extensions

    Brief list of a few other useful/alternative extensions, e.g. Web Developer Toolbar, Measure-It, Stylish

Ajax Patterns Lookalike

So there’s this Japanese R&D blog that focuses on covers and spotted an uncanny resemblance.

Ajax本が一杯出てきているけど、トウトウこんな本まで登場です。

Ajax Design Patterns
http://www.oreilly.com/catalog/ajaxdp/index.html

Ajax Design Patterns

  • 作者: Michael Mahemoff
  • 出版社/メーカー: Oreilly & Associates Inc
  • 発売日: 2006/07
  • メディア: ペーパーバック

カバー表紙が「バクダッド・カフェ」風味。ちょっと惹かれる。

 

紀伊国屋、DVD「バクダッド・カフェ 完全版」を4月25日に発売
―日本初公開版に、カットシーンを追加した完全版で登場
http://www.watch.impress.co.jp/av/docs/20030204/kino.htm

少しは読もうかな?

Bagdad Cafe is an arthouse that was always in the video library but I never watched. The film runs 95 minutes in the U.S. and 108 minutes in the German version). It is a somewhat surreal comedy set in a down-at-heel truck-stop café and motel in the Mojave Desert. An ill-assorted cast of characters are assembled, including a plump German tourist (Sägebrecht as Jasmin) who has left her husband after a row in the middle of the desert, the short-tempered owner of the café (Pounder as Brenda) who has just thrown her husband out, Brenda’s two children and grandchild, a strange ex-Hollywood set-painter (Palance), and a glamorous tattoo artist (Kaufmann). Through a passion for cleaning and for magic tricks, Jasmin transforms the café and all the people in it.