forked from 0x2620/pandora
update pdf.js
This commit is contained in:
parent
e1967e96bc
commit
7ac68697d4
116 changed files with 49715 additions and 39660 deletions
|
|
@ -24,9 +24,10 @@
|
|||
- Disables language initialization on page loading;
|
||||
- Removes consoleWarn and consoleLog and use console.log/warn directly.
|
||||
- Removes window._ assignment.
|
||||
- Remove compatibility code for OldIE.
|
||||
*/
|
||||
|
||||
/*jshint browser: true, devel: true, globalstrict: true */
|
||||
/*jshint browser: true, devel: true, es5: true, globalstrict: true */
|
||||
'use strict';
|
||||
|
||||
document.webL10n = (function(window, document, undefined) {
|
||||
|
|
@ -98,14 +99,14 @@ document.webL10n = (function(window, document, undefined) {
|
|||
document.dispatchEvent(evtObject);
|
||||
}
|
||||
|
||||
function xhrLoadText(url, onSuccess, onFailure, asynchronous) {
|
||||
function xhrLoadText(url, onSuccess, onFailure) {
|
||||
onSuccess = onSuccess || function _onSuccess(data) {};
|
||||
onFailure = onFailure || function _onFailure() {
|
||||
console.warn(url + ' not found.');
|
||||
};
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', url, asynchronous);
|
||||
xhr.open('GET', url, gAsyncResourceLoading);
|
||||
if (xhr.overrideMimeType) {
|
||||
xhr.overrideMimeType('text/plain; charset=utf-8');
|
||||
}
|
||||
|
|
@ -142,7 +143,7 @@ document.webL10n = (function(window, document, undefined) {
|
|||
* URL of the l10n resource to parse.
|
||||
*
|
||||
* @param {string} lang
|
||||
* locale (language) to parse.
|
||||
* locale (language) to parse. Must be a lowercase string.
|
||||
*
|
||||
* @param {Function} successCallback
|
||||
* triggered when the l10n resource has been successully parsed.
|
||||
|
|
@ -174,8 +175,10 @@ document.webL10n = (function(window, document, undefined) {
|
|||
}
|
||||
|
||||
// parse *.properties text data into an l10n dictionary
|
||||
function parseProperties(text) {
|
||||
var dictionary = [];
|
||||
// If gAsyncResourceLoading is false, then the callback will be called
|
||||
// synchronously. Otherwise it is called asynchronously.
|
||||
function parseProperties(text, parsedPropertiesCallback) {
|
||||
var dictionary = {};
|
||||
|
||||
// token expressions
|
||||
var reBlank = /^\s*|\s*$/;
|
||||
|
|
@ -185,55 +188,69 @@ document.webL10n = (function(window, document, undefined) {
|
|||
var reSplit = /^([^=\s]*)\s*=\s*(.+)$/; // TODO: escape EOLs with '\'
|
||||
|
||||
// parse the *.properties file into an associative array
|
||||
function parseRawLines(rawText, extendedSyntax) {
|
||||
function parseRawLines(rawText, extendedSyntax, parsedRawLinesCallback) {
|
||||
var entries = rawText.replace(reBlank, '').split(/[\r\n]+/);
|
||||
var currentLang = '*';
|
||||
var genericLang = lang.replace(/-[a-z]+$/i, '');
|
||||
var genericLang = lang.split('-', 1)[0];
|
||||
var skipLang = false;
|
||||
var match = '';
|
||||
|
||||
for (var i = 0; i < entries.length; i++) {
|
||||
var line = entries[i];
|
||||
function nextEntry() {
|
||||
// Use infinite loop instead of recursion to avoid reaching the
|
||||
// maximum recursion limit for content with many lines.
|
||||
while (true) {
|
||||
if (!entries.length) {
|
||||
parsedRawLinesCallback();
|
||||
return;
|
||||
}
|
||||
var line = entries.shift();
|
||||
|
||||
// comment or blank line?
|
||||
if (reComment.test(line))
|
||||
continue;
|
||||
// comment or blank line?
|
||||
if (reComment.test(line))
|
||||
continue;
|
||||
|
||||
// the extended syntax supports [lang] sections and @import rules
|
||||
if (extendedSyntax) {
|
||||
if (reSection.test(line)) { // section start?
|
||||
// the extended syntax supports [lang] sections and @import rules
|
||||
if (extendedSyntax) {
|
||||
match = reSection.exec(line);
|
||||
currentLang = match[1];
|
||||
skipLang = (currentLang !== '*') &&
|
||||
(currentLang !== lang) && (currentLang !== genericLang);
|
||||
continue;
|
||||
} else if (skipLang) {
|
||||
continue;
|
||||
}
|
||||
if (reImport.test(line)) { // @import rule?
|
||||
match = reImport.exec(line);
|
||||
loadImport(baseURL + match[1]); // load the resource synchronously
|
||||
}
|
||||
}
|
||||
if (match) { // section start?
|
||||
// RFC 4646, section 4.4, "All comparisons MUST be performed
|
||||
// in a case-insensitive manner."
|
||||
|
||||
// key-value pair
|
||||
var tmp = line.match(reSplit);
|
||||
if (tmp && tmp.length == 3) {
|
||||
dictionary[tmp[1]] = evalString(tmp[2]);
|
||||
currentLang = match[1].toLowerCase();
|
||||
skipLang = (currentLang !== '*') &&
|
||||
(currentLang !== lang) && (currentLang !== genericLang);
|
||||
continue;
|
||||
} else if (skipLang) {
|
||||
continue;
|
||||
}
|
||||
match = reImport.exec(line);
|
||||
if (match) { // @import rule?
|
||||
loadImport(baseURL + match[1], nextEntry);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// key-value pair
|
||||
var tmp = line.match(reSplit);
|
||||
if (tmp && tmp.length == 3) {
|
||||
dictionary[tmp[1]] = evalString(tmp[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
nextEntry();
|
||||
}
|
||||
|
||||
// import another *.properties file
|
||||
function loadImport(url) {
|
||||
function loadImport(url, callback) {
|
||||
xhrLoadText(url, function(content) {
|
||||
parseRawLines(content, false); // don't allow recursive imports
|
||||
}, null, false); // load synchronously
|
||||
parseRawLines(content, false, callback); // don't allow recursive imports
|
||||
}, null);
|
||||
}
|
||||
|
||||
// fill the dictionary
|
||||
parseRawLines(text, true);
|
||||
return dictionary;
|
||||
parseRawLines(text, true, function() {
|
||||
parsedPropertiesCallback(dictionary);
|
||||
});
|
||||
}
|
||||
|
||||
// load and parse l10n data (warning: global variables are used here)
|
||||
|
|
@ -241,33 +258,40 @@ document.webL10n = (function(window, document, undefined) {
|
|||
gTextData += response; // mostly for debug
|
||||
|
||||
// parse *.properties text data into an l10n dictionary
|
||||
var data = parseProperties(response);
|
||||
parseProperties(response, function(data) {
|
||||
|
||||
// find attribute descriptions, if any
|
||||
for (var key in data) {
|
||||
var id, prop, index = key.lastIndexOf('.');
|
||||
if (index > 0) { // an attribute has been specified
|
||||
id = key.substring(0, index);
|
||||
prop = key.substr(index + 1);
|
||||
} else { // no attribute: assuming text content by default
|
||||
id = key;
|
||||
prop = gTextProp;
|
||||
// find attribute descriptions, if any
|
||||
for (var key in data) {
|
||||
var id, prop, index = key.lastIndexOf('.');
|
||||
if (index > 0) { // an attribute has been specified
|
||||
id = key.substring(0, index);
|
||||
prop = key.substr(index + 1);
|
||||
} else { // no attribute: assuming text content by default
|
||||
id = key;
|
||||
prop = gTextProp;
|
||||
}
|
||||
if (!gL10nData[id]) {
|
||||
gL10nData[id] = {};
|
||||
}
|
||||
gL10nData[id][prop] = data[key];
|
||||
}
|
||||
if (!gL10nData[id]) {
|
||||
gL10nData[id] = {};
|
||||
}
|
||||
gL10nData[id][prop] = data[key];
|
||||
}
|
||||
|
||||
// trigger callback
|
||||
if (successCallback) {
|
||||
successCallback();
|
||||
}
|
||||
}, failureCallback, gAsyncResourceLoading);
|
||||
// trigger callback
|
||||
if (successCallback) {
|
||||
successCallback();
|
||||
}
|
||||
});
|
||||
}, failureCallback);
|
||||
}
|
||||
|
||||
// load and parse all resources for the specified locale
|
||||
function loadLocale(lang, callback) {
|
||||
// RFC 4646, section 2.1 states that language tags have to be treated as
|
||||
// case-insensitive. Convert to lowercase for case-insensitive comparisons.
|
||||
if (lang) {
|
||||
lang = lang.toLowerCase();
|
||||
}
|
||||
|
||||
callback = callback || function _callback() {};
|
||||
|
||||
clear();
|
||||
|
|
@ -282,7 +306,19 @@ document.webL10n = (function(window, document, undefined) {
|
|||
var dict = getL10nDictionary();
|
||||
if (dict && dict.locales && dict.default_locale) {
|
||||
console.log('using the embedded JSON directory, early way out');
|
||||
gL10nData = dict.locales[lang] || dict.locales[dict.default_locale];
|
||||
gL10nData = dict.locales[lang];
|
||||
if (!gL10nData) {
|
||||
var defaultLocale = dict.default_locale.toLowerCase();
|
||||
for (var anyCaseLang in dict.locales) {
|
||||
anyCaseLang = anyCaseLang.toLowerCase();
|
||||
if (anyCaseLang === lang) {
|
||||
gL10nData = dict.locales[lang];
|
||||
break;
|
||||
} else if (anyCaseLang === defaultLocale) {
|
||||
gL10nData = dict.locales[defaultLocale];
|
||||
}
|
||||
}
|
||||
}
|
||||
callback();
|
||||
} else {
|
||||
console.log('no resource to load, early way out');
|
||||
|
|
@ -308,24 +344,23 @@ document.webL10n = (function(window, document, undefined) {
|
|||
// load all resource files
|
||||
function L10nResourceLink(link) {
|
||||
var href = link.href;
|
||||
var type = link.type;
|
||||
// Note: If |gAsyncResourceLoading| is false, then the following callbacks
|
||||
// are synchronously called.
|
||||
this.load = function(lang, callback) {
|
||||
var applied = lang;
|
||||
parseResource(href, lang, callback, function() {
|
||||
console.warn(href + ' not found.');
|
||||
applied = '';
|
||||
// lang not found, used default resource instead
|
||||
console.warn('"' + lang + '" resource not found');
|
||||
gLanguage = '';
|
||||
// Resource not loaded, but we still need to call the callback.
|
||||
callback();
|
||||
});
|
||||
return applied; // return lang if found, an empty string if not found
|
||||
};
|
||||
}
|
||||
|
||||
for (var i = 0; i < langCount; i++) {
|
||||
var resource = new L10nResourceLink(langLinks[i]);
|
||||
var rv = resource.load(lang, onResourceLoaded);
|
||||
if (rv != lang) { // lang not found, used default resource instead
|
||||
console.warn('"' + lang + '" resource not found');
|
||||
gLanguage = '';
|
||||
}
|
||||
resource.load(lang, onResourceLoaded);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -841,28 +876,17 @@ document.webL10n = (function(window, document, undefined) {
|
|||
|
||||
// replace {{arguments}} with their values
|
||||
function substArguments(str, args, key) {
|
||||
var reArgs = /\{\{\s*(.+?)\s*\}\}/;
|
||||
var match = reArgs.exec(str);
|
||||
while (match) {
|
||||
if (!match || match.length < 2)
|
||||
return str; // argument key not found
|
||||
|
||||
var arg = match[1];
|
||||
var sub = '';
|
||||
var reArgs = /\{\{\s*(.+?)\s*\}\}/g;
|
||||
return str.replace(reArgs, function(matched_text, arg) {
|
||||
if (args && arg in args) {
|
||||
sub = args[arg];
|
||||
} else if (arg in gL10nData) {
|
||||
sub = gL10nData[arg][gTextProp];
|
||||
} else {
|
||||
console.log('argument {{' + arg + '}} for #' + key + ' is undefined.');
|
||||
return str;
|
||||
return args[arg];
|
||||
}
|
||||
|
||||
str = str.substring(0, match.index) + sub +
|
||||
str.substr(match.index + match[0].length);
|
||||
match = reArgs.exec(str);
|
||||
}
|
||||
return str;
|
||||
if (arg in gL10nData) {
|
||||
return gL10nData[arg];
|
||||
}
|
||||
console.log('argument {{' + arg + '}} for #' + key + ' is undefined.');
|
||||
return matched_text;
|
||||
});
|
||||
}
|
||||
|
||||
// translate an HTML element
|
||||
|
|
@ -942,7 +966,6 @@ document.webL10n = (function(window, document, undefined) {
|
|||
translateElement(element);
|
||||
}
|
||||
|
||||
// cross-browser API (sorry, oldIE doesn't support getters & setters)
|
||||
return {
|
||||
// get a localized string
|
||||
get: function(key, args, fallbackString) {
|
||||
|
|
@ -970,14 +993,21 @@ document.webL10n = (function(window, document, undefined) {
|
|||
|
||||
// get|set the document language
|
||||
getLanguage: function() { return gLanguage; },
|
||||
setLanguage: function(lang) { loadLocale(lang, translateFragment); },
|
||||
setLanguage: function(lang, callback) {
|
||||
loadLocale(lang, function() {
|
||||
if (callback)
|
||||
callback();
|
||||
translateFragment();
|
||||
});
|
||||
},
|
||||
|
||||
// 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'];
|
||||
return (rtlList.indexOf(gLanguage) >= 0) ? 'rtl' : 'ltr';
|
||||
var shortCode = gLanguage.split('-', 1)[0];
|
||||
return (rtlList.indexOf(shortCode) >= 0) ? 'rtl' : 'ltr';
|
||||
},
|
||||
|
||||
// translate an element or document fragment
|
||||
|
|
@ -989,14 +1019,13 @@ document.webL10n = (function(window, document, undefined) {
|
|||
if (!callback) {
|
||||
return;
|
||||
} else if (gReadyState == 'complete' || gReadyState == 'interactive') {
|
||||
window.setTimeout(callback);
|
||||
window.setTimeout(function() {
|
||||
callback();
|
||||
});
|
||||
} else if (document.addEventListener) {
|
||||
document.addEventListener('localized', callback);
|
||||
} else if (document.attachEvent) {
|
||||
document.documentElement.attachEvent('onpropertychange', function(e) {
|
||||
if (e.propertyName === 'localized') {
|
||||
callback();
|
||||
}
|
||||
document.addEventListener('localized', function once() {
|
||||
document.removeEventListener('localized', once);
|
||||
callback();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue