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
[email protected]
https://lists.mozilla.org/listinfo/dev-platform