User:Mezvan/myskin.js

/*
 * 99% of this file is Hyphenator.js.
 * I'll probably separate it later (Wikipedia only gives you one js file).
 * Skip all the way down for custom js.

/** @license Hyphenator 3.2.0 - client side hyphenation for webbrowsers /* /* 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 */
 * Copyright (C) 2010 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.
 * section 4, provided you include this license notice and a URL
 * through which recipients can access the Corresponding Source.
 * Comments are jsdoctoolkit formatted. See http://code.google.com/p/jsdoc-toolkit/

/** var Hyphenator = (function (window) {
 * @constructor
 * @description Provides all functionality to do hyphenation, except the patterns that are loaded
 * externally.
 * @author Mathias Nater, mathias@mnn.ch
 * @version 3.2.0
 * @namespace Holds all methods and properties
 * @example
 * &lt;script src = "Hyphenator.js" type = "text/javascript"&gt;&lt;/script&gt;
 * &lt;script type = "text/javascript"&gt;
 * Hyphenator.run;
 * &lt;/script&gt;

var /** supportedLang = { 'be': 'be.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', 'no': 'no-nb.js', 'no-nb': 'no-nb.js', 'nl': 'nl.js', 'or': 'or.js', 'pa': 'pa.js', 'pl': 'pl.js', 'pt': 'pt.js', 'ru': 'ru.js', 'sl': 'sl.js', 'sv': 'sv.js', 'ta': 'ta.js', 'te': 'te.js', 'tr': 'tr.js', 'uk': 'uk.js' },
 * @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))

/**
 * @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; }),

/** 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-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

/** 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-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

/** isLocal = (function { var re = false; if (window.location.href.indexOf(basePath) !== -1) { re = true; } return re; }),
 * @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)

/** documentLoaded = false, documentCount = 0,
 * @name Hyphenator-documentLoaded
 * @description
 * documentLoaded is true, when the DOM has been loaded. This is set by runOnContentLoaded

/** persistentConfig = false,
 * @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.

/** contextWindow = window,
 * @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!

/** doFrames = false,
 * @name Hyphenator-doFrames
 * @description
 * switch to control if frames/iframes should be hyphenated, too
 * defaults to false (frames are a bag of hurt!)

/** 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},
 * @name Hyphenator-dontHyphenate
 * @description
 * A key-value object containing all html-tags whose content should not be hyphenated
 * @type {Object.}
 * @private
 * @see Hyphenator-hyphenateElement

/** enableCache = 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

/** storageType = 'local',
 * @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

/** storage,
 * @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

/** enableReducedPatternSet = false,
 * @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

/** enableRemoteLoading = true,
 * @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

/** displayToggleBox = false,
 * @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

/** hyphenateClass = 'hyphenate',
 * @name Hyphenator-hyphenateClass
 * @description
 * A string containing the css-class-name for the hyphenate class
 * @type {string}
 * @default 'hyphenate'
 * @private
 * @example
 * &lt;p class = "hyphenate"&gt;Text&lt;/p&gt;
 * @see Hyphenator.config

/** dontHyphenateClass = 'donthyphenate',
 * @name Hyphenator-dontHyphenateClass
 * @description
 * A string containing the css-class-name for elements that should not be hyphenated
 * @type {string}
 * @default 'donthyphenate'
 * @private
 * @example
 * &lt;p class = "donthyphenate"&gt;Text&lt;/p&gt;
 * @see Hyphenator.config

/** min = 6,
 * @name Hyphenator-min
 * @description
 * A number wich indicates the minimal length of words to hyphenate.
 * @type {number}
 * @default 6
 * @private
 * @see Hyphenator.config

/** orphanControl = 1,
 * @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

/** 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-isBookmarklet
 * @description
 * Indicates if Hyphanetor runs as bookmarklet or not.
 * @type boolean
 * @default false
 * @private

/** mainLanguage = null,
 * @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

/** defaultLanguage = '',
 * @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

/** elements = [],
 * @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

/** exceptions = {},
 * @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

countObjProps = function (obj) { var k, l = 0; for (k in obj) { if (obj.hasOwnProperty(k)) { l++; } } return l; }, /** docLanguages = {},
 * @name Hyphenator-docLanguages
 * @description
 * An object holding all languages used in the document. This is filled by
 * {@link Hyphenator-gatherDocumentInfos}
 * @type {Object}
 * @private

/** state = 0,
 * @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

/** 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 /** mail = '[\\w-\\.]+@[\\w\\.]+',
 * @name Hyphenator-url
 * @description
 * A string containing a RegularExpression to match URL's
 * @type {string}
 * @private
 * @name Hyphenator-mail
 * @description
 * A string containing a RegularExpression to match mail-adresses
 * @type {string}
 * @private

/** urlOrMailRE = new RegExp('(' + url + ')|(' + mail + ')', 'i'),
 * @name Hyphenator-urlRE
 * @description
 * A RegularExpressions-Object for url- and mail adress matching
 * @type {RegExp}
 * @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-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

/** 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-createElem
 * @description
 * A function alias to document.createElementNS or document.createElement
 * @type {function(string, Object)}
 * @private

/** onHyphenationDone = function {},
 * @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

/** onError = function (e) { //window.alert("Hyphenator.js says:\n\nAn Error ocurred:\n" + e.message); },
 * @name Hyphenator-onError
 * @description
 * A function that can be called upon an error.
 * @see Hyphenator.config
 * @type {function(Object)}
 * @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-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

/** intermediateState = 'hidden',
 * @name Hyphenator-intermediateState
 * @description
 * The value of style.visibility of the text while it is hyphenated.
 * @see Hyphenator.config
 * @type {string}
 * @private

/** hyphen = String.fromCharCode(173),
 * @name Hyphenator-hyphen
 * @description
 * A string containing the character for in-word-hyphenation
 * @type {string}
 * @default the soft hyphen
 * @private
 * @see Hyphenator.config

/** urlhyphen = zeroWidthSpace,
 * @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

/** safeCopy = true,
 * @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

/** Expando = (function { var container = {}, name = "HyphenatorExpando_" + Math.random, uuid = 0; return { getDataForElem : function (elem) { return container[elem[name].id]; }, setDataForElem : function (elem, data) { var id; if (elem[name] && elem[name].id !== '') { id = elem[name].id; } else { id = uuid++; elem[name] = {'id': id}; //object needed, otherways it is reflected in HTML in IE } container[id] = data; }, appendDataForElem : function (elem, data) { var k; for (k in data) { if (data.hasOwnProperty(k)) { container[elem[name].id][k] = data[k]; } } }, delDataOfElem : function (elem) { delete container[elem[name]]; } }; }),
 * @name Hyphenator-Expando
 * @description
 * This custom object stores data for elements: storing data directly in elements
 * (DomElement.customData = foobar;) isn't a good idea. It would lead to conflicts
 * in form elements, when the form has a child with name="foobar". Therefore, this
 * solution follows the approach of jQuery: the data is stored in an object and
 * referenced by a unique attribute of the element. The attribute has a name that
 * is built by the prefix "HyphenatorExpando_" and a random number, so if the very
 * very rare case occurs, that there's already an attribute with the same name, a
 * simple reload is enough to make it function.
 * @private

/* /** runOnContentLoaded = function (w, f) { var DOMContentLoaded = function {}, toplevel, hyphRunForThis = {}; if (documentLoaded && !hyphRunForThis[w.location.href]) { f; hyphRunForThis[w.location.href] = true; return; } function init(context) { contextWindow = context || window; if (!hyphRunForThis[contextWindow.location.href] && (!documentLoaded || contextWindow != window.parent)) { documentLoaded = true; f; hyphRunForThis[contextWindow.location.href] = 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
 * 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
 * 
 * I added some functionality: e.g. support for frames and iframes…
 * @param {Object} w the window-object
 * @param {function} f the function to call onDOMContentLoaded
 * @private

function doScrollCheck { try { // If IE is used, use the trick by Diego Perini // http://javascript.nwbox.com/IEContentLoaded/ document.documentElement.doScroll("left"); } catch (error) { setTimeout(doScrollCheck, 1); return; }

// and execute any waiting functions init(window); }

function doOnLoad { var i, haveAccess, fl = window.frames.length; if (doFrames && fl > 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; } }

},

/** 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-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

/** autoSetMainLanguage = function (w) { w = w || contextWindow; var el = w.document.getElementsByTagName('html')[0], m = w.document.getElementsByTagName('meta'), i, text, e, ul; mainLanguage = getLang(el, false); if (!mainLanguage) { for (i = 0; i < m.length; i++) { // if (!!m[i].getAttribute('http-equiv') && (m[i].getAttribute('http-equiv').toLowerCase === 'content-language')) { mainLanguage = m[i].getAttribute('content').toLowerCase; } // if (!!m[i].getAttribute('name') && (m[i].getAttribute('name').toLowerCase === 'dc.language')) { mainLanguage = m[i].getAttribute('content').toLowerCase; }	// if (!!m[i].getAttribute('name') && (m[i].getAttribute('name').toLowerCase === 'language')) { mainLanguage = m[i].getAttribute('content').toLowerCase; } } } //get lang for frame from enclosing document if (!mainLanguage && doFrames && contextWindow != window.parent) { autoSetMainLanguage(window.parent); } //fallback to defaultLang if set if (!mainLanguage && defaultLanguage !== '') { mainLanguage = defaultLanguage; } //ask user for lang if (!mainLanguage) { text = ''; ul = navigator.language ? navigator.language : navigator.userLanguage; ul = ul.substring(0, 2); if (prompterStrings.hasOwnProperty(ul)) { text = prompterStrings[ul]; } else { text = prompterStrings.en; } text += ' (ISO 639-1)\n\n' + languageHint; mainLanguage = window.prompt(unescape(text), ul).toLowerCase; } if (!supportedLang.hasOwnProperty(mainLanguage)) { if (supportedLang.hasOwnProperty(mainLanguage.split('-')[0])) { //try subtag mainLanguage = mainLanguage.split('-')[0]; } else { e = new Error('The language "' + mainLanguage + '" is not yet supported.'); throw e; } } }, /** gatherDocumentInfos = function { var elToProcess, tmp, i = 0, process = function (el, hide, lang) { var n, i = 0, hyphenatorSettings = {}; if (hide && intermediateState === 'hidden') { if (!!el.getAttribute('style')) { hyphenatorSettings.hasOwnStyle = true; } else { hyphenatorSettings.hasOwnStyle = false; } hyphenatorSettings.isHidden = true; el.style.visibility = 'hidden'; } if (el.lang && typeof(el.lang) === 'string') { hyphenatorSettings.language = el.lang.toLowerCase; //copy attribute-lang to internal lang } else if (lang) { hyphenatorSettings.language = lang.toLowerCase; } else { hyphenatorSettings.language = getLang(el, true); } lang = hyphenatorSettings.language; if (supportedLang[lang]) { docLanguages[lang] = true; } else { if (supportedLang.hasOwnProperty(lang.split('-')[0])) { //try subtag lang = lang.split('-')[0]; hyphenatorSettings.language = lang; } else if (!isBookmarklet) { onError(new Error('Language ' + lang + ' is not yet supported.')); } } Expando.setDataForElem(el, hyphenatorSettings);
 * @name Hyphenator-autoSetMainLanguage
 * @description
 * Retrieves the language of the document from the DOM.
 * The function looks in the following places:
 * 
 * lang-attribute in the html-tag
 * &lt;meta http-equiv = "content-language" content = "xy" /&gt;
 * &lt;meta name = "DC.Language" content = "xy" /&gt;
 * <li>&lt;meta name = "language" content = "xy" /&gt;</li>
 * </li>
 * If nothing can be found a prompt using {@link Hyphenator-languageHint} and {@link Hyphenator-prompterStrings} is displayed.
 * If the retrieved language is in the object {@link Hyphenator-supportedLang} it is copied to {@link Hyphenator-mainLanguage}
 * @private
 * @name Hyphenator-gatherDocumentInfos
 * @description
 * This method runs through the DOM and executes the process-function on:
 * - every node returned by the {@link Hyphenator-selectorFunction}.
 * The process-function copies the element to the elements-variable, sets its visibility
 * to intermediateState, retrieves its language and recursivly descends the DOM-tree until
 * the child-Nodes aren't of type 1
 * @private

elements.push(el); while (!!(n = el.childNodes[i++])) { if (n.nodeType === 1 && !dontHyphenate[n.nodeName.toLowerCase] && n.className.indexOf(dontHyphenateClass) === -1 && !(n in elToProcess)) { process(n, false, lang); } } }; if (isBookmarklet) { elToProcess = contextWindow.document.getElementsByTagName('body')[0]; process(elToProcess, false, mainLanguage); } else { elToProcess = selectorFunction; while (!!(tmp = elToProcess[i++])) { process(tmp, true, ''); }	} if (!Hyphenator.languages.hasOwnProperty(mainLanguage)) { docLanguages[mainLanguage] = true; } else if (!Hyphenator.languages[mainLanguage].prepared) { docLanguages[mainLanguage] = true; } if (elements.length > 0) { Expando.appendDataForElem(elements[elements.length - 1], {isLast : true}); } },

/** convertPatterns = function (lang) { var plen, anfang, ende, pats, pat, key, tmp = {}; pats = Hyphenator.languages[lang].patterns; for (plen in pats) { if (pats.hasOwnProperty(plen)) { plen = parseInt(plen, 10); anfang = 0; ende = plen; while (!!(pat = pats[plen].substring(anfang, ende))) { key = pat.replace(/\d/g, ''); tmp[key] = pat; anfang = ende; ende += plen; } } } Hyphenator.languages[lang].patterns = tmp; Hyphenator.languages[lang].patternsConverted = true; },
 * @name Hyphenator-convertPatterns
 * @description
 * Converts the patterns from string '_a6' to object '_a':'_a6'.
 * The result is stored in the {@link Hyphenator-patterns}-object.
 * @private
 * @param {string} lang the language whose patterns shall be converted

/** convertExceptionsToObject = function (exc) { var w = exc.split(', '), r = {}, i, l, key; for (i = 0, l = w.length; i < l; i++) { key = w[i].replace(/-/g, ''); if (!r.hasOwnProperty(key)) { r[key] = w[i]; } } return r; },
 * @name Hyphenator-convertExceptionsToObject
 * @description
 * Converts a list of comma seprated exceptions to an object:
 * 'Fortran,Hy-phen-a-tion' -> {'Fortran':'Fortran','Hyphenation':'Hy-phen-a-tion'}
 * @private
 * @param {string} exc a comma separated string of exceptions (without spaces)

/** loadPatterns = function (lang) { var url, xhr, head, script; if (supportedLang[lang] && !Hyphenator.languages[lang]) { url = basePath + 'patterns/' + supportedLang[lang]; } else { return; } if (isLocal && !isBookmarklet) { //check if 'url' is available: xhr = null; if (typeof XMLHttpRequest !== 'undefined') { xhr = new XMLHttpRequest; } if (!xhr) { try { xhr = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { xhr = null; } } if (xhr) { xhr.open('HEAD', url, false); xhr.setRequestHeader('Cache-Control', 'no-cache'); xhr.send(null); if (xhr.status === 404) { onError(new Error('Could not load\n' + url)); delete docLanguages[lang]; return; } } } if (createElem) { head = window.document.getElementsByTagName('head').item(0); script = createElem('script', window); script.src = url; script.type = 'text/javascript'; head.appendChild(script); } },
 * @name Hyphenator-loadPatterns
 * @description
 * Adds a &lt;script&gt;-Tag to the DOM to load an externeal .js-file containing patterns and settings for the given language.
 * If the given language is not in the {@link Hyphenator-supportedLang}-Object it returns.
 * One may ask why we are not using AJAX to load the patterns. The XMLHttpRequest-Object
 * has a same-origin-policy. This makes the isBookmarklet-functionality impossible.
 * @param {string} lang The language to load the patterns for
 * @private
 * @see Hyphenator-basePath

/** prepareLanguagesObj = function (lang) { var lo = Hyphenator.languages[lang], wrd; if (!lo.prepared) { if (enableCache) { lo.cache = {}; //Export lo['cache'] = lo.cache; } if (enableReducedPatternSet) { lo.redPatSet = {}; } //add exceptions from the pattern file to the local 'exceptions'-obj if (lo.hasOwnProperty('exceptions')) { Hyphenator.addExceptions(lang, lo.exceptions); delete lo.exceptions; } //copy global exceptions to the language specific exceptions if (exceptions.hasOwnProperty('global')) { if (exceptions.hasOwnProperty(lang)) { exceptions[lang] += ', ' + exceptions.global; } else { exceptions[lang] = exceptions.global; } } //move exceptions from the the local 'exceptions'-obj to the 'language'-object if (exceptions.hasOwnProperty(lang)) { lo.exceptions = convertExceptionsToObject(exceptions[lang]); delete exceptions[lang]; } else { lo.exceptions = {}; } convertPatterns(lang); wrd = '[\\w' + lo.specialChars + '@' + String.fromCharCode(173) + '-]{' + min + ',}'; lo.genRegExp = new RegExp('(' + url + ')|(' + mail + ')|(' + wrd + ')', 'gi'); lo.prepared = true; } if (!!storage) { try { storage.setItem('Hyphenator_' + lang, window.JSON.stringify(lo)); } catch (e) { //onError(e); } }
 * @name Hyphenator-prepareLanguagesObj
 * @description
 * Adds a cache to each language and converts the exceptions-list to an object.
 * If storage is active the object is stored there.
 * @private
 * @param {string} lang the language ob the lang-obj

},

/** prepare = function (callback) { var lang, interval, tmp1, tmp2; if (!enableRemoteLoading) { for (lang in Hyphenator.languages) { if (Hyphenator.languages.hasOwnProperty(lang)) { prepareLanguagesObj(lang); } } state = 2; callback; return; } // get all languages that are used and preload the patterns state = 1; for (lang in docLanguages) { if (docLanguages.hasOwnProperty(lang)) { if (!!storage && storage.getItem('Hyphenator_' + lang)) { Hyphenator.languages[lang] = window.JSON.parse(storage.getItem('Hyphenator_' + lang)); if (exceptions.hasOwnProperty('global')) { tmp1 = convertExceptionsToObject(exceptions.global); for (tmp2 in tmp1) { if (tmp1.hasOwnProperty(tmp2)) { Hyphenator.languages[lang].exceptions[tmp2] = tmp1[tmp2]; } } } //Replace exceptions since they may have been changed: if (exceptions.hasOwnProperty(lang)) { tmp1 = convertExceptionsToObject(exceptions[lang]); for (tmp2 in tmp1) { if (tmp1.hasOwnProperty(tmp2)) { Hyphenator.languages[lang].exceptions[tmp2] = tmp1[tmp2]; } } delete exceptions[lang]; } //Replace genRegExp since it may have been changed: tmp1 = '[\\w' + Hyphenator.languages[lang].specialChars + '@' + String.fromCharCode(173) + '-]{' + min + ',}'; Hyphenator.languages[lang].genRegExp = new RegExp('(' + url + ')|(' + mail + ')|(' + tmp1 + ')', 'gi');
 * @name Hyphenator-prepare
 * @description
 * This funtion prepares the Hyphenator-Object: If RemoteLoading is turned off, it assumes
 * that the patternfiles are loaded, all conversions are made and the callback is called.
 * If storage is active the object is retrieved there.
 * If RemoteLoading is on (default), it loads the pattern files and waits until they are loaded,
 * by repeatedly checking Hyphenator.languages. If a patterfile is loaded the patterns are
 * converted to their object style and the lang-object extended.
 * Finally the callback is called.
 * @param {function} callback to call, when all patterns are loaded
 * @private

delete docLanguages[lang]; continue; } else { loadPatterns(lang); } } } // if all patterns are loaded from storage: callback if (countObjProps(docLanguages) === 0) { state = 2; callback; return; } // else async wait until patterns are loaded, then callback interval = window.setInterval(function { var finishedLoading = true, lang; for (lang in docLanguages) { if (docLanguages.hasOwnProperty(lang)) { finishedLoading = false; if (!!Hyphenator.languages[lang]) { delete docLanguages[lang]; //do conversion while other patterns are loading: prepareLanguagesObj(lang); } } } if (finishedLoading) { //console.log('callig callback for ' + contextWindow.location.href); window.clearInterval(interval); state = 2; callback; } }, 100); },

/** toggleBox = function { var myBox, bdy, myIdAttribute, myTextNode, myClassAttribute, text = (Hyphenator.doHyphenation ? 'Hy-phen-a-tion' : 'Hyphenation'); if (!!(myBox = contextWindow.document.getElementById('HyphenatorToggleBox'))) { myBox.firstChild.data = text; } else { bdy = contextWindow.document.getElementsByTagName('body')[0]; myBox = createElem('div', contextWindow); myIdAttribute = contextWindow.document.createAttribute('id'); myIdAttribute.nodeValue = 'HyphenatorToggleBox'; myClassAttribute = contextWindow.document.createAttribute('class'); myClassAttribute.nodeValue = dontHyphenateClass; myTextNode = contextWindow.document.createTextNode(text); myBox.appendChild(myTextNode); myBox.setAttributeNode(myIdAttribute); myBox.setAttributeNode(myClassAttribute); myBox.onclick = Hyphenator.toggleHyphenation; myBox.style.position = 'absolute'; myBox.style.top = '0px'; myBox.style.right = '0px'; myBox.style.margin = '0'; myBox.style.backgroundColor = '#AAAAAA'; myBox.style.color = '#FFFFFF'; myBox.style.font = '6pt Arial'; myBox.style.letterSpacing = '0.2em'; myBox.style.padding = '3px'; myBox.style.cursor = 'pointer'; myBox.style.WebkitBorderBottomLeftRadius = '4px'; myBox.style.MozBorderRadiusBottomleft = '4px'; bdy.appendChild(myBox); } },
 * @name Hyphenator-switchToggleBox
 * @description
 * Creates or hides the toggleBox: a small button to turn off/on hyphenation on a page.
 * @param {boolean} s true when hyphenation is on, false when it's off
 * @see Hyphenator.config
 * @private

/** hyphenateWord = function (lang, word) { var lo = Hyphenator.languages[lang], parts, i, l, w, wl, s, hypos, p, maxwins, win, pat = false, patk, c, t, n, numb3rs, inserted, hyphenatedword, val; if (word === '') { return ''; } if (word.indexOf(hyphen) !== -1) { //word already contains shy; -> leave at it is! return word; } if (enableCache && lo.cache.hasOwnProperty(word)) { //the word is in the cache return lo.cache[word]; } if (lo.exceptions.hasOwnProperty(word)) { //the word is in the exceptions list return lo.exceptions[word].replace(/-/g, hyphen); } if (word.indexOf('-') !== -1) { //word contains '-' -> hyphenate the parts separated with '-' parts = word.split('-'); for (i = 0, l = parts.length; i < l; i++) { parts[i] = hyphenateWord(lang, parts[i]); } return parts.join('-'); } //finally the core hyphenation algorithm w = '_' + word + '_'; wl = w.length; s = w.split(''); if (word.indexOf("'") !== -1) { w = w.toLowerCase.replace("'", "’"); //replace APOSTROPHE with RIGHT SINGLE QUOTATION MARK (since the latter is used in the patterns) } else { w = w.toLowerCase; } hypos = []; numb3rs = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}; //check for member is faster then isFinite n = wl - lo.shortestPattern; for (p = 0; p <= n; p++) { maxwins = Math.min((wl - p), lo.longestPattern); for (win = lo.shortestPattern; win <= maxwins; win++) { if (lo.patterns.hasOwnProperty(patk = w.substring(p, p + win))) { pat = lo.patterns[patk]; if (enableReducedPatternSet && (typeof pat === 'string')) { lo.redPatSet[patk] = pat; } if (typeof pat === 'string') { //convert from string 'a5b' to array [1,5] (pos,value) t = 0; val = []; for (i = 0; i < pat.length; i++) { if (!!(c = numb3rs[pat.charAt(i)])) { val.push(i - t, c); t++; } } pat = lo.patterns[patk] = val; } } else { continue; } for (i = 0; i < pat.length; i++) { c = p - 1 + pat[i]; if (!hypos[c] || hypos[c] < pat[i + 1]) { hypos[c] = pat[i + 1]; } i++; } } } inserted = 0; for (i = lo.leftmin; i <= (word.length - lo.rightmin); i++) { if (!!(hypos[i] & 1)) { s.splice(i + inserted + 1, 0, hyphen); inserted++; } } hyphenatedword = s.slice(1, -1).join(''); if (enableCache) { lo.cache[word] = hyphenatedword; } return hyphenatedword; },
 * @name Hyphenator-hyphenateWord
 * @description
 * This function is the heart of Hyphenator.js. It returns a hyphenated word.
 * If there's already a {@link Hyphenator-hypen} in the word, the word is returned as it is.
 * If the word is in the exceptions list or in the cache, it is retrieved from it.
 * If there's a '-' put a zeroWidthSpace after the '-' and hyphenate the parts.
 * @param {string} lang The language of the word
 * @param {string} word The word
 * @returns string The hyphenated word
 * @public
 * @public

/** hyphenateURL = function (url) { return url.replace(/([:\/\.\?#&_,;!@]+)/gi, '$&' + urlhyphen); },
 * @name Hyphenator-hyphenateURL
 * @description
 * Puts {@link Hyphenator-urlhyphen} after each no-alphanumeric char that my be in a URL.
 * @param {string} url to hyphenate
 * @returns string the hyphenated URL
 * @public

/** removeHyphenationFromElement = function (el) { var h, i = 0, n; switch (hyphen) { case '|': h = '\\|'; break; case '+': h = '\\+'; break; case '*': h = '\\*'; break; default: h = hyphen; } while (!!(n = el.childNodes[i++])) { if (n.nodeType === 3) { n.data = n.data.replace(new RegExp(h, 'g'), ''); n.data = n.data.replace(new RegExp(zeroWidthSpace, 'g'), ''); } else if (n.nodeType === 1) { removeHyphenationFromElement(n); } } },
 * @name Hyphenator-removeHyphenationFromElement
 * @description
 * Removes all hyphens from the element. If there are other elements, the function is
 * called recursively.
 * Removing hyphens is usefull if you like to copy text. Some browsers are buggy when the copy hyphenated texts.
 * @param {Object} el The element where to remove hyphenation.
 * @public

/** registerOnCopy = function (el) { var body = el.ownerDocument.getElementsByTagName('body')[0], shadow, selection, range, rangeShadow, restore, oncopyHandler = function (e) { e = e || window.event; var target = e.target || e.srcElement, currDoc = target.ownerDocument, body = currDoc.getElementsByTagName('body')[0], targetWindow = 'defaultView' in currDoc ? currDoc.defaultView : currDoc.parentWindow; if (target.tagName && dontHyphenate[target.tagName.toLowerCase]) { //Safari needs this return; } //create a hidden shadow element shadow = currDoc.createElement('div'); shadow.style.overflow = 'hidden'; shadow.style.position = 'absolute'; shadow.style.top = '-5000px'; shadow.style.height = '1px'; body.appendChild(shadow); if (!!window.getSelection) { //FF3, Webkit selection = targetWindow.getSelection; range = selection.getRangeAt(0); shadow.appendChild(range.cloneContents); removeHyphenationFromElement(shadow); selection.selectAllChildren(shadow); restore = function { shadow.parentNode.removeChild(shadow); selection.addRange(range); }; } else { // IE selection = targetWindow.document.selection; range = selection.createRange; shadow.innerHTML = range.htmlText; removeHyphenationFromElement(shadow); rangeShadow = body.createTextRange; rangeShadow.moveToElementText(shadow); rangeShadow.select; restore = function { shadow.parentNode.removeChild(shadow); if (range.text !== "") { range.select; } }; } window.setTimeout(restore, 0); }; if (!body) { return; } el = el || body; if (window.addEventListener) { el.addEventListener("copy", oncopyHandler, false); } else { el.attachEvent("oncopy", oncopyHandler); } },
 * @name Hyphenator-registerOnCopy
 * @description
 * Huge work-around for browser-inconsistency when it comes to
 * copying of hyphenated text.
 * The idea behind this code has been provided by http://github.com/aristus/sweet-justice
 * sweet-justice is under BSD-License
 * @private

/** hyphenateElement = function (el) { var hyphenatorSettings = Expando.getDataForElem(el), lang = hyphenatorSettings.language, hyphenate, n, i, controlOrphans = function (part) { var h, r; switch (hyphen) { case '|': h = '\\|'; break; case '+': h = '\\+'; break; case '*': h = '\\*'; break; default: h = hyphen; } if (orphanControl >= 2) { //remove hyphen points from last word r = part.split(' '); r[1] = r[1].replace(new RegExp(h, 'g'), ''); r[1] = r[1].replace(new RegExp(zeroWidthSpace, 'g'), ''); r = r.join(' '); } if (orphanControl === 3) { //replace spaces by non breaking spaces r = r.replace(/[ ]+/g, String.fromCharCode(160)); } return r; }; if (Hyphenator.languages.hasOwnProperty(lang)) { hyphenate = function (word) { if (!Hyphenator.doHyphenation) { return word; } else if (urlOrMailRE.test(word)) { return hyphenateURL(word); } else { return hyphenateWord(lang, word); } }; if (safeCopy && (el.tagName.toLowerCase !== 'body')) { registerOnCopy(el); } i = 0; while (!!(n = el.childNodes[i++])) { if (n.nodeType === 3 && n.data.length >= min) { //type 3 = #text -> hyphenate! n.data = n.data.replace(Hyphenator.languages[lang].genRegExp, hyphenate); if (orphanControl !== 1) { n.data = n.data.replace(/[\S]+ [\S]+$/, controlOrphans); } } } } if (hyphenatorSettings.isHidden && intermediateState === 'hidden') { el.style.visibility = 'visible'; if (!hyphenatorSettings.hasOwnStyle) { el.setAttribute('style', ''); // without this, removeAttribute doesn't work in Safari (thanks to molily) el.removeAttribute('style'); } else { if (el.style.removeProperty) { el.style.removeProperty('visibility'); } else if (el.style.removeAttribute) { // IE el.style.removeAttribute('visibility'); } } } if (hyphenatorSettings.isLast) { state = 3; documentCount--; if (documentCount > (-1000) && documentCount <= 0) { documentCount = (-2000); onHyphenationDone; } } },
 * @name Hyphenator-hyphenateElement
 * @description
 * Takes the content of the given element and - if there's text - replaces the words
 * by hyphenated words. If there's another element, the function is called recursively.
 * When all words are hyphenated, the visibility of the element is set to 'visible'.
 * @param {Object} el The element to hyphenate
 * @private

/** hyphenateDocument = function { function bind(fun, arg) { return function { return fun(arg); }; } var i = 0, el; while (!!(el = elements[i++])) { if (el.ownerDocument.location.href === contextWindow.location.href) { window.setTimeout(bind(hyphenateElement, el), 0); } } },
 * @name Hyphenator-hyphenateDocument
 * @description
 * Calls hyphenateElement for all members of elements. This is done with a setTimout
 * to prevent a "long running Script"-alert when hyphenating large pages.
 * Therefore a tricky bind-function was necessary.
 * @private

/** removeHyphenationFromDocument = function { var i = 0, el; while (!!(el = elements[i++])) { removeHyphenationFromElement(el); } state = 4; },
 * @name Hyphenator-removeHyphenationFromDocument
 * @description
 * Does what it says ;-)
 * @private

/** createStorage = function { try { if (storageType !== 'none' && typeof(window.localStorage) !== 'undefined' && typeof(window.sessionStorage) !== 'undefined' && typeof(window.JSON.stringify) !== 'undefined' && typeof(window.JSON.parse) !== 'undefined') { switch (storageType) { case 'session': storage = window.sessionStorage; break; case 'local': storage = window.localStorage; break; default: storage = undefined; break; } } } catch (f) { //FF throws an error if DOM.storage.enabled is set to false } },
 * @name Hyphenator-createStorage
 * @description
 * inits the private var storage depending of the setting in storageType
 * and the supported features of the system.
 * @private

/** storeConfiguration = function { if (!storage) { return; } var settings = { 'STORED': true, 'classname': hyphenateClass, 'donthyphenateclassname': dontHyphenateClass, 'minwordlength': min, 'hyphenchar': hyphen, 'urlhyphenchar': urlhyphen, 'togglebox': toggleBox, 'displaytogglebox': displayToggleBox, 'remoteloading': enableRemoteLoading, 'enablecache': enableCache, 'onhyphenationdonecallback': onHyphenationDone, 'onerrorhandler': onError, 'intermediatestate': intermediateState, 'selectorfunction': selectorFunction, 'safecopy': safeCopy, 'doframes': doFrames, 'storagetype': storageType, 'orphancontrol': orphanControl, 'dohyphenation': Hyphenator.doHyphenation, 'persistentconfig': persistentConfig, 'defaultlanguage': defaultLanguage }; storage.setItem('Hyphenator_config', window.JSON.stringify(settings)); },
 * @name Hyphenator-storeConfiguration
 * @description
 * Stores the current config-options in DOM-Storage
 * @private

/** restoreConfiguration = function { var settings; if (storage.getItem('Hyphenator_config')) { settings = window.JSON.parse(storage.getItem('Hyphenator_config')); Hyphenator.config(settings); } };
 * @name Hyphenator-restoreConfiguration
 * @description
 * Retrieves config-options from DOM-Storage and does configuration accordingly
 * @private

return {

/** version: '3.2.0',
 * @name Hyphenator.version
 * @memberOf Hyphenator
 * @description
 * String containing the actual version of Hyphenator.js
 * [major release].[minor releas].[bugfix release]
 * major release: new API, new Features, big changes
 * minor release: new languages, improvements
 * @public

/** doHyphenation: true,
 * @name Hyphenator.doHyphenation
 * @description
 * If doHyphenation is set to false (defaults to true), hyphenateDocument isn't called.
 * All other actions are performed.

/** languages: {},
 * @name Hyphenator.languages
 * @memberOf Hyphenator
 * @description
 * Objects that holds key-value pairs, where key is the language and the value is the
 * language-object loaded from (and set by) the pattern file.
 * The language object holds the following members:
 * And optionally (or after prepareLanguagesObj has been called):
 * @public
 * @public
 * @public

/** config: function (obj) { var assert = function (name, type) { if (typeof obj[name] === type) { return true; } else { onError(new Error('Config onError: ' + name + ' must be of type ' + type)); return false; } }, key;
 * @name Hyphenator.config
 * @description
 * Config function that takes an object as an argument. The object contains key-value-pairs
 * containig Hyphenator-settings. This is a shortcut for calling Hyphenator.set...-Methods.
 * @param {Object} obj
 * @public
 * @example &lt;script src = "Hyphenator.js" type = "text/javascript"&gt;&lt;/script&gt;
 * &lt;script type = "text/javascript"&gt;
 * Hyphenator.config({'minwordlength':4,'hyphenchar':'|'});
 * Hyphenator.run;
 * &lt;/script&gt;

if (obj.hasOwnProperty('storagetype')) { if (assert('storagetype', 'string')) { storageType = obj.storagetype; } if (!storage) { createStorage; }	} if (!obj.hasOwnProperty('STORED') && storage && obj.hasOwnProperty('persistentconfig') && obj.persistentconfig === true) { restoreConfiguration; }

for (key in obj) { if (obj.hasOwnProperty(key)) { switch (key) { case 'STORED': break; case 'classname': if (assert('classname', 'string')) { hyphenateClass = obj[key]; } break; case 'donthyphenateclassname': if (assert('donthyphenateclassname', 'string')) { dontHyphenateClass = obj[key]; }	break; case 'minwordlength': if (assert('minwordlength', 'number')) { min = obj[key]; } break; case 'hyphenchar': if (assert('hyphenchar', 'string')) { if (obj.hyphenchar === '&shy;') { obj.hyphenchar = String.fromCharCode(173); } hyphen = obj[key]; } break; case 'urlhyphenchar': if (obj.hasOwnProperty('urlhyphenchar')) { if (assert('urlhyphenchar', 'string')) { urlhyphen = obj[key]; } } break; case 'togglebox': if (assert('togglebox', 'function')) { toggleBox = obj[key]; } break; case 'displaytogglebox': if (assert('displaytogglebox', 'boolean')) { displayToggleBox = obj[key]; } break; case 'remoteloading': if (assert('remoteloading', 'boolean')) { enableRemoteLoading = obj[key]; } break; case 'enablecache': if (assert('enablecache', 'boolean')) { enableCache = obj[key]; } break; case 'enablereducedpatternset': if (assert('enablereducedpatternset', 'boolean')) { enableReducedPatternSet = obj[key]; } break; case 'onhyphenationdonecallback': if (assert('onhyphenationdonecallback', 'function')) { onHyphenationDone = obj[key]; } break; case 'onerrorhandler': if (assert('onerrorhandler', 'function')) { onError = obj[key]; } break; case 'intermediatestate': if (assert('intermediatestate', 'string')) { intermediateState = obj[key]; } break; case 'selectorfunction': if (assert('selectorfunction', 'function')) { selectorFunction = obj[key]; } break; case 'safecopy': if (assert('safecopy', 'boolean')) { safeCopy = obj[key]; } break; case 'doframes': if (assert('doframes', 'boolean')) { doFrames = obj[key]; } break; case 'storagetype': if (assert('storagetype', 'string')) { storageType = obj[key]; }	break; case 'orphancontrol': if (assert('orphancontrol', 'number')) { orphanControl = obj[key]; } break; case 'dohyphenation': if (assert('dohyphenation', 'boolean')) { Hyphenator.doHyphenation = obj[key]; } break; case 'persistentconfig': if (assert('persistentconfig', 'boolean')) { persistentConfig = obj[key]; } break; case 'defaultlanguage': if (assert('defaultlanguage', 'string')) { defaultLanguage = obj[key]; } break; default: onError(new Error('Hyphenator.config: property ' + key + ' not known.')); } } } if (storage && persistentConfig) { storeConfiguration; } },

/** run: function { documentCount = 0; var process = function { try { if (contextWindow.document.getElementsByTagName('frameset').length > 0) { return; //we are in a frameset } documentCount++; autoSetMainLanguage(undefined); gatherDocumentInfos; //console.log('preparing for ' + contextWindow.location.href); prepare(hyphenateDocument); if (displayToggleBox) { toggleBox; } } catch (e) { onError(e); } }, i, haveAccess, fl = window.frames.length;
 * @name Hyphenator.run
 * @description
 * Bootstrap function that starts all hyphenation processes when called.
 * @public
 * @example &lt;script src = "Hyphenator.js" type = "text/javascript"&gt;&lt;/script&gt;
 * &lt;script type = "text/javascript"&gt;
 * Hyphenator.run;
 * &lt;/script&gt;

if (!storage) { createStorage; } if (!documentLoaded && !isBookmarklet) { runOnContentLoaded(window, process); } if (isBookmarklet || documentLoaded) { if (doFrames && fl > 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) { contextWindow = window.frames[i]; process; }	} } contextWindow = window; process; } },

/** addExceptions: function (lang, words) { if (lang === '') { lang = 'global'; } if (exceptions.hasOwnProperty(lang)) { exceptions[lang] += ", " + words; } else { exceptions[lang] = words; } },
 * @name Hyphenator.addExceptions
 * @description
 * Adds the exceptions from the string to the appropriate language in the
 * {@link Hyphenator-languages}-object
 * @param {string} lang The language
 * @param {string} words A comma separated string of hyphenated words WITH spaces.
 * @public
 * @example &lt;script src = "Hyphenator.js" type = "text/javascript"&gt;&lt;/script&gt;
 * &lt;script type = "text/javascript"&gt;
 * Hyphenator.addExceptions('de','ziem-lich, Wach-stube');
 * Hyphenator.run;
 * &lt;/script&gt;

/** hyphenate: function (target, lang) { var hyphenate, n, i; if (Hyphenator.languages.hasOwnProperty(lang)) { if (!Hyphenator.languages[lang].prepared) { prepareLanguagesObj(lang); } hyphenate = function (word) { if (urlOrMailRE.test(word)) { return hyphenateURL(word); } else { return hyphenateWord(lang, word); } }; if (typeof target === 'string' || target.constructor === String) { return target.replace(Hyphenator.languages[lang].genRegExp, hyphenate); } else if (typeof target === 'object') { i = 0; while (!!(n = target.childNodes[i++])) { if (n.nodeType === 3 && n.data.length >= min) { //type 3 = #text -> hyphenate! n.data = n.data.replace(Hyphenator.languages[lang].genRegExp, hyphenate); } else if (n.nodeType === 1) { if (n.lang !== '') { Hyphenator.hyphenate(n, n.lang); } else { Hyphenator.hyphenate(n, lang); } } } } } else { onError(new Error('Language "' + lang + '" is not loaded.')); } },
 * @name Hyphenator.hyphenate
 * @public
 * @description
 * Hyphenates the target. The language patterns must be loaded.
 * If the target is a string, the hyphenated string is returned,
 * if it's an object, the values are hyphenated directly.
 * @param {string|Object} target the target to be hyphenated
 * @param {string} lang the language of the target
 * @returns string
 * @example &lt;script src = "Hyphenator.js" type = "text/javascript"&gt;&lt;/script&gt;
 * &lt;script src = "patterns/en.js" type = "text/javascript"&gt;&lt;/script&gt;
 * &lt;script type = "text/javascript"&gt;
 * var t = Hyphenator.hyphenate('Hyphenation', 'en'); //Hy|phen|ation
 * &lt;/script&gt;

/** getRedPatternSet: function (lang) { return Hyphenator.languages[lang].redPatSet; },
 * @name Hyphenator.getRedPatternSet
 * @description
 * Returns {@link Hyphenator-isBookmarklet}.
 * @param {string} lang the language patterns are stored for
 * @returns object {'patk': pat}
 * @public

/** isBookmarklet: function { return isBookmarklet; },
 * @name Hyphenator.isBookmarklet
 * @description
 * Returns {@link Hyphenator-isBookmarklet}.
 * @returns boolean
 * @public

getConfigFromURI: function { var loc = null, re = {}, jsArray = document.getElementsByTagName('script'), i, j, l, s, gp, option; for (i = 0, l = jsArray.length; i < l; i++) { if (!!jsArray[i].getAttribute('src')) { loc = jsArray[i].getAttribute('src'); } if (!loc) { continue; } else { s = loc.indexOf('Hyphenator.js?'); if (s === -1) { continue; } gp = loc.substring(s + 14).split('&'); for (j = 0; j < gp.length; j++) { option = gp[j].split('='); if (option[0] === 'bm') { continue; } if (option[1] === 'true') { re[option[0]] = true; continue; } if (option[1] === 'false') { re[option[0]] = false; continue; } if (isFinite(option[1])) { re[option[0]] = parseInt(option[1], 10); continue; } if (option[0] === 'onhyphenationdonecallback') { re[option[0]] = new Function('', option[1]); continue; } re[option[0]] = option[1]; } break; } } return re; },

/** toggleHyphenation: function { if (Hyphenator.doHyphenation) { removeHyphenationFromDocument; Hyphenator.doHyphenation = false; storeConfiguration; toggleBox; } else { hyphenateDocument; Hyphenator.doHyphenation = true; storeConfiguration; toggleBox; } } }; }(window));
 * @name Hyphenator.toggleHyphenation
 * @description
 * Checks the current state of the ToggleBox and removes or does hyphenation.
 * @public

//Export properties/methods (for google closure compiler) Hyphenator['languages'] = Hyphenator.languages; Hyphenator['config'] = Hyphenator.config; Hyphenator['run'] = Hyphenator.run; Hyphenator['addExceptions'] = Hyphenator.addExceptions; Hyphenator['hyphenate'] = Hyphenator.hyphenate; Hyphenator['getRedPatternSet'] = Hyphenator.getRedPatternSet; Hyphenator['isBookmarklet'] = Hyphenator.isBookmarklet; Hyphenator['getConfigFromURI'] = Hyphenator.getConfigFromURI; Hyphenator['toggleHyphenation'] = Hyphenator.toggleHyphenation; window['Hyphenator'] = Hyphenator;

if (Hyphenator.isBookmarklet) { Hyphenator.config({displaytogglebox: true, intermediatestate: 'visible', doframes: true}); Hyphenator.config(Hyphenator.getConfigFromURI); Hyphenator.run; }

/* Not Hyphenator.js below */

