Site-Specific Preferences: Difference between revisions

From MozillaWiki
Jump to navigation Jump to search
(document the controller API)
Line 200: Line 200:


Question: would it make more sense for this to be read-only and for the service to use the grouper specified by an application-wide preference?
Question: would it make more sense for this to be read-only and for the service to use the grouper specified by an application-wide preference?
=== Controller API ===
The controller API is implemented as a JavaScript object in the chrome window context of browser windows.
Question: is "controller" conceptually an accurate description of this component?
It implements the following API for pref handlers to register themselves for notification of changes to preferences for the page currently being displayed in the browser:
  void addObserver(in AString name, in nsIObserver observer);
  void removeObserver(in AString name, in nsIObserver observer);
Question: should the controller let observers tell it to hold weak references to them?
The controller registers itself as a web progress listener and DOMContentLoaded event listener for the tab browser widget and then notifies its observers when the widget's location changes (nsIWebProgressListener::onLocationChange) or a DOMContentLoaded event fires for a browser in the widget.
For location changes, the controller notifies observers with the "content-pref-location-changed" topic, the URI of the new location as the subject, and the value of the site-specific preference for the new location (if any) as the data.
For DOMContentLoaded events, the controller notifies observers with the "content-pref-dom-content-loaded" topic, the document object whose content was loaded as the subject, and the value of the site-specific preference for the document (if any) as the data.
Question: are these the right topic names for these notifications?


== Extensibility ==
== Extensibility ==

Revision as of 23:58, 30 April 2007

Status

Content Preferences, a prototype extension implementing some of the proposed functionality, has been developed and is being distributed on AMO.

An API/architectural overview has been posted to mda.firefox and Myk's blog. Comments have been solicited, and some discussion has taken place.

The feature has been raised in Firefox and Gecko weekly meetings, and other features (f.e. a site-specific DOMStorage quota) have been identified as potential dependencies.

The feature has not yet been added to the Firefox 3 Product Requirements Document.

Overview

Motivation

The primary purpose of this feature is to enable users to specify their preferences regarding certain core browser and content settings (f.e. text zoom, character encoding, and page style) that affect web page appearance and behavior for specific sites rather than merely for specific tabs or for the browsing session.

Use Cases

Text Zoom

Every day, Joe visits a web site whose text size is too small for him to read it easily. After going to the site, Joe uses the View > Text Size > Increase command to increase the browser's text zoom value until the text is a reasonable size.

Joe has to do this each time he goes to the site, and when he leaves the site, he has to use the View > Text Size > Decrease command to return the text zoom to its normal value for the other sites he browses.

If the text zoom setting was site-specific, Joe would only have to change it once for the site whose size is too small, and he would never have to reset the setting to its normal value after leaving the site.

Note: John Lilly and Dan Veditz have described personal use cases which aren't satisfied by a site-specific text zoom.

John sometimes increases the text zoom for the browser in order to browse the web (including potentially multiple sites) while sitting farther away from his monitor. Afterwards, he decreases the text zoom back to its normal value.

