summaryrefslogtreecommitdiffstats
path: root/application/basilisk/extensions/pdfjs/content/web/l10n.js
blob: e45cf200a5b95f95b4af3b79b12d94b0fc314a70 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
'use strict';

// Small subset of the webL10n API by Fabien Cazenave for pdf.js extension.
(function(window) {
  var gLanguage = '';
  var gExternalLocalizerServices = null;
  var gReadyState = 'loading';

  // fetch an l10n objects
  function getL10nData(key) {
    var response = gExternalLocalizerServices.getStrings(key);
    var data = JSON.parse(response);
    if (!data) {
      console.warn('[l10n] #' + key + ' missing for [' + gLanguage + ']');
    }
    return data;
  }

  // replace {{arguments}} with their values
  function substArguments(text, args) {
    if (!args) {
      return text;
    }
    return text.replace(/\{\{\s*(\w+)\s*\}\}/g, function(all, name) {
      return (name in args ? args[name] : '{{' + name + '}}');
    });
  }

  // translate a string
  function translateString(key, args, fallback) {
    var i = key.lastIndexOf('.');
    var name, property;
    if (i >= 0) {
      name = key.substring(0, i);
      property = key.substring(i + 1);
    } else {
      name = key;
      property = 'textContent';
    }
    var data = getL10nData(name);
    var value = (data && data[property]) || fallback;
    if (!value) {
      return '{{' + key + '}}';
    }
    return substArguments(value, args);
  }

  // translate an HTML element
  function translateElement(element) {
    if (!element || !element.dataset) {
      return;
    }

    // get the related l10n object
    var key = element.dataset.l10nId;
    var data = getL10nData(key);
    if (!data) {
      return;
    }

    // get arguments (if any)
    // TODO: more flexible parser?
    var args;
    if (element.dataset.l10nArgs) {
      try {
        args = JSON.parse(element.dataset.l10nArgs);
      } catch (e) {
        console.warn('[l10n] could not parse arguments for #' + key + '');
      }
    }

    // translate element
    // TODO: security check?
    for (var k in data) {
      element[k] = substArguments(data[k], args);
    }
  }


  // translate an HTML subtree
  function translateFragment(element) {
    element = element || document.querySelector('html');

    // check all translatable children (= w/ a `data-l10n-id' attribute)
    var children = element.querySelectorAll('*[data-l10n-id]');
    var elementCount = children.length;
    for (var i = 0; i < elementCount; i++) {
      translateElement(children[i]);
    }

    // translate element itself if necessary
    if (element.dataset.l10nId) {
      translateElement(element);
    }
  }

  function translateDocument() {
    gLanguage = gExternalLocalizerServices.getLocale();

    translateFragment();

    gReadyState = 'complete';

    // fire a 'localized' DOM event
    var evtObject = document.createEvent('Event');
    evtObject.initEvent('localized', false, false);
    evtObject.language = gLanguage;
    window.dispatchEvent(evtObject);
  }

  window.addEventListener('DOMContentLoaded', function() {
    if (gExternalLocalizerServices) {
      translateDocument();
    }
    // ... else see setExternalLocalizerServices below
  });

  // Public API
  document.mozL10n = {
    // get a localized string
    get: translateString,

    // get the document language
    getLanguage: function() {
      return gLanguage;
    },

    // get the direction (ltr|rtl) of the current language
    getDirection: function() {
      // http://www.w3.org/International/questions/qa-scripts
      // Arabic, Hebrew, Farsi, Pashto, Urdu
      var rtlList = ['ar', 'he', 'fa', 'ps', 'ur'];

      // use the short language code for "full" codes like 'ar-sa' (issue 5440)
      var shortCode = gLanguage.split('-')[0];

      return (rtlList.indexOf(shortCode) >= 0) ? 'rtl' : 'ltr';
    },

    getReadyState: function() { return gReadyState; },

    setExternalLocalizerServices: function (externalLocalizerServices) {
      gExternalLocalizerServices = externalLocalizerServices;

      // ... in case if we missed DOMContentLoaded above.
      if (window.document.readyState === 'interactive' ||
          window.document.readyState === 'complete') {
        translateDocument();
      }
    },

    // translate an element or document fragment
    translate: translateFragment
  };
})(this);