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