/** @license Hyphenator 4.0.0 - client side hyphenation for webbrowsers * Copyright (C) 2011 Mathias Nater, Zürich (mathias at mnn dot ch) * Project and Source hosted on http://code.google.com/p/hyphenator/ * * This JavaScript code is free software: you can redistribute * it and/or modify it under the terms of the GNU Lesser * General Public License (GNU LGPL) as published by the Free Software * Foundation, either version 3 of the License, or (at your option) * any later version. The code is distributed WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU GPL for more details. * * As additional permission under GNU GPL version 3 section 7, you * may distribute non-source (e.g., minimized or compacted) forms of * that code without the copy of the GNU GPL normally required by * section 4, provided you include this license notice and a URL * through which recipients can access the Corresponding Source. * * * Hyphenator.js contains code from Bram Steins hypher.js-Project: * https://github.com/bramstein/Hypher * * Code from this project is marked in the source and belongs * to the following license: * * Copyright (c) 2011, Bram Stein * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /* * Comments are jsdoctoolkit formatted. See http://code.google.com/p/jsdoc-toolkit/ */ /* The following comment is for JSLint: */ /*global window, ActiveXObject, unescape */ /*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, regexp: true, sub: true, newcap: true, immed: true, evil: true, eqeqeq: false */ /** * @constructor * @description Provides all functionality to do hyphenation, except the patterns that are loaded * externally. * @author Mathias Nater, mathias@mnn.ch * @version X.Y.Z * @namespace Holds all methods and properties * @example * <script src = "Hyphenator.js" type = "text/javascript"></script> * <script type = "text/javascript"> * Hyphenator.run(); * </script> */ var Hyphenator = (function (window) { var /** * @name Hyphenator-supportedLang * @description * A key-value object that stores supported languages. * The key is the bcp47 code of the language and the value * is the (abbreviated) filename of the pattern file. * @type {Object.} * @private * @example * Check if language lang is supported: * if (supportedLang.hasOwnProperty(lang)) */ supportedLang = { 'be': 'be.js', 'ca': 'ca.js', 'cs': 'cs.js', 'da': 'da.js', 'bn': 'bn.js', 'de': 'de.js', 'el': 'el-monoton.js', 'el-monoton': 'el-monoton.js', 'el-polyton': 'el-polyton.js', 'en': 'en-us.js', 'en-gb': 'en-gb.js', 'en-us': 'en-us.js', 'es': 'es.js', 'fi': 'fi.js', 'fr': 'fr.js', 'grc': 'grc.js', 'gu': 'gu.js', 'hi': 'hi.js', 'hu': 'hu.js', 'hy': 'hy.js', 'it': 'it.js', 'kn': 'kn.js', 'la': 'la.js', 'lt': 'lt.js', 'lv': 'lv.js', 'ml': 'ml.js', 'nb': 'nb-no.js', 'no': 'nb-no.js', 'nb-no': 'nb-no.js', 'nl': 'nl.js', 'or': 'or.js', 'pa': 'pa.js', 'pl': 'pl.js', 'pt': 'pt.js', 'ru': 'ru.js', 'sk': 'sk.js', 'sl': 'sl.js', 'sv': 'sv.js', 'ta': 'ta.js', 'te': 'te.js', 'tr': 'tr.js', 'uk': 'uk.js' }, /** * @name Hyphenator-languageHint * @description * An automatically generated string to be displayed in a prompt if the language can't be guessed. * The string is generated using the supportedLang-object. * @see Hyphenator-supportedLang * @type {string} * @private * @see Hyphenator-autoSetMainLanguage */ languageHint = (function () { var k, r = ''; for (k in supportedLang) { if (supportedLang.hasOwnProperty(k)) { r += k + ', '; } } r = r.substring(0, r.length - 2); return r; }()), /** * @name Hyphenator-prompterStrings * @description * A key-value object holding the strings to be displayed if the language can't be guessed * If you add hyphenation patterns change this string. * @type {Object.} * @private * @see Hyphenator-autoSetMainLanguage */ prompterStrings = { 'be': 'Мова гэтага сайта не можа быць вызначаны аўтаматычна. Калі ласка пакажыце мову:', 'cs': 'Jazyk této internetové stránky nebyl automaticky rozpoznán. Určete prosím její jazyk:', 'da': 'Denne websides sprog kunne ikke bestemmes. Angiv venligst sprog:', 'de': 'Die Sprache dieser Webseite konnte nicht automatisch bestimmt werden. Bitte Sprache angeben:', 'en': 'The language of this website could not be determined automatically. Please indicate the main language:', 'es': 'El idioma del sitio no pudo determinarse autom%E1ticamente. Por favor, indique el idioma principal:', 'fi': 'Sivun kielt%E4 ei tunnistettu automaattisesti. M%E4%E4rit%E4 sivun p%E4%E4kieli:', 'fr': 'La langue de ce site n%u2019a pas pu %EAtre d%E9termin%E9e automatiquement. Veuillez indiquer une langue, s.v.p.%A0:', 'hu': 'A weboldal nyelvét nem sikerült automatikusan megállapítani. Kérem adja meg a nyelvet:', 'hy': 'Չհաջողվեց հայտնաբերել այս կայքի լեզուն։ Խնդրում ենք նշեք հիմնական լեզուն՝', 'it': 'Lingua del sito sconosciuta. Indicare una lingua, per favore:', 'kn': 'ಜಾಲ ತಾಣದ ಭಾಷೆಯನ್ನು ನಿರ್ಧರಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ. ದಯವಿಟ್ಟು ಮುಖ್ಯ ಭಾಷೆಯನ್ನು ಸೂಚಿಸಿ:', 'lt': 'Nepavyko automatiškai nustatyti šios svetainės kalbos. Prašome įvesti kalbą:', 'lv': 'Šīs lapas valodu nevarēja noteikt automātiski. Lūdzu norādiet pamata valodu:', 'ml': 'ഈ വെ%u0D2C%u0D4D%u200Cസൈറ്റിന്റെ ഭാഷ കണ്ടുപിടിയ്ക്കാ%u0D28%u0D4D%u200D കഴിഞ്ഞില്ല. ഭാഷ ഏതാണെന്നു തിരഞ്ഞെടുക്കുക:', 'nl': 'De taal van deze website kan niet automatisch worden bepaald. Geef de hoofdtaal op:', 'no': 'Nettstedets språk kunne ikke finnes automatisk. Vennligst oppgi språk:', 'pt': 'A língua deste site não pôde ser determinada automaticamente. Por favor indique a língua principal:', 'ru': 'Язык этого сайта не может быть определен автоматически. Пожалуйста укажите язык:', 'sl': 'Jezika te spletne strani ni bilo mogoče samodejno določiti. Prosim navedite jezik:', 'sv': 'Spr%E5ket p%E5 den h%E4r webbplatsen kunde inte avg%F6ras automatiskt. V%E4nligen ange:', 'tr': 'Bu web sitesinin dili otomatik olarak tespit edilememiştir. Lütfen dökümanın dilini seçiniz%A0:', 'uk': 'Мова цього веб-сайту не може бути визначена автоматично. Будь ласка, вкажіть головну мову:' }, /** * @name Hyphenator-basePath * @description * A string storing the basepath from where Hyphenator.js was loaded. * This is used to load the patternfiles. * The basepath is determined dynamically by searching all script-tags for Hyphenator.js * If the path cannot be determined http://hyphenator.googlecode.com/svn/trunk/ is used as fallback. * @type {string} * @private * @see Hyphenator-loadPatterns */ basePath = (function () { var s = document.getElementsByTagName('script'), i = 0, p, src, t; while (!!(t = s[i++])) { if (!t.src) { continue; } src = t.src; p = src.indexOf('Hyphenator.js'); if (p !== -1) { return src.substring(0, p); } } return 'http://hyphenator.googlecode.com/svn/trunk/'; }()), /** * @name Hyphenator-isLocal * @description * isLocal is true, if Hyphenator is loaded from the same domain, as the webpage, but false, if * it's loaded from an external source (i.e. directly from google.code) */ isLocal = (function () { var re = false; if (window.location.href.indexOf(basePath) !== -1) { re = true; } return re; }()), /** * @name Hyphenator-documentLoaded * @description * documentLoaded is true, when the DOM has been loaded. This is set by runOnContentLoaded */ documentLoaded = false, documentCount = 0, /** * @name Hyphenator-persistentConfig * @description * if persistentConfig is set to true (defaults to false), config options and the state of the * toggleBox are stored in DOM-storage (according to the storage-setting). So they haven't to be * set for each page. */ persistentConfig = false, /** * @name Hyphenator-contextWindow * @description * contextWindow stores the window for the document to be hyphenated. * If there are frames this will change. * So use contextWindow instead of window! */ contextWindow = window, /** * @name Hyphenator-doFrames * @description * switch to control if frames/iframes should be hyphenated, too * defaults to false (frames are a bag of hurt!) */ doFrames = false, /** * @name Hyphenator-dontHyphenate * @description * A key-value object containing all html-tags whose content should not be hyphenated * @type {Object.} * @private * @see Hyphenator-hyphenateElement */ dontHyphenate = {'script': true, 'code': true, 'pre': true, 'img': true, 'br': true, 'samp': true, 'kbd': true, 'var': true, 'abbr': true, 'acronym': true, 'sub': true, 'sup': true, 'button': true, 'option': true, 'label': true, 'textarea': true, 'input': true, 'math': true, 'svg': true}, /** * @name Hyphenator-enableCache * @description * A variable to set if caching is enabled or not * @type boolean * @default true * @private * @see Hyphenator.config * @see hyphenateWord */ enableCache = true, /** * @name Hyphenator-storageType * @description * A variable to define what html5-DOM-Storage-Method is used ('none', 'local' or 'session') * @type {string} * @default 'none' * @private * @see Hyphenator.config */ storageType = 'local', /** * @name Hyphenator-storage * @description * An alias to the storage-Method defined in storageType. * Set by Hyphenator.run() * @type {Object|undefined} * @default null * @private * @see Hyphenator.run */ storage, /** * @name Hyphenator-enableReducedPatternSet * @description * A variable to set if storing the used patterns is set * @type boolean * @default false * @private * @see Hyphenator.config * @see hyphenateWord * @see Hyphenator.getRedPatternSet */ enableReducedPatternSet = false, /** * @name Hyphenator-enableRemoteLoading * @description * A variable to set if pattern files should be loaded remotely or not * @type boolean * @default true * @private * @see Hyphenator.config * @see Hyphenator-loadPatterns */ enableRemoteLoading = true, /** * @name Hyphenator-displayToggleBox * @description * A variable to set if the togglebox should be displayed or not * @type boolean * @default false * @private * @see Hyphenator.config * @see Hyphenator-toggleBox */ displayToggleBox = false, /** * @name Hyphenator-css3 * @description * A variable to set if css3 hyphenation should be used * @type boolean * @default false * @private * @see Hyphenator.config */ css3 = false, /** * @name Hyphenator-css3_hsupport * @description * A generated object containing information for CSS3-hyphenation support * { * support: boolean, * property: , * languages: * } * @type object * @default undefined * @private * @see Hyphenator-css3_gethsupport */ css3_h9n, /** * @name Hyphenator-css3_gethsupport * @description * This function sets Hyphenator-css3_h9n for the current UA * @type function * @private * @see Hyphenator-css3_h9n */ css3_gethsupport = function () { var s, ua = navigator.userAgent, r = { support: false, property: '', languages: {} }; if (window.getComputedStyle) { s = window.getComputedStyle(window.document.getElementsByTagName('body')[0]); } else { //ancient Browser don't support CSS3 anyway css3_h9n = r; return; } if (ua.indexOf('Chrome') !== -1) { //Chrome actually knows -webkit-hyphens but does no hyphenation r.support = false; } else if ((ua.indexOf('Safari') !== -1) && (s['-webkit-hyphens'] !== undefined)) { r.support = true; r.property = '-webkit-hyphens'; if (ua.indexOf('Mobile') !== -1) { //iOS only hyphenates in systemlanguage r.languages[navigator.language.split('-')[0]] = true; } else { //Desktop Safari only hyphenates some languages: r.languages = { de: true, en: true, es: true, fr: true, it: true, nl: true, ru: true, zh: true }; } } else if ((ua.indexOf('Firefox') !== -1) && (s['MozHyphens'] !== undefined)) { r.support = true; r.property = 'MozHyphens'; r.languages = { en: true }; } css3_h9n = r; }, /** * @name Hyphenator-hyphenateClass * @description * A string containing the css-class-name for the hyphenate class * @type {string} * @default 'hyphenate' * @private * @example * <p class = "hyphenate">Text</p> * @see Hyphenator.config */ hyphenateClass = 'hyphenate', /** * @name Hyphenator-dontHyphenateClass * @description * A string containing the css-class-name for elements that should not be hyphenated * @type {string} * @default 'donthyphenate' * @private * @example * <p class = "donthyphenate">Text</p> * @see Hyphenator.config */ dontHyphenateClass = 'donthyphenate', /** * @name Hyphenator-min * @description * A number wich indicates the minimal length of words to hyphenate. * @type {number} * @default 6 * @private * @see Hyphenator.config */ min = 6, /** * @name Hyphenator-orphanControl * @description * Control how the last words of a line are handled: * level 1 (default): last word is hyphenated * level 2: last word is not hyphenated * level 3: last word is not hyphenated and last space is non breaking * @type {number} * @default 1 * @private */ orphanControl = 1, /** * @name Hyphenator-isBookmarklet * @description * Indicates if Hyphanetor runs as bookmarklet or not. * @type boolean * @default false * @private */ isBookmarklet = (function () { var loc = null, re = false, jsArray = document.getElementsByTagName('script'), i, l; for (i = 0, l = jsArray.length; i < l; i++) { if (!!jsArray[i].getAttribute('src')) { loc = jsArray[i].getAttribute('src'); } if (!loc) { continue; } else if (loc.indexOf('Hyphenator.js?bm=true') !== -1) { re = true; } } return re; }()), /** * @name Hyphenator-mainLanguage * @description * The general language of the document. In contrast to {@link Hyphenator-defaultLanguage}, * mainLanguage is defined by the client (i.e. by the html or by a prompt). * @type {string|null} * @private * @see Hyphenator-autoSetMainLanguage */ mainLanguage = null, /** * @name Hyphenator-defaultLanguage * @description * The language defined by the developper. This language setting is defined by a config option. * It is overwritten by any html-lang-attribute and only taken in count, when no such attribute can * be found (i.e. just before the prompt). * @type {string|null} * @private * @see Hyphenator-autoSetMainLanguage */ defaultLanguage = '', /** * @name Hyphenator-elements * @description * An array holding all elements that have to be hyphenated. This var is filled by * {@link Hyphenator-gatherDocumentInfos} * @type {Array} * @private */ elements = (function () { var Element = function (element, data) { this.element = element; this.hyphenated = false; this.treated = false; //collected but not hyphenated (dohyphenation is off) this.data = data; }, ElementCollection = function () { this.count = 0; this.hyCount = 0; this.list = {}; }; ElementCollection.prototype = { add: function (el, lang, data) { if (!this.list.hasOwnProperty(lang)) { this.list[lang] = []; } this.list[lang].push(new Element(el, data)); this.count += 1; }, each: function (fn) { var k; for (k in this.list) { if (this.list.hasOwnProperty(k)) { fn(k, this.list[k]); } } } }; return new ElementCollection(); }()), /** * @name Hyphenator-exceptions * @description * An object containing exceptions as comma separated strings for each language. * When the language-objects are loaded, their exceptions are processed, copied here and then deleted. * @see Hyphenator-prepareLanguagesObj * @type {Object} * @private */ exceptions = {}, /** * @name Hyphenator-docLanguages * @description * An object holding all languages used in the document. This is filled by * {@link Hyphenator-gatherDocumentInfos} * @type {Object} * @private */ docLanguages = {}, /** * @name Hyphenator-state * @description * A number that inidcates the current state of the script * 0: not initialized * 1: loading patterns * 2: ready * 3: hyphenation done * 4: hyphenation removed * @type {number} * @private */ state = 0, /** * @name Hyphenator-url * @description * A string containing a RegularExpression to match URL's * @type {string} * @private */ url = '(\\w*:\/\/)?((\\w*:)?(\\w*)@)?((([\\d]{1,3}\\.){3}([\\d]{1,3}))|((www\\.|[a-zA-Z]\\.)?[a-zA-Z0-9\\-\\.]+\\.([a-z]{2,4})))(:\\d*)?(\/[\\w#!:\\.?\\+=&%@!\\-]*)*', // protocoll usr pwd ip or host tld port path /** * @name Hyphenator-mail * @description * A string containing a RegularExpression to match mail-adresses * @type {string} * @private */ mail = '[\\w-\\.]+@[\\w\\.]+', /** * @name Hyphenator-urlRE * @description * A RegularExpressions-Object for url- and mail adress matching * @type {RegExp} * @private */ urlOrMailRE = new RegExp('(' + url + ')|(' + mail + ')', 'i'), /** * @name Hyphenator-zeroWidthSpace * @description * A string that holds a char. * Depending on the browser, this is the zero with space or an empty string. * zeroWidthSpace is used to break URLs * @type {string} * @private */ zeroWidthSpace = (function () { var zws, ua = navigator.userAgent.toLowerCase(); zws = String.fromCharCode(8203); //Unicode zero width space if (ua.indexOf('msie 6') !== -1) { zws = ''; //IE6 doesn't support zws } if (ua.indexOf('opera') !== -1 && ua.indexOf('version/10.00') !== -1) { zws = ''; //opera 10 on XP doesn't support zws } return zws; }()), /** * @name Hyphenator-createElem * @description * A function alias to document.createElementNS or document.createElement * @type {function(string, Object)} * @private */ createElem = function (tagname, context) { context = context || contextWindow; if (document.createElementNS) { return context.document.createElementNS('http://www.w3.org/1999/xhtml', tagname); } else if (document.createElement) { return context.document.createElement(tagname); } }, /** * @name Hyphenator-onHyphenationDone * @description * A method to be called, when the last element has been hyphenated or the hyphenation has been * removed from the last element. * @see Hyphenator.config * @type {function()} * @private */ onHyphenationDone = function () {}, /** * @name Hyphenator-onError * @description * A function that can be called upon an error. * @see Hyphenator.config * @type {function(Object)} * @private */ onError = function (e) { window.alert("Hyphenator.js says:\n\nAn Error ocurred:\n" + e.message); }, /** * @name Hyphenator-selectorFunction * @description * A function that has to return a HTMLNodeList of Elements to be hyphenated. * By default it uses the classname ('hyphenate') to select the elements. * @see Hyphenator.config * @type {function()} * @private */ selectorFunction = function () { var tmp, el = [], i, l; if (document.getElementsByClassName) { el = contextWindow.document.getElementsByClassName(hyphenateClass); } else { tmp = contextWindow.document.getElementsByTagName('*'); l = tmp.length; for (i = 0; i < l; i++) { if (tmp[i].className.indexOf(hyphenateClass) !== -1 && tmp[i].className.indexOf(dontHyphenateClass) === -1) { el.push(tmp[i]); } } } return el; }, /** * @name Hyphenator-intermediateState * @description * The value of style.visibility of the text while it is hyphenated. * @see Hyphenator.config * @type {string} * @private */ intermediateState = 'hidden', /** * @name Hyphenator-unhide * @description * How hidden elements unhide: either simultaneous (default: 'wait') or progressively. * 'wait' makes Hyphenator.js to wait until all elements are hyphenated (one redraw) * With 'progressiv' Hyphenator.js unhides elements as soon as they are hyphenated. * @see Hyphenator.config * @type {string} * @private */ unhide = 'wait', /** * @name Hyphenator-hyphen * @description * A string containing the character for in-word-hyphenation * @type {string} * @default the soft hyphen * @private * @see Hyphenator.config */ hyphen = String.fromCharCode(173), /** * @name Hyphenator-urlhyphen * @description * A string containing the character for url/mail-hyphenation * @type {string} * @default the zero width space * @private * @see Hyphenator.config * @see Hyphenator-zeroWidthSpace */ urlhyphen = zeroWidthSpace, /** * @name Hyphenator-safeCopy * @description * Defines wether work-around for copy issues is active or not * Not supported by Opera (no onCopy handler) * @type boolean * @default true * @private * @see Hyphenator.config * @see Hyphenator-registerOnCopy */ safeCopy = true, /* * runOnContentLoaded is based od jQuery.bindReady() * see * jQuery JavaScript Library v1.3.2 * http://jquery.com/ * * Copyright (c) 2009 John Resig * Dual licensed under the MIT and GPL licenses. * http://docs.jquery.com/License * * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009) * Revision: 6246 */ /** * @name Hyphenator-runOnContentLoaded * @description * A crossbrowser solution for the DOMContentLoaded-Event based on jQuery * 0) { for (i = 0; i < fl; i++) { haveAccess = undefined; //try catch isn't enough for webkit try { //opera throws only on document.toString-access haveAccess = window.frames[i].document.toString(); } catch (e) { haveAccess = undefined; } if (!!haveAccess) { init(window.frames[i]); } } contextWindow = window; f(); hyphRunForThis[window.location.href] = true; } else { init(window); } } // Cleanup functions for the document ready method if (document.addEventListener) { DOMContentLoaded = function () { document.removeEventListener("DOMContentLoaded", DOMContentLoaded, false); if (doFrames && window.frames.length > 0) { //we are in a frameset, so do nothing but wait for onload to fire return; } else { init(window); } }; } else if (document.attachEvent) { DOMContentLoaded = function () { // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). if (document.readyState === "complete") { document.detachEvent("onreadystatechange", DOMContentLoaded); if (doFrames && window.frames.length > 0) { //we are in a frameset, so do nothing but wait for onload to fire return; } else { init(window); } } }; } // Mozilla, Opera and webkit nightlies currently support this event if (document.addEventListener) { // Use the handy event callback document.addEventListener("DOMContentLoaded", DOMContentLoaded, false); // A fallback to window.onload, that will always work window.addEventListener("load", doOnLoad, false); // If IE event model is used } else if (document.attachEvent) { // ensure firing before onload, // maybe late but safe also for iframes document.attachEvent("onreadystatechange", DOMContentLoaded); // A fallback to window.onload, that will always work window.attachEvent("onload", doOnLoad); // If IE and not a frame // continually check to see if the document is ready toplevel = false; try { toplevel = window.frameElement === null; } catch (e) {} if (document.documentElement.doScroll && toplevel) { doScrollCheck(); } } }, /** * @name Hyphenator-getLang * @description * Gets the language of an element. If no language is set, it may use the {@link Hyphenator-mainLanguage}. * @param {Object} el The first parameter is an DOM-Element-Object * @param {boolean} fallback The second parameter is a boolean to tell if the function should return the {@link Hyphenator-mainLanguage} * if there's no language found for the element. * @private */ getLang = function (el, fallback) { if (!!el.getAttribute('lang')) { return el.getAttribute('lang').toLowerCase(); } // The following doesn't work in IE due to a bug when getAttribute('xml:lang') in a table /*if (!!el.getAttribute('xml:lang')) { return el.getAttribute('xml:lang').substring(0, 2); }*/ //instead, we have to do this (thanks to borgzor): try { if (!!el.getAttribute('xml:lang')) { return el.getAttribute('xml:lang').toLowerCase(); } } catch (ex) {} if (el.tagName !== 'HTML') { return getLang(el.parentNode, true); } if (fallback) { return mainLanguage; } return null; }, /** * @name Hyphenator-autoSetMainLanguage * @description * Retrieves the language of the document from the DOM. * The function looks in the following places: *