Dan changes the text zoom each time he switches between two displays (I think his laptop's built-in display and an external monitor).

Although site-specific text zoom doesn't work well in these cases, tab-specific text zoom, which is what we currently have, probably doesn't work well either, because it makes them set (and later reset) the text zoom setting for every tab.

Character Encoding

-> Verify that the character encoding functionality currently in Firefox is accurately described in this section.

Jane lives in a country whose primary language uses a non-Western encoding. She frequently visits web sites whose character encoding is specified incorrectly (or not at all) by the server or page and is not correctly auto-detected by Firefox.

Every time she visits such a site, she has to set the correct encoding for it using the View > Character Encoding menu, but because Firefox only stores the character encoding for pages that she bookmarks, and then only for the specific bookmarked page (not for all pages on that site), Jane finds that she repeatedly has to set the encoding.

If the character encoding setting was site-specific (instead of or in addition to the bookmark-based page-specific mechanism), then Jane would no longer have to set the character encoding each time she visited a site for which it was set incorrectly. Instead, she could set it once and have Firefox reapply that encoding each subsequent time she visited the site.

Requirements

Service

P1 FR a service that stores and permits chrome code to get, set, remove, and observe changes to preferences for arbitrary settings on a site-specific basis P1 FR support for defining sites by host name P1 FR support for defining sites by ETLD + 1 P3 FR a hidden preference that allows users to switch between definitions of a site P3 FR ability for extensions to define and register additional site definitions

Controller

P2 FR a controller for each browser window that simplifies the process of listening for location changes and retrieving preferences for specific sites by defining an API that pref handlers can use for the purpose

Sidebar

P? FR a sidebar or other UI area that displays and allows users to set and unset the consolidated group of site-specific preferences P? FR support for setting the default value for each site-specific setting

Text Zoom Setting

P1 FR the value of the text zoom setting, which is set by commands in the View > Text Zoom menu or via the scrollwheel, is automatically recorded and restored on a site-specific basis P1 FR a mechanism for changing the default value of the setting

Character Encoding Setting

P2 FR the value of the character encoding setting, which is set by commands in the View > Character Encoding menu, is automatically recorded and restored on a site-specific basis

Page Style Setting

P3 FR the value of the page style setting, which is set by commands in the View > Page Style menu, is automatically recorded and restored on a site-specific basis P3 FR a mechanism for setting the default value of the setting to either "page default" or "no style"

Other Settings?

(are there other settings important and common enough to add to the core?)

Schedule

2006 December 12: Content Preferences (cpref) extension version 0.1 - first prototype implementation - announcement

December 13: cpref version 0.1.1 - minor bug fix release

2007 January 26: cpref version 0.1.2, minor bug fix release

February 13: cpref version 0.2 - second prototype implementation - announcement

February 14: API/architecture discussion started - blog post mda.firefox article

March XX: API/security review

March XX: cpref version 0.3 - third prototype implementation w/enhanced UI, addl. prefs, wider-scale testing

March/April: land service on trunk

April: cpref version 0.4 - fourth prototype implementation?

April/May: land additional elements of feature (controller, handlers for core prefs, sidebar or other UI) on trunk

May: release stable implementation of elements not destined for the core as extensions

Also see history of extension on AMO.

Design & Implementation

Documentation
Repository

The code for the feature currently lives in an extension. The service portion of the code should land in the Mozilla repository. The consolidated user interface for viewing and setting preferences should either land in the Mozilla repository or a Mozdev project repository depending on whether it ends up as a core component or remains as an extension.

API Changes

This feature changes no existing APIs, but it does add several APIs. First, it adds a application-wide "service" API for getting and setting site-specific preferences. Second, it adds a window-specific "controller" API for registering as a pref handler and observing pref-related events. Third, it adds a "sidebar" API for adding controls to a sidebar presenting a consolidated view of preferences for the current site.

Service API

The service is implemented as a JavaScript XPCOM component with contract ID "@mozilla.org/content-pref/service;1" that implements the nsIContentPrefService interface.

Core Methods

The service's core API comprises the following four methods:

 nsIVariant getPref(in nsIURI uri, in AString name);
 void setPref(in nsIURI uri, in AString name, in nsIVariant value);
 boolean hasPref(in nsIURI uri, in AString name);
 void removePref(in nsIURI uri, in AString name);

All four methods take as input a URI belonging to the site in question and a name for the preference. The service is responsible for extracting the name of the site from the URI.

Question: should we make the consumer responsible for extracting site names from URIs so consumers can set preferences for non-standard groupings?

The name of the preference is an arbitrary string. Preference namespacing is the responsibility of the consumer, as it is with the application-wide preferences accessed via nsIPrefBranch.

The setPref method also takes as input an nsIVariant representing the value of the preference, while the getPref method returns such an nsIVariant. Consumers can set the value of a preference to null (nsIVariant::VTYPE_EMPTY), and the service distinguishes between preferences set to null and those that have not been set by representing the latter as the undefined value (nsIVariant::VTYPE_VOID).

Getting All Prefs

The getPrefs method allows consumers to retrieve all preferences for a given site:

 nsIPropertyBag getPrefs(in nsIURI uri);

The method returns an instance of "@mozilla.org/hash-property-bag;1", which implements both the nsIPropertyBag and the nsIPropertyBag2 interfaces. Bag keys are preference names, while bag values are preference values.

Observers

The service also implements methods for adding and removing observers:

 void addObserver(in AString name, in nsIObserver observer, in boolean holdWeak);
 void removeObserver(in AString name, in nsIObserver observer);

When a pref changes, the service notifies observers via the "content-pref-changed" topic. The notification is similar to one nsIPrefBranch2 sends with the "nsPref:changed" topic, but it has two key differences:

  • nsIContentPrefService takes only an exact preference name (nsIPrefBranch2 permits a consumer to watch an entire preference branch by passing in a branch prefix like "foo.bar.")
  • nsIContentPrefService passes the new value of the pref in notification's subject parameter, which is an nsIPropertyBag containing the following properties:
    • group: the site (or other grouping) to which the preference belongs;
    • name: the name of the preference;
    • oldValue: the old value of the preference;
    • newValue: the new value of the preference.

Question: should the service support preference branches?

Question: should the service pass a custom component with a custom interface (like the LiveTitleNotificationSubject component with the nsILiveTitleNotificationSubject interface) instead of a property bag?

Question: is there any use for the notification's data parameter?

Groupers

Groupers are components that categorize URIs into groups (f.e. by site). They implement a simple interface, nsIContentURIGrouper:

   readonly attribute AString name;
   AString group(in nsIURI uri);

The name attribute is an arbitrary identifier for the grouper that the service uses to associate a preference in the database with the grouper responsible for determining its group. The group method returns the name of the group to which a given URI belongs.

Question: should we just use the contract ID as the arbitrary identifier for the grouper, and how do we retrieve that from an instance of the component?

The default grouper categorizes URIs by effective TLD + one additional hostname segment (i.e. example.com or bbc.co.uk).

Question: should the default grouper categorize URIs by entire hostname?

The service distinguishes between groups with the same name that have been categorized by different groupers to avoid collisions between groups that have the same name but are semantically different.

Question: should we make groupers responsible for namespacing group names to avoid these collisions the same way we make pref consumers responsible for namespacing pref names?

The service implements an attribute representing the grouper it uses to extract a site from a URI:

 attribute nsIContentURIGrouper grouper;

The attribute is read/write so that extensions can change the way URIs get grouped.

Question: would it make more sense for this to be read-only and for the service to use the grouper specified by an application-wide preference?

Controller API

The controller API is implemented as a JavaScript object in the chrome window context of browser windows.

Question: is "controller" conceptually an accurate description of this component?

It implements the following API for pref handlers to register themselves for notification of changes to preferences for the page currently being displayed in the browser:

 void addObserver(in AString name, in nsIObserver observer);
 void removeObserver(in AString name, in nsIObserver observer);

Question: should the controller let observers tell it to hold weak references to them?

The controller registers itself as a web progress listener and DOMContentLoaded event listener for the tab browser widget and then notifies its observers when the widget's location changes (nsIWebProgressListener::onLocationChange) or a DOMContentLoaded event fires for a browser in the widget.

For location changes, the controller notifies observers with the "content-pref-location-changed" topic, the URI of the new location as the subject, and the value of the site-specific preference for the new location (if any) as the data.

For DOMContentLoaded events, the controller notifies observers with the "content-pref-dom-content-loaded" topic, the document object whose content was loaded as the subject, and the value of the site-specific preference for the document (if any) as the data.

Question: are these the right topic names for these notifications?

Extensibility

Extensibility of this feature is a top priority, since numerous and popular extensions provide users with ways to alter browser settings affecting site appearance and behavior, and the ability to set preferences for those settings on a site-specific basis is a common function of (or feature request for) those extensions.

Examples of extensions that permit site-specific control over browser settings include Flashblock and NoSquint. An experimental version of the HashColouredTabs+ extension supports site-specific functionality via the version 0.2 of the Content Preferences prototype extension.

This feature should be extensible in the following ways:

  1. it should be possible for extensions to get and set site-specific preferences via the same APIs that core code uses;
  2. it should be possible for extensions to overlay themselves onto the site preferences sidebar so that their controls for setting preferences are visible alongside (or perhaps below) core controls and are as usable as the core controls;
  3. extensions should be able to register themselves as pref handlers in the same way that core code registers themselves as pref handlers and receive the same notifications that core code receives.

Should it be possible for extensions to override core pref handlers so that they can implement enhanced/modified functionality to that provided by the core handlers?

Should it be possible for extensions to provide additional ways of defining sites so that users who want a different way of looking at sites can get it and to promote innovation in site definition? F.e. one could say that all Mozilla domains (mozilla.org, mozilla.com) are a single site because they all relate to the Mozilla project, or one could define a site as every domain that uses an SSL certificate issued to the same organization, or every site that uses a certain stylesheet (for browser settings like text zoom and page style that affect style), or perhaps finer-grained controls that define different paths on a certain host as separate sites.

Customization

This feature adds customization controls to a sidebar, which has potential impact on many preferences and customization controls, particularly the Preferences > Content pane and items in the View menu like Text Zoom, Page Style, and Character Encoding.

The potential impact includes:

  • items in the View menu might start to affect browser settings on a site-specific basis rather than a tab- or page-specific basis;
  • the Content pane might provide an option for viewing and editing preferences for sites;
  • other site-specific lists in the Preferences dialog like the list of cookies and extension whitelists might be combined with UI for viewing preferences for sites generally;
  • items in the View menu and Content prefpane might be removed or modified in favor of UI in the consolidated preference view.

Performance

There are two notable potential consequences for a performance regression from this functionality.

First, as the user goes from site to site, the controller will get preferences for each site from the service, which queries the datastore for them. There is some cost to doing this, but it's not yet clear what that is. A test for this would be to populate a database with some site-specific preferences and then measure the amount of time it takes for the controller to retrieve a set of preferences for a site.

Second, because settings may be changed on a site-specific basis, switching from one site to another may now prompt costly changes to browser settings.

The effect of this is mitigated by the fact that such changes will only take place when the user has explicitly set preferences for a site, so users who don't use the feature won't be affected, and users who do use the feature probably are willing to experience the regression in exchange for the functionality provided.

But we should keep an eye on that latter assertion, since users may assume that site-specific preferences (at least those built into the core product) do not cause performance regressions and thus not understand why certain sites load more slowly than others. At a minimum, we must make it obvious and easy to undo a site-specific preference. And if settings built into the core product turn out to be costly, we should reconsider making them site-specific or provide additional feedback to the user about the cost (f.e. by providing progress or some other indication that the preference was applied) to inform the user about the cost so she can make an informed decision whether or not to accept it.

Reliability/Stability

In general, this feature should not impact reliability or stability, although it could expose or amplify the effect of bugs in core browser functionality (f.e. the code that adjusts text zoom) to the extent that it increases the frequency by which that functionality is invoked.

Security

The service and the controller are only available to chrome code, so they should have no security impact.

Site-specific preferences can be loosely grouped into "browser" and content categories. Browser prefs are those that affect the browser object (browser, docShell, presShell, etc.) embedded into each tab in Firefox, f.e. the text zoom preference. Content prefs are those that affect the document object for a given web page which is loaded into a browser object, f.e. the page style preference.

Existing prefs of either type should have no additional security impact, although they could expose security holes in core browser functionality to the extent that they increase the frequency by which that functionality is invoked.

New content prefs could have additional security impact, although no such prefs are being proposed yet.

To the extent that this functionality makes it easier to write extensions that add content prefs, however, it may cause the number of such extensions, and thus the danger of security holes in them, to increase.


Privacy

In general, site-specific preferences are not expected to be particularly high value or personal, but they can provide some information about users should be considered private. Preferences are stored persistently in a file in the user's profile, so they are subject to the same security measures we use to protect other personal data in the profile directory. Preference data is transiently stored in the memory of chrome objects to which content does not have access and in chrome controls to which content does not have access.

Global Audience

Since this feature introduces new UI, care should be taken to ensure that it remains accessible in the same way that the current non-site-specific UI is accessible.

L10n requirements apply as they do to other chrome.

Web Compatibility

Users might find that some of their preferences are incompatible with web sites, so it should be easy to remove a preference that results in an incompatibility.

To the extent this feature and its popularity causes web sites to become less insistent on appearing and behaving in a particular way, this feature should have a positive impact on web compatibility.

Other

Discussion & Implications

Caveats / What We've Tried Before

References