fabi1cazenave / webL10n

Client-side internationalization / localization library
http://fabi1cazenave.github.com/webL10n/
279 stars 71 forks source link

getL10nData not working in Chrome #64

Open rhasan516 opened 9 years ago

rhasan516 commented 9 years ago

Hi, as part of porting Loqui (which uses this library) we are seeing a lot of undefined warning logs according to the following code:

function getL10nData(key, args, fallback) {
    var data = gL10nData[key]; // << basically gL10nData does not have the Key.
    if (!data) {
      consoleWarn('#' + key + ' is undefined.');
      if (!fallback) {
        return null;
      }
      data = fallback;
    }

It looks like load and parse l10n data is happening AFTER the warning is printed (set breakpoints, above code executes first before the loading is complete). The code in index.html is:

<script type="text/spacebars" name="welcome">        
    <h1>{{_ 'WelcomeTo' app.name}}</h1>
  </script>

However others are working:

<h1 data-l10n-id="Providers">Add accounts</h1> // << This works fine.

Thanks for your help.

paulguz commented 9 years ago

Yes, I see this too, intermittently. I think this is a knock-on from the fix for #48 and #52 made back in February which made loading of the properties files asynchronous at all times.

A workaround for now would be to set gAsyncResourceLoading to false to load the files synchronously. You'll get a "Synchronous XMLHttpRequest" warning in Chrome, but it's only a temporary measure until there's a fix for this.

rhasan516 commented 9 years ago

Thanks :) my team member told me this workaround works for now.

paulguz commented 9 years ago

SIlly me. On second thoughts, this isn't a bug.

Please see the comment above gAsyncResourceLoading in the source (which I didn't read before):

Synchronously loading l10n resources significantly minimizes flickering from displaying the app with non-localized strings and then updating the strings. Although this will block all script execution on this page, we expect that the l10n resources are available locally on flash-storage.

As synchronous XHR is generally considered as a bad idea, we're still loading l10n resources asynchronously -- but we keep this in a setting, just in case... and applications using this library should hide their content until the `localized' event happens.

So, start your application inside of an event handler for 'localized'. In my case, I have a Backbone application using require.js, so I start my application like so:

document.addEventListener('localized', function () {
    require(["app"], function (app) {
        Backbone.history.start();
    });
});
Rob--W commented 9 years ago

Use .ready instead of the event. This ensures that the callback is called even if the event has already been triggered.

document.webL10n.ready(function() {
   require(['app'], function (app) { Backbone.history.start(); });
});
paulguz commented 9 years ago

Thanks Rob. That means this also works (which I prefer, as require is pretty fundamental to the operation of the application!)

    require(["app"], function (app) {
        document.webL10n.ready(function () { //wait until l10n has finished loading resources
            Backbone.history.start();
        });
    });
paulguz commented 9 years ago

Hmm, I thought webL10n.ready() was working, but it seems not - I'm still seeing the "undefined" warnings from time to time. I've reverted to using the localized event.

Rob--W commented 9 years ago

@paulguz I've submitted a patch for your issue, could you check whether it solves your problem, and report back?

paulguz commented 9 years ago

@Rob--W Yes, that does seem to have made a difference. However, it only works if I put my require statement inside the ready() call; if I put the ready call inside the require(), I still see the warnings. So, this works:

document.webL10n.ready(function () { //wait until l10n has finished loading resources
      require(["app"], function (app) {
      Backbone.history.start();
    });
});

But this doesn't:

require(["app"], function (app) {
   document.webL10n.ready(function () { //wait until l10n has finished loading resources
        Backbone.history.start();
    });
});

Thanks.

Rob--W commented 9 years ago

@paulguz I have added another commit to #70, assuming that you're loading additional localization files using loadLocale. If that does not solve your issue, could you share a minimal project that demonstrates your problem?

paulguz commented 8 years ago

Hello again, after a whole year. I've been sidetracked in that time, but found myself looking at this again recently after upgrading dependencies in my project.

It appears that the last commit by @Rob--W has reintroduced the console warnings.

For the record, I'm not using loadLocale.

Unfortunately I'm too busy right now to put together a sample project.