// From https://gist.github.com/705071 // And http://code.google.com/p/ligature-js/ function smarten(a) { a = a.replace(/(^|[-\u2014/(\[{"\s])'/g, "$1\u2018"); // opening singles a = a.replace(/'/g, "\u2019"); // closing singles & apostrophes a = a.replace(/(^|[-\u2014/(\[{\u2018\s])"/g, "$1\u201c"); // opening doubles a = a.replace(/"/g, "\u201d"); // closing doubles

a = a.replace(/ffl/g, 'ﬄ') .replace(/ffi/g, 'ﬃ') .replace(/fl/g, 'ﬂ') .replace(/fi/g, 'ﬁ') .replace(/ff/g, 'ﬀ') .replace(/ij/g, 'ĳ') .replace(/IJ/g, 'Ĳ');

return a }

function smartenNode(node) { if(node.nodeType == 3) node.nodeValue = smarten(node.nodeValue); }

// From http://blog.dingoeweb.com/javascript/recursive-iteration-through-the-html-dom iterate = function iterate(task, node) { for(var x = 0; x < node.childNodes.length; x++) { var childNode = node.childNodes[x]; task(childNode); if(childNode.childNodes.length > 0) iterate(task, childNode); } }

document.getElementById('searchInput').placeholder = "Search Wikipedia…";

