While working on the new localization API (See Intent to Implement post from 
yesterday), we're developing bindings into UI languages used by Firefox and we 
have some decisions to make that could be better answered by this group.

The general API is declarative and DOM-based.  Instead of forcing developers to 
programmatically create string bundles, request raw strings from them and 
manually interpolate variables, L20n uses a Mutation Observer which is notified 
about changes to data-l10n-* attributes.  The complexity of the language 
negotiation, resource loading, error fallback and string interpolation is 
hidden in the mutation handler.  Most of our questions in this email relate to 
what the best way to declare resources is.


1) HTML API

Our HTML API has to allow us to create a set of localization bundle objects, 
each with a unique name, that aggregate a set of localization sources.  It also 
has to allow us to annotate elements with L10n ID/Args pairs and potentially 
with L10n Bundle reference id.

Currently, our proposal looks like this:
    
<html>
  <head>
    <link rel="localization" name="main" href="./locales/resource1.ftl"/>
    <link rel="localization" name="main" href="./locales/resource2.ftl"/>

    <link rel="localization" name="menu" href="./locales/resource3.ftl"/>
    <link rel="localization" name="menu" href="./locales/resource4.ftl"/>
  </head>
  <body>
    <h1 data-l10n-id="mainTitle" data-l10n-args="{\"user\": \"John\"}" 
data-l10n-bundle="main" />
  </body>
</html>

Resource URIs are identifiers resolved by a localization registry which -- 
similar to the chrome registry -- knows which languages are available in the 
current build and optionally knows about other locations to check for resources 
(other Gecko packages, langpacks, remote services etc.). Localization bundles 
can query the registry multiple times to get alternative versions of a 
resource, a feature which makes it possible to provide a runtime fallback 
mechanism for missing or broken translations.

We're considering allowing names to be omitted which would imply the "default" 
bundle to reduce the noise for scenarios where only a single l10n bundle is 
needed.  There's also a document.l10n collection which stores all localization 
bundles by name, manages the Mutation Observer and listens to languagechange 
events.

The open questions are:

 * Would it be better to instead use custom elements like <l10n-bundle> 
<l10n-source src="…"/> </l10n-bundle>?
 * Are data-l10n-* for attributes OK?
 * Is there a better way to store arguments than stringified JSON?  We 
considered storing arguments as separate attributes (e.g. 
data-l10n-arg-user="John") but that would make it impossible to the Mutation 
Observer to know what to observe.
 * Any other feedback on the design?



2) XUL API

For XUL, we would like to use custom elements for bundles which are bound by 
XBL. The binding looks for <source> elements and creates a localization bundle 
object which is also available via the document.l10n collection.
    
<window>
  <localization name="browser">
    <source src="./locales/resource1.ftl" />
    <source src="./locales/resource2.ftl" />
  </localization>
  <label data-l10n-bundle="browser" data-l10n-id="foo></label>
</window>

The open questions are:

 * Can we use custom elements like <localization> in XUL?
 * Is there a more canonical way to do this?
 * Are there plans to replace XBL components with Web Components?
 * Is it okay to use the "name" attribute in XUL for the <localization> object?
 * Is it okay to use data-l10n-* attributes for localizable elements? Or 
perhaps l10n-* would be sufficient?



3) XBL API

For XBL, we plan to use the same XUL bindings but inside of the anonymous 
content.  Again, this creates a localization bundle object which is available 
via the document.l10n collection.

<content>
  <xul:localization name="tabbrowser">                
    <xul:source src="/browser/tabbrowser.ftl"/>                
  </xul:localization>
  <xul:label data-l10n-bundle="tabbrowser" data-l10n-id="foo"></xul:label>
</content>

Open questions:

 * We understand that this creates and destroys the element each time the 
parent is bound/unbound. Is there UI that does that on a timing-sensitive path 
extensively? That'd be good to measure.

 * Mutations inside of the anonymous content are caught be the document.l10n's 
observer;  are there plans to unify this with how mutations are handled in 
shadow DOM where observers observing non-anonymous content aren't notified 
about mutations in the anonymous content?



4) Performance measuring

We need to evaluate the performance impact of the change. So far we've been 
able to measure the loading time of about:support with DTD/StringBundle vs L20n 
using the  Performance Timing API and the results are promising (perf win!), 
but we don't know how representative it is for Firefox startup and memory.

Question: Which performance tests should we run to ensure that L20n is indeed 
not regressing performance of Firefox?


That's it for now. We appreciate your feedback and comments!
Your L10n Team
_______________________________________________
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform

Reply via email to