JEP 102 - Single UI Element
- Champion: Aza Raskin - aza@mozilla.com
- Other Peeps: Alex Faaborg, Daniel Buchner, Jennifer Boriss, Dietrich Ayala
- Status: Under Review
- Bug Ticket: bug 543585
- Type: API
Proposal
/** Creates a new simple feature, whose properties are that it has a small 32x32 pixel display, as well as a larger display that defaults to 350px by 450px. @constructor @param options {object} @prop content {uri|html|xml|window} This is the small view of the feature. uri: A link to the URL of either an icon or a webpage html: A HTML string that will be rendered xml: E4X version of the above window: a reference to a DOM window object @prop [panel] {uri|html|xml|window|panel} See above descriptions. panel: A reference to a panel object If a panel is specified then the default action is that a click on the content area opens the panel. If you wish to override this behavior you do it in the standard way: by creating a new widget.onClick that returns false, or calls event.preventDefault(). @prop [on*] {function} You can optionally place event handlers in the constructor. **/ widget = require("widget").Widget(options); // Using the convention that constructors can optionally // take new or not. /** Event handlers @method @param callback {function} Potential to be all standard events. But for now: load, click, mouseover, mouseout **/ widget.on*( callback ) //f.e., widget.onClick() /** Remove event handlers. Without any arguments, all bound events are removed. If the function that was passed to bind is provided, only that specific event handler is removed. @method @param [callback] {function} **/ widget.on*.unbind( [callback] ) /** Enumerates all event handlers of the type specified, returning a list of event handlers. @method **/ for( var eventHandler in widget.on* ){ console.log( eventHandler ); } /** Removes the widget from the interface. @method **/ widget.destroy() /** @prop [content] {canvas|window} If there was a image passed into the constructor this will be a canvas you can draw on. It updates the displayed icon in real time. If there was a page, then this is a window element. @prop [panel] {panel} A reference to the panel object. **/ feature.property
Sizing
The bar can have two sizes: one where the height of the widgets are 24px and one where they are 16px. The size is set by the user/Firefox, and cannot be changed via this API. For now, the widgets are always rendered as if at a height of 24px and then scaled to 16px height.
Notes
- Do we want a
widget.listEventsHandlers()
?
Open Issues
- What are the conditions that we should impose on add-ons being included in this UI element.
- Need to figure out ContentFrames.
- How is overflow handled?
- Can users pin a widget?
- Can users change widget order? Via drag-and-drop?
- Can widgets stay alive, but manage their own visibility? (ie: only show if there's activity)
- Can widgets change their own position in the display? Or force themselves out of overflow into the visible set?
Dependencies & Requirements
- JEP 103 - Panel
- ContentFrame
- Update-allowable implementation of "icon" - may share similar implementation of content area with Panel and other JEPs
- Icons sizes should be in the following size formats: Large: 24px, Small: 16px
Use Cases
- Create a email notifier that shows you a small view that has the latest count/sparkline of emails yet to be read, and when you click on it it shows the detailed information about those unread messages.
- A clock, which has no detail view. Similarly, an x-eyes reimplementation (the eyes follow your cursor around).
- A Stumble Upon-style interface, where the small view allows you to upvote/downvote a page, and when a triangle is clicked shows a detailed view of ratings of this page.
- Snow-globe, where when you click it causes the snow to swirl around the page you are looking at. Clicking a little gear opens a detailed view for setting the color and strength of the snow storm. (Like the previous case.)
- An expanding search interface. It is displayed as a small search box. When you click in it, the search box expands in width with a quick animation. As you start typing, a panel appears which has search results listed in which you can arrow up/down, or mouse to.
Examples
Snow Globe
function SnowGlobe(win){ // ... } var globes = {}; widget = require("basic-widget").Widget({ content: "snowglobe.png", onClick: function(){ tabs = require("tabs"); var win = tabs.focused.contentWindow; if( !globes[win] ) globes[win] = new SnowGlobe(win); globes[win].shake(); } });
Mobile Reddit
widget = require("basic-widget").Widget({ content: "http://reddit.com/favicon", panel: "http://m.reddit.com" })
Wikipedia Lookup
widget = require("basic-widget").Widget({ content: "http://wikipedia.com/favicon", panel: "Loading..." }) widget.onClick(function(){ var sel = require("selection").text; var url = "http://wikipedia.com/search?q=" + sel; widget.panel.content = url; });