document.getElementById('ca-edit').getElementsByTagName('a')[0].innerText = "Edit";

document.getElementById('p-tb').getElementsByTagName('h5')[0].innerText = "Tools"; document.getElementById('p-coll-print_export').getElementsByTagName('h5')[0].innerText = "Print";

iterate(smartenNode, document);

if(navigator.userAgent.match(/iPad/i)) { var viewportmeta = document.createElement('meta'); viewportmeta.setAttribute('name', 'viewport'); viewportmeta.content = 'width=device-width, initial-scale=1.0, minimum-scale=1.0'; document.getElementsByTagName('head')[0].appendChild(viewportmeta); } else { var images = document.getElementsByClassName("thumbinner"); for(var i = 0; i < images.length; i++) images[i].getElementsByTagName('a')[0].setAttribute('rel', 'lightbox');

var para = document.getElementsByTagName("p"); for(var i = 0; i < para.length; i++) para[i].className = "hyphenate";

Hyphenator.run; }

GitHub Links

GitHub About Blog Features Contact & Support Training GitHub Enterprise Site Status

Clients GitHub for Mac GitHub for Windows GitHub for Eclipse GitHub Mobile Apps

Tools Gauges: Web analytics Speaker Deck: Presentations Gist: Code snippets Extras Job Board GitHub Shop The Octodex

Documentation GitHub Help Developer API GitHub Flavored Markdown GitHub Pages

Terms of Service Privacy Security

© 2012 GitHub Inc. All rights reserved. Dedicated Server Powered by the Dedicated Servers and Cloud Computing of Rackspace Hosting®