all repos — h3rald @ 640fa955633370e1ec7d4f18aec87f24cdc8c46c

The sources of https://h3rald.com

No longer storing *anything* on client browsers anymore (EU "Cookie Law" compliance).
h3rald h3rald@h3rald.com
Fri, 05 Jun 2015 20:39:44 +0200
commit

640fa955633370e1ec7d4f18aec87f24cdc8c46c

parent

040d2120cac18405fe70e5dea72d2f85f5cee2b3

A content/js/fingerprint.min.js

@@ -0,0 +1,1 @@

+(function(a,c,b){if(typeof module!=="undefined"&&module.exports){module.exports=b()}else{if(typeof define==="function"&&define.amd){define(b)}else{c[a]=b()}}})("Fingerprint",this,function(){var a=function(b){var c,d;c=Array.prototype.forEach;d=Array.prototype.map;this.each=function(k,j,h){if(k===null){return}if(c&&k.forEach===c){k.forEach(j,h)}else{if(k.length===+k.length){for(var g=0,e=k.length;g<e;g++){if(j.call(h,k[g],g,k)==={}){return}}}else{for(var f in k){if(k.hasOwnProperty(f)){if(j.call(h,k[f],f,k)==={}){return}}}}}};this.map=function(h,g,f){var e=[];if(h==null){return e}if(d&&h.map===d){return h.map(g,f)}this.each(h,function(k,i,j){e[e.length]=g.call(f,k,i,j)});return e};if(typeof b=="object"){this.hasher=b.hasher;this.screen_resolution=b.screen_resolution;this.canvas=b.canvas;this.ie_activex=b.ie_activex}else{if(typeof b=="function"){this.hasher=b}}};a.prototype={get:function(){var c=[];c.push(navigator.userAgent);c.push(navigator.language);c.push(screen.colorDepth);if(this.screen_resolution){var b=this.getScreenResolution();if(typeof b!=="undefined"){c.push(this.getScreenResolution().join("x"))}}c.push(new Date().getTimezoneOffset());c.push(this.hasSessionStorage());c.push(this.hasLocalStorage());c.push(!!window.indexedDB);if(document.body){c.push(typeof(document.body.addBehavior))}else{c.push(typeof undefined)}c.push(typeof(window.openDatabase));c.push(navigator.cpuClass);c.push(navigator.platform);c.push(navigator.doNotTrack);c.push(this.getPluginsString());if(this.canvas&&this.isCanvasSupported()){c.push(this.getCanvasFingerprint())}if(this.hasher){return this.hasher(c.join("###"),31)}else{return this.murmurhash3_32_gc(c.join("###"),31)}},murmurhash3_32_gc:function(j,f){var k,l,h,b,e,c,g,d;k=j.length&3;l=j.length-k;h=f;e=3432918353;c=461845907;d=0;while(d<l){g=((j.charCodeAt(d)&255))|((j.charCodeAt(++d)&255)<<8)|((j.charCodeAt(++d)&255)<<16)|((j.charCodeAt(++d)&255)<<24);++d;g=((((g&65535)*e)+((((g>>>16)*e)&65535)<<16)))&4294967295;g=(g<<15)|(g>>>17);g=((((g&65535)*c)+((((g>>>16)*c)&65535)<<16)))&4294967295;h^=g;h=(h<<13)|(h>>>19);b=((((h&65535)*5)+((((h>>>16)*5)&65535)<<16)))&4294967295;h=(((b&65535)+27492)+((((b>>>16)+58964)&65535)<<16))}g=0;switch(k){case 3:g^=(j.charCodeAt(d+2)&255)<<16;case 2:g^=(j.charCodeAt(d+1)&255)<<8;case 1:g^=(j.charCodeAt(d)&255);g=(((g&65535)*e)+((((g>>>16)*e)&65535)<<16))&4294967295;g=(g<<15)|(g>>>17);g=(((g&65535)*c)+((((g>>>16)*c)&65535)<<16))&4294967295;h^=g}h^=j.length;h^=h>>>16;h=(((h&65535)*2246822507)+((((h>>>16)*2246822507)&65535)<<16))&4294967295;h^=h>>>13;h=((((h&65535)*3266489909)+((((h>>>16)*3266489909)&65535)<<16)))&4294967295;h^=h>>>16;return h>>>0},hasLocalStorage:function(){try{return !!window.localStorage}catch(b){return true}},hasSessionStorage:function(){try{return !!window.sessionStorage}catch(b){return true}},isCanvasSupported:function(){var b=document.createElement("canvas");return !!(b.getContext&&b.getContext("2d"))},isIE:function(){if(navigator.appName==="Microsoft Internet Explorer"){return true}else{if(navigator.appName==="Netscape"&&/Trident/.test(navigator.userAgent)){return true}}return false},getPluginsString:function(){if(this.isIE()&&this.ie_activex){return this.getIEPluginsString()}else{return this.getRegularPluginsString()}},getRegularPluginsString:function(){return this.map(navigator.plugins,function(c){var b=this.map(c,function(d){return[d.type,d.suffixes].join("~")}).join(",");return[c.name,c.description,b].join("::")},this).join(";")},getIEPluginsString:function(){if(window.ActiveXObject){var b=["ShockwaveFlash.ShockwaveFlash","AcroPDF.PDF","PDF.PdfCtrl","QuickTime.QuickTime","rmocx.RealPlayer G2 Control","rmocx.RealPlayer G2 Control.1","RealPlayer.RealPlayer(tm) ActiveX Control (32-bit)","RealVideo.RealVideo(tm) ActiveX Control (32-bit)","RealPlayer","SWCtl.SWCtl","WMPlayer.OCX","AgControl.AgControl","Skype.Detection"];return this.map(b,function(c){try{new ActiveXObject(c);return c}catch(d){return null}}).join(";")}else{return""}},getScreenResolution:function(){return[screen.height,screen.width]},getCanvasFingerprint:function(){var d=document.createElement("canvas");var c=d.getContext("2d");var b="http://valve.github.io";c.textBaseline="top";c.font="14px 'Arial'";c.textBaseline="alphabetic";c.fillStyle="#f60";c.fillRect(125,1,62,20);c.fillStyle="#069";c.fillText(b,2,15);c.fillStyle="rgba(102, 204, 0, 0.7)";c.fillText(b,4,17);return d.toDataURL()}};return a});
D content/js/hyphenator.js

@@ -1,3002 +0,0 @@

-/** @license Hyphenator 4.3.0 - client side hyphenation for webbrowsers - * Copyright (C) 2014 Mathias Nater, Zürich (mathiasnater at gmail dot com) - * 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 jsdoc3 formatted. See http://usejsdoc.org - * Use mergeAndPack.html to get rid of the comments and to reduce the file size of this script! - */ - -/* The following comment is for JSLint: */ -/*jslint browser: true */ - -/** - * @desc Provides all functionality to do hyphenation, except the patterns that are loaded externally - * @global - * @namespace Hyphenator - * @author Mathias Nater, <mathias@mnn.ch> - * @version X.Y.Z - * @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 Hyphenator = (function (window) { - 'use strict'; - - /** - * @member Hyphenator~contextWindow - * @access private - * @desc - * contextWindow stores the window for the actual document to be hyphenated. - * If there are frames this will change. - * So use contextWindow instead of window! - */ - var contextWindow = window, - - - /** - * @member {Object.<string, Hyphenator~supportedLangs~supportedLanguage>} Hyphenator~supportedLangs - * @desc - * A generated key-value object that stores supported languages and meta data. - * The key is the {@link http://tools.ietf.org/rfc/bcp/bcp47.txt bcp47} code of the language and the value - * is an object of type {@link Hyphenator~supportedLangs~supportedLanguage} - * @namespace Hyphenator~supportedLangs - * @access private - * //Check if language lang is supported: - * if (supportedLangs.hasOwnProperty(lang)) - */ - supportedLangs = (function () { - /** - * @typedef {Object} Hyphenator~supportedLangs~supportedLanguage - * @property {string} file - The name of the pattern file - * @property {number} script - The script type of the language (e.g. 'latin' for english), this type is abbreviated by an id - * @property {string} prompt - The sentence prompted to the user, if Hyphenator.js doesn't find a language hint - */ - - /** - * @lends Hyphenator~supportedLangs - */ - var r = {}, - /** - * @method Hyphenator~supportedLangs~o - * @desc - * Sets a value of Hyphenator~supportedLangs - * @access protected - * @param {string} code The {@link http://tools.ietf.org/rfc/bcp/bcp47.txt bcp47} code of the language - * @param {string} file The name of the pattern file - * @param {Number} script A shortcut for a specific script: latin:0, cyrillic: 1, arabic: 2, armenian:3, bengali: 4, devangari: 5, greek: 6 - * gujarati: 7, kannada: 8, lao: 9, malayalam: 10, oriya: 11, persian: 12, punjabi: 13, tamil: 14, telugu: 15 - * @param {string} prompt The sentence prompted to the user, if Hyphenator.js doesn't find a language hint - */ - o = function (code, file, script, prompt) { - r[code] = {'file': file, 'script': script, 'prompt': prompt}; - }; - - o('be', 'be.js', 1, 'Мова гэтага сайта не можа быць вызначаны аўтаматычна. Калі ласка пакажыце мову:'); - o('ca', 'ca.js', 0, ''); - o('cs', 'cs.js', 0, 'Jazyk této internetové stránky nebyl automaticky rozpoznán. Určete prosím její jazyk:'); - o('da', 'da.js', 0, 'Denne websides sprog kunne ikke bestemmes. Angiv venligst sprog:'); - o('bn', 'bn.js', 4, ''); - o('de', 'de.js', 0, 'Die Sprache dieser Webseite konnte nicht automatisch bestimmt werden. Bitte Sprache angeben:'); - o('el', 'el-monoton.js', 6, ''); - o('el-monoton', 'el-monoton.js', 6, ''); - o('el-polyton', 'el-polyton.js', 6, ''); - o('en', 'en-us.js', 0, 'The language of this website could not be determined automatically. Please indicate the main language:'); - o('en-gb', 'en-gb.js', 0, 'The language of this website could not be determined automatically. Please indicate the main language:'); - o('en-us', 'en-us.js', 0, 'The language of this website could not be determined automatically. Please indicate the main language:'); - o('eo', 'eo.js', 0, 'La lingvo de ĉi tiu retpaĝo ne rekoneblas aŭtomate. Bonvolu indiki ĝian ĉeflingvon:'); - o('es', 'es.js', 0, 'El idioma del sitio no pudo determinarse autom%E1ticamente. Por favor, indique el idioma principal:'); - o('et', 'et.js', 0, 'Veebilehe keele tuvastamine ebaõnnestus, palun valige kasutatud keel:'); - o('fi', 'fi.js', 0, 'Sivun kielt%E4 ei tunnistettu automaattisesti. M%E4%E4rit%E4 sivun p%E4%E4kieli:'); - o('fr', 'fr.js', 0, 'La langue de ce site n%u2019a pas pu %EAtre d%E9termin%E9e automatiquement. Veuillez indiquer une langue, s.v.p.%A0:'); - o('grc', 'grc.js', 6, ''); - o('gu', 'gu.js', 7, ''); - o('hi', 'hi.js', 5, ''); - o('hu', 'hu.js', 0, 'A weboldal nyelvét nem sikerült automatikusan megállapítani. Kérem adja meg a nyelvet:'); - o('hy', 'hy.js', 3, 'Չհաջողվեց հայտնաբերել այս կայքի լեզուն։ Խնդրում ենք նշեք հիմնական լեզուն՝'); - o('it', 'it.js', 0, 'Lingua del sito sconosciuta. Indicare una lingua, per favore:'); - o('kn', 'kn.js', 8, 'ಜಾಲ ತಾಣದ ಭಾಷೆಯನ್ನು ನಿರ್ಧರಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ. ದಯವಿಟ್ಟು ಮುಖ್ಯ ಭಾಷೆಯನ್ನು ಸೂಚಿಸಿ:'); - o('la', 'la.js', 0, ''); - o('lt', 'lt.js', 0, 'Nepavyko automatiškai nustatyti šios svetainės kalbos. Prašome įvesti kalbą:'); - o('lv', 'lv.js', 0, 'Šīs lapas valodu nevarēja noteikt automātiski. Lūdzu norādiet pamata valodu:'); - o('ml', 'ml.js', 10, 'ഈ വെ%u0D2C%u0D4D%u200Cസൈറ്റിന്റെ ഭാഷ കണ്ടുപിടിയ്ക്കാ%u0D28%u0D4D%u200D കഴിഞ്ഞില്ല. ഭാഷ ഏതാണെന്നു തിരഞ്ഞെടുക്കുക:'); - o('nb', 'nb-no.js', 0, 'Nettstedets språk kunne ikke finnes automatisk. Vennligst oppgi språk:'); - o('no', 'nb-no.js', 0, 'Nettstedets språk kunne ikke finnes automatisk. Vennligst oppgi språk:'); - o('nb-no', 'nb-no.js', 0, 'Nettstedets språk kunne ikke finnes automatisk. Vennligst oppgi språk:'); - o('nl', 'nl.js', 0, 'De taal van deze website kan niet automatisch worden bepaald. Geef de hoofdtaal op:'); - o('or', 'or.js', 11, ''); - o('pa', 'pa.js', 13, ''); - o('pl', 'pl.js', 0, 'Języka tej strony nie można ustalić automatycznie. Proszę wskazać język:'); - o('pt', 'pt.js', 0, 'A língua deste site não pôde ser determinada automaticamente. Por favor indique a língua principal:'); - o('ru', 'ru.js', 1, 'Язык этого сайта не может быть определен автоматически. Пожалуйста укажите язык:'); - o('sk', 'sk.js', 0, ''); - o('sl', 'sl.js', 0, 'Jezika te spletne strani ni bilo mogoče samodejno določiti. Prosim navedite jezik:'); - o('sr-cyrl', 'sr-cyrl.js', 1, 'Језик овог сајта није детектован аутоматски. Молим вас наведите језик:'); - o('sr-latn', 'sr-latn.js', 0, 'Jezika te spletne strani ni bilo mogoče samodejno določiti. Prosim navedite jezik:'); - o('sv', 'sv.js', 0, 'Spr%E5ket p%E5 den h%E4r webbplatsen kunde inte avg%F6ras automatiskt. V%E4nligen ange:'); - o('ta', 'ta.js', 14, ''); - o('te', 'te.js', 15, ''); - o('tr', 'tr.js', 0, 'Bu web sitesinin dili otomatik olarak tespit edilememiştir. Lütfen dökümanın dilini seçiniz%A0:'); - o('uk', 'uk.js', 1, 'Мова цього веб-сайту не може бути визначена автоматично. Будь ласка, вкажіть головну мову:'); - o('ro', 'ro.js', 0, 'Limba acestui sit nu a putut fi determinată automat. Alege limba principală:'); - - return r; - }()), - - - /** - * @member {string} Hyphenator~basePath - * @desc - * A string storing the basepath from where Hyphenator.js was loaded. - * This is used to load the pattern files. - * The basepath is determined dynamically by searching all script-tags for Hyphenator.js - * If the path cannot be determined {@link http://hyphenator.googlecode.com/svn/trunk/} is used as fallback. - * @access private - * @see {@link Hyphenator~loadPatterns} - */ - basePath = (function () { - var s = contextWindow.document.getElementsByTagName('script'), i = 0, p, src, t = s[i], r = ''; - while (!!t) { - if (!!t.src) { - src = t.src; - p = src.indexOf('Hyphenator.js'); - if (p !== -1) { - r = src.substring(0, p); - } - } - i += 1; - t = s[i]; - } - return !!r ? r : '//hyphenator.googlecode.com/svn/trunk/'; - }()), - - /** - * @member {boolean} Hyphenator~isLocal - * @access private - * @desc - * 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; - }()), - - /** - * @member {boolean} Hyphenator~documentLoaded - * @access private - * @desc - * documentLoaded is true, when the DOM has been loaded. This is set by {@link Hyphenator~runWhenLoaded} - */ - documentLoaded = false, - - /** - * @member {boolean} Hyphenator~persistentConfig - * @access private - * @desc - * 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. - * @default false - * @see {@link Hyphenator.config} - */ - persistentConfig = false, - - /** - * @member {boolean} Hyphenator~doFrames - * @access private - * @desc - * switch to control if frames/iframes should be hyphenated, too. - * defaults to false (frames are a bag of hurt!) - * @default false - * @see {@link Hyphenator.config} - */ - doFrames = false, - - /** - * @member {Object.<string,boolean>} Hyphenator~dontHyphenate - * @desc - * A key-value object containing all html-tags whose content should not be hyphenated - * @access private - */ - dontHyphenate = {'video': true, 'audio': true, '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, 'style': true}, - - /** - * @member {boolean} Hyphenator~enableCache - * @desc - * A variable to set if caching is enabled or not - * @default true - * @access private - * @see {@link Hyphenator.config} - */ - enableCache = true, - - /** - * @member {string} Hyphenator~storageType - * @desc - * A variable to define what html5-DOM-Storage-Method is used ('none', 'local' or 'session') - * @default 'local' - * @access private - * @see {@link Hyphenator.config} - */ - storageType = 'local', - - /** - * @member {Object|undefined} Hyphenator~storage - * @desc - * An alias to the storage defined in storageType. This is set by {@link Hyphenator~createStorage}. - * Set by {@link Hyphenator.run} - * @default null - * @access private - * @see {@link Hyphenator~createStorage} - */ - storage, - - /** - * @member {boolean} Hyphenator~enableReducedPatternSet - * @desc - * A variable to set if storing the used patterns is set - * @default false - * @access private - * @see {@link Hyphenator.config} - * @see {@link Hyphenator.getRedPatternSet} - */ - enableReducedPatternSet = false, - - /** - * @member {boolean} Hyphenator~enableRemoteLoading - * @desc - * A variable to set if pattern files should be loaded remotely or not - * @default true - * @access private - * @see {@link Hyphenator.config} - */ - enableRemoteLoading = true, - - /** - * @member {boolean} Hyphenator~displayToggleBox - * @desc - * A variable to set if the togglebox should be displayed or not - * @default false - * @access private - * @see {@link Hyphenator.config} - */ - displayToggleBox = false, - - /** - * @method Hyphenator~onError - * @desc - * A function that can be called upon an error. - * @see {@link Hyphenator.config} - * @access private - */ - onError = function (e) { - window.alert("Hyphenator.js says:\n\nAn Error occurred:\n" + e.message); - }, - - /** - * @method Hyphenator~onWarning - * @desc - * A function that can be called upon a warning. - * @see {@link Hyphenator.config} - * @access private - */ - onWarning = function (e) { - window.console.log(e.message); - }, - - /** - * @method Hyphenator~createElem - * @desc - * A function alias to document.createElementNS or document.createElement - * @access private - */ - createElem = function (tagname, context) { - context = context || contextWindow; - var el; - if (window.document.createElementNS) { - el = context.document.createElementNS('http://www.w3.org/1999/xhtml', tagname); - } else if (window.document.createElement) { - el = context.document.createElement(tagname); - } - return el; - }, - - /** - * @member {boolean} Hyphenator~css3 - * @desc - * A variable to set if css3 hyphenation should be used - * @default false - * @access private - * @see {@link Hyphenator.config} - */ - css3 = false, - - /** - * @typedef {Object} Hyphenator~css3_hsupport - * @property {boolean} support - if css3-hyphenation is supported - * @property {string} property - the css property name to access hyphen-settings (e.g. -webkit-hyphens) - * @property {Object.<string, boolean>} supportedBrowserLangs - an object caching tested languages - * @property {function} checkLangSupport - a method that checks if the browser supports a requested language - */ - - /** - * @member {Hyphenator~css3_h9n} Hyphenator~css3_h9n - * @desc - * A generated object containing information for CSS3-hyphenation support - * This is set by {@link Hyphenator~css3_gethsupport} - * @default undefined - * @access private - * @see {@link Hyphenator~css3_gethsupport} - * @example - * //Check if browser supports a language - * css3_h9n.checkLangSupport(&lt;lang&gt;) - */ - css3_h9n, - - /** - * @method Hyphenator~css3_gethsupport - * @desc - * This function sets {@link Hyphenator~css3_h9n} for the current UA - * @type function - * @access private - * @see Hyphenator~css3_h9n - */ - css3_gethsupport = function () { - var s, - createLangSupportChecker = function (prefix) { - var testStrings = [ - //latin: 0 - 'aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz', - //cyrillic: 1 - 'абвгдеёжзийклмнопрстуфхцчшщъыьэюя', - //arabic: 2 - 'أبتثجحخدذرزسشصضطظعغفقكلمنهوي', - //armenian: 3 - 'աբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆ', - //bengali: 4 - 'ঁংঃঅআইঈউঊঋঌএঐওঔকখগঘঙচছজঝঞটঠডঢণতথদধনপফবভমযরলশষসহ়ঽািীুূৃৄেৈোৌ্ৎৗড়ঢ়য়ৠৡৢৣ', - //devangari: 5 - 'ँंःअआइईउऊऋऌएऐओऔकखगघङचछजझञटठडढणतथदधनपफबभमयरलळवशषसहऽािीुूृॄेैोौ्॒॑ॠॡॢॣ', - //greek: 6 - 'αβγδεζηθικλμνξοπρσςτυφχψω', - //gujarati: 7 - 'બહઅઆઇઈઉઊઋૠએઐઓઔાિીુૂૃૄૢૣેૈોૌકખગઘઙચછજઝઞટઠડઢણતથદધનપફસભમયરલળવશષ', - //kannada: 8 - 'ಂಃಅಆಇಈಉಊಋಌಎಏಐಒಓಔಕಖಗಘಙಚಛಜಝಞಟಠಡಢಣತಥದಧನಪಫಬಭಮಯರಱಲಳವಶಷಸಹಽಾಿೀುೂೃೄೆೇೈೊೋೌ್ೕೖೞೠೡ', - //lao: 9 - 'ກຂຄງຈຊຍດຕຖທນບປຜຝພຟມຢຣລວສຫອຮະັາິີຶືຸູົຼເແໂໃໄ່້໊໋ໜໝ', - //malayalam: 10 - 'ംഃഅആഇഈഉഊഋഌഎഏഐഒഓഔകഖഗഘങചഛജഝഞടഠഡഢണതഥദധനപഫബഭമയരറലളഴവശഷസഹാിീുൂൃെേൈൊോൌ്ൗൠൡൺൻർൽൾൿ', - //oriya: 11 - 'ଁଂଃଅଆଇଈଉଊଋଌଏଐଓଔକଖଗଘଙଚଛଜଝଞଟଠଡଢଣତଥଦଧନପଫବଭମଯରଲଳଵଶଷସହାିୀୁୂୃେୈୋୌ୍ୗୠୡ', - //persian: 12 - 'أبتثجحخدذرزسشصضطظعغفقكلمنهوي', - //punjabi: 13 - 'ਁਂਃਅਆਇਈਉਊਏਐਓਔਕਖਗਘਙਚਛਜਝਞਟਠਡਢਣਤਥਦਧਨਪਫਬਭਮਯਰਲਲ਼ਵਸ਼ਸਹਾਿੀੁੂੇੈੋੌ੍ੰੱ', - //tamil: 14 - 'ஃஅஆஇஈஉஊஎஏஐஒஓஔகஙசஜஞடணதநனபமயரறலளழவஷஸஹாிீுூெேைொோௌ்ௗ', - //telugu: 15 - 'ఁంఃఅఆఇఈఉఊఋఌఎఏఐఒఓఔకఖగఘఙచఛజఝఞటఠడఢణతథదధనపఫబభమయరఱలళవశషసహాిీుూృౄెేైొోౌ్ౕౖౠౡ' - ], - f = function (lang) { - var shadow, - computedHeight, - bdy, - r = false; - - //check if lang has already been tested - if (this.supportedBrowserLangs.hasOwnProperty(lang)) { - r = this.supportedBrowserLangs[lang]; - } else if (supportedLangs.hasOwnProperty(lang)) { - //create and append shadow-test-element - bdy = window.document.getElementsByTagName('body')[0]; - shadow = createElem('div', window); - shadow.id = 'Hyphenator_LanguageChecker'; - shadow.style.width = '5em'; - shadow.style[prefix] = 'auto'; - shadow.style.hyphens = 'auto'; - shadow.style.fontSize = '12px'; - shadow.style.lineHeight = '12px'; - shadow.style.visibility = 'hidden'; - shadow.lang = lang; - shadow.style['-webkit-locale'] = "'" + lang + "'"; - shadow.innerHTML = testStrings[supportedLangs[lang].script]; - bdy.appendChild(shadow); - //measure its height - computedHeight = shadow.offsetHeight; - //remove shadow element - bdy.removeChild(shadow); - r = (computedHeight > 12) ? true : false; - this.supportedBrowserLangs[lang] = r; - } else { - r = false; - } - return r; - }; - return f; - }, - r = { - support: false, - supportedBrowserLangs: {}, - property: '', - checkLangSupport: {} - }; - - if (window.getComputedStyle) { - s = window.getComputedStyle(window.document.getElementsByTagName('body')[0], null); - } else { - //ancient Browsers don't support CSS3 anyway - css3_h9n = r; - return; - } - - if (s.hyphens !== undefined) { - r.support = true; - r.property = 'hyphens'; - r.checkLangSupport = createLangSupportChecker('hyphens'); - } else if (s['-webkit-hyphens'] !== undefined) { - r.support = true; - r.property = '-webkit-hyphens'; - r.checkLangSupport = createLangSupportChecker('-webkit-hyphens'); - } else if (s.MozHyphens !== undefined) { - r.support = true; - r.property = '-moz-hyphens'; - r.checkLangSupport = createLangSupportChecker('MozHyphens'); - } else if (s['-ms-hyphens'] !== undefined) { - r.support = true; - r.property = '-ms-hyphens'; - r.checkLangSupport = createLangSupportChecker('-ms-hyphens'); - } - css3_h9n = r; - }, - - /** - * @member {string} Hyphenator~hyphenateClass - * @desc - * A string containing the css-class-name for the hyphenate class - * @default 'hyphenate' - * @access private - * @example - * &lt;p class = "hyphenate"&gt;Text&lt;/p&gt; - * @see {@link Hyphenator.config} - */ - hyphenateClass = 'hyphenate', - - /** - * @member {string} Hyphenator~urlHyphenateClass - * @desc - * A string containing the css-class-name for the urlhyphenate class - * @default 'urlhyphenate' - * @access private - * @example - * &lt;p class = "urlhyphenate"&gt;Text&lt;/p&gt; - * @see {@link Hyphenator.config} - */ - urlHyphenateClass = 'urlhyphenate', - - /** - * @member {string} Hyphenator~classPrefix - * @desc - * A string containing a unique className prefix to be used - * whenever Hyphenator sets a CSS-class - * @access private - */ - classPrefix = 'Hyphenator' + Math.round(Math.random() * 1000), - - /** - * @member {string} Hyphenator~hideClass - * @desc - * The name of the class that hides elements - * @access private - */ - hideClass = classPrefix + 'hide', - - /** - * @member {RegExp} Hyphenator~hideClassRegExp - * @desc - * RegExp to remove hideClass from a list of classes - * @access private - */ - hideClassRegExp = new RegExp("\\s?\\b" + hideClass + "\\b", "g"), - - /** - * @member {string} Hyphenator~hideClass - * @desc - * The name of the class that unhides elements - * @access private - */ - unhideClass = classPrefix + 'unhide', - - /** - * @member {RegExp} Hyphenator~hideClassRegExp - * @desc - * RegExp to remove unhideClass from a list of classes - * @access private - */ - unhideClassRegExp = new RegExp("\\s?\\b" + unhideClass + "\\b", "g"), - - /** - * @member {string} Hyphenator~css3hyphenateClass - * @desc - * The name of the class that hyphenates elements with css3 - * @access private - */ - css3hyphenateClass = classPrefix + 'css3hyphenate', - - /** - * @member {CSSEdit} Hyphenator~css3hyphenateClass - * @desc - * The var where CSSEdit class is stored - * @access private - */ - css3hyphenateClassHandle, - - /** - * @member {string} Hyphenator~dontHyphenateClass - * @desc - * A string containing the css-class-name for elements that should not be hyphenated - * @default 'donthyphenate' - * @access private - * @example - * &lt;p class = "donthyphenate"&gt;Text&lt;/p&gt; - * @see {@link Hyphenator.config} - */ - dontHyphenateClass = 'donthyphenate', - - /** - * @member {number} Hyphenator~min - * @desc - * A number wich indicates the minimal length of words to hyphenate. - * @default 6 - * @access private - * @see {@link Hyphenator.config} - */ - min = 6, - - /** - * @member {number} Hyphenator~orphanControl - * @desc - * 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 - * @default 1 - * @access private - */ - orphanControl = 1, - - /** - * @member {boolean} Hyphenator~isBookmarklet - * @desc - * True if Hyphanetor runs as bookmarklet. - * @access private - */ - isBookmarklet = (function () { - var loc = null, - re = false, - scripts = contextWindow.document.getElementsByTagName('script'), - i = 0, - l = scripts.length; - while (!re && i < l) { - loc = scripts[i].getAttribute('src'); - if (!!loc && loc.indexOf('Hyphenator.js?bm=true') !== -1) { - re = true; - } - i += 1; - } - return re; - }()), - - /** - * @member {string|null} Hyphenator~mainLanguage - * @desc - * 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). - * @access private - * @see {@link Hyphenator~autoSetMainLanguage} - */ - mainLanguage = null, - - /** - * @member {string|null} Hyphenator~defaultLanguage - * @desc - * 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). - * @access private - * @see {@link Hyphenator.config} - * @see {@link Hyphenator~autoSetMainLanguage} - */ - defaultLanguage = '', - - /** - * @member {ElementCollection} Hyphenator~elements - * @desc - * A class representing all elements (of type Element) that have to be hyphenated. This var is filled by - * {@link Hyphenator~gatherDocumentInfos} - * @access private - */ - elements = (function () { - /** - * @constructor Hyphenator~elements~ElementCollection~Element - * @desc represents a DOM Element with additional information - * @access private - */ - var Element = function (element) { - /** - * @member {Object} Hyphenator~elements~ElementCollection~Element~element - * @desc A DOM Element - * @access protected - */ - this.element = element; - /** - * @member {boolean} Hyphenator~elements~ElementCollection~Element~hyphenated - * @desc Marks if the element has been hyphenated - * @access protected - */ - this.hyphenated = false; - /** - * @member {boolean} Hyphenator~elements~ElementCollection~Element~treated - * @desc Marks if information of the element has been collected but not hyphenated (e.g. dohyphenation is off) - * @access protected - */ - this.treated = false; - }, - /** - * @constructor Hyphenator~elements~ElementCollection - * @desc A collection of Elements to be hyphenated - * @access protected - */ - ElementCollection = function () { - /** - * @member {number} Hyphenator~elements~ElementCollection~count - * @desc The Number of collected Elements - * @access protected - */ - this.count = 0; - /** - * @member {number} Hyphenator~elements~ElementCollection~hyCount - * @desc The Number of hyphenated Elements - * @access protected - */ - this.hyCount = 0; - /** - * @member {Object.<string, Array.<Element>>} Hyphenator~elements~ElementCollection~list - * @desc The collection of elements, where the key is a language code and the value is an array of elements - * @access protected - */ - this.list = {}; - }; - /** - * @member {Object} Hyphenator~elements~ElementCollection.prototype - * @augments Hyphenator~elements~ElementCollection - * @access protected - */ - ElementCollection.prototype = { - /** - * @method Hyphenator~elements~ElementCollection.prototype~add - * @augments Hyphenator~elements~ElementCollection - * @access protected - * @desc adds a DOM element to the collection - * @param {Object} el - The DOM element - * @param {string} lang - The language of the element - */ - add: function (el, lang) { - var elo = new Element(el); - if (!this.list.hasOwnProperty(lang)) { - this.list[lang] = []; - } - this.list[lang].push(elo); - this.count += 1; - return elo; - }, - - /** - * @method Hyphenator~elements~ElementCollection.prototype~remove - * @augments Hyphenator~elements~ElementCollection - * @access protected - * @desc removes a DOM element from the collection - * @param {Object} el - The DOM element - */ - remove: function (el) { - var lang, i, e, l; - for (lang in this.list) { - if (this.list.hasOwnProperty(lang)) { - for (i = 0; i < this.list[lang].length; i += 1) { - if (this.list[lang][i].element === el) { - e = i; - l = lang; - break; - } - } - } - } - this.list[l].splice(e, 1); - this.count -= 1; - this.hyCount -= 1; - }, - /** - * @callback Hyphenator~elements~ElementCollection.prototype~each~callback fn - The callback that is executed for each element - * @param {string} [k] The key (i.e. language) of the collection - * @param {Hyphenator~elements~ElementCollection~Element} element - */ - - /** - * @method Hyphenator~elements~ElementCollection.prototype~each - * @augments Hyphenator~elements~ElementCollection - * @access protected - * @desc takes each element of the collection as an argument of fn - * @param {Hyphenator~elements~ElementCollection.prototype~each~callback} fn - A function that takes an element as an argument - */ - each: function (fn) { - var k; - for (k in this.list) { - if (this.list.hasOwnProperty(k)) { - if (fn.length === 2) { - fn(k, this.list[k]); - } else { - fn(this.list[k]); - } - } - } - } - }; - return new ElementCollection(); - }()), - - - /** - * @member {Object.<sting, string>} Hyphenator~exceptions - * @desc - * 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. - * Exceptions can also be set by the user. - * @see {@link Hyphenator~prepareLanguagesObj} - * @access private - */ - exceptions = {}, - - /** - * @member {Object.<string, boolean>} Hyphenator~docLanguages - * @desc - * An object holding all languages used in the document. This is filled by - * {@link Hyphenator~gatherDocumentInfos} - * @access private - */ - docLanguages = {}, - - /** - * @member {string} Hyphenator~url - * @desc - * A string containing a insane RegularExpression to match URL's - * @access 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 - - /** - * @member {string} Hyphenator~mail - * @desc - * A string containing a RegularExpression to match mail-adresses - * @access private - */ - mail = '[\\w-\\.]+@[\\w\\.]+', - - /** - * @member {RegExp} Hyphenator~urlRE - * @desc - * A RegularExpressions-Object for url- and mail adress matching - * @access private - */ - urlOrMailRE = new RegExp('(' + url + ')|(' + mail + ')', 'i'), - - /** - * @member {string} Hyphenator~zeroWidthSpace - * @desc - * 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 - * @access private - */ - zeroWidthSpace = (function () { - var zws, ua = window.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; - }()), - - /** - * @method Hyphenator~onBeforeWordHyphenation - * @desc - * This method is called just before a word is hyphenated. - * It is called with two parameters: the word and its language. - * The method must return a string (aka the word). - * @see {@link Hyphenator.config} - * @access private - * @param {string} word - * @param {string} lang - * @return {string} The word that goes into hyphenation - */ - onBeforeWordHyphenation = function (word) { - return word; - }, - - /** - * @method Hyphenator~onAfterWordHyphenation - * @desc - * This method is called for each word after it is hyphenated. - * Takes the word as a first parameter and its language as a second parameter. - * Returns a string that will replace the word that has been hyphenated. - * @see {@link Hyphenator.config} - * @access private - * @param {string} word - * @param {string} lang - * @return {string} The word that goes into hyphenation - */ - onAfterWordHyphenation = function (word) { - return word; - }, - - /** - * @method Hyphenator~onHyphenationDone - * @desc - * A method to be called, when the last element has been hyphenated. - * If there are frames the method is called for each frame. - * Therefore the location.href of the contextWindow calling this method is given as a parameter - * @see {@link Hyphenator.config} - * @param {string} context - * @access private - */ - onHyphenationDone = function (context) { - return context; - }, - - /** - * @name Hyphenator~selectorFunction - * @desc - * A function set by the user that has to return a HTMLNodeList or array of Elements to be hyphenated. - * By default this is set to false so we can check if a selectorFunction is set… - * @see {@link Hyphenator.config} - * @see {@link Hyphenator~mySelectorFunction} - * @default false - * @type {function|boolean} - * @access private - */ - selectorFunction = false, - - /** - * @method Hyphenator~mySelectorFunction - * @desc - * A function that returns a HTMLNodeList or array of Elements to be hyphenated. - * By default it uses the classname ('hyphenate') to select the elements. - * @access private - */ - mySelectorFunction = function (hyphenateClass) { - var tmp, el = [], i, l; - if (window.document.getElementsByClassName) { - el = contextWindow.document.getElementsByClassName(hyphenateClass); - } else if (window.document.querySelectorAll) { - el = contextWindow.document.querySelectorAll('.' + hyphenateClass); - } else { - tmp = contextWindow.document.getElementsByTagName('*'); - l = tmp.length; - for (i = 0; i < l; i += 1) { - if (tmp[i].className.indexOf(hyphenateClass) !== -1 && tmp[i].className.indexOf(dontHyphenateClass) === -1) { - el.push(tmp[i]); - } - } - } - return el; - }, - - /** - * @method Hyphenator~selectElements - * @desc - * A function that uses either selectorFunction set by the user - * or the default mySelectorFunction. - * @access private - */ - selectElements = function () { - var elems; - if (selectorFunction) { - elems = selectorFunction(); - } else { - elems = mySelectorFunction(hyphenateClass); - } - return elems; - }, - - /** - * @member {string} Hyphenator~intermediateState - * @desc - * The visibility of elements while they are hyphenated: - * 'visible': unhyphenated text is visible and then redrawn when hyphenated. - * 'hidden': unhyphenated text is made invisible as soon as possible and made visible after hyphenation. - * @default 'hidden' - * @see {@link Hyphenator.config} - * @access private - */ - intermediateState = 'hidden', - - /** - * @member {string} Hyphenator~unhide - * @desc - * How hidden elements unhide: either simultaneous (default: 'wait') or progressively. - * 'wait' makes Hyphenator.js to wait until all elements are hyphenated (one redraw) - * With 'progressive' Hyphenator.js unhides elements as soon as they are hyphenated. - * @see {@link Hyphenator.config} - * @access private - */ - unhide = 'wait', - - /** - * @member {Array.<Hyphenator~CSSEdit>} Hyphenator~CSSEditors - * @desc A container array that holds CSSEdit classes - * For each window object one CSSEdit class is inserted - * @access private - */ - CSSEditors = [], - - /** - * @constructor Hyphenator~CSSEdit - * @desc - * This class handles access and editing of StyleSheets. - * Thanks to this styles (e.g. hiding and unhiding elements upon hyphenation) - * can be changed in one place instead for each element. - * @access private - */ - CSSEdit = function (w) { - w = w || window; - var doc = w.document, - /** - * @member {Object} Hyphenator~CSSEdit~sheet - * @desc - * A StyleSheet, where Hyphenator can write to. - * If no StyleSheet can be found, lets create one. - * @access private - */ - sheet = (function () { - var i, - l = doc.styleSheets.length, - s, - element, - r = false; - for (i = 0; i < l; i += 1) { - s = doc.styleSheets[i]; - try { - if (!!s.cssRules) { - r = s; - break; - } - } catch (ignore) {} - } - r = false; - if (r === false) { - element = doc.createElement('style'); - element.type = 'text/css'; - doc.getElementsByTagName('head')[0].appendChild(element); - r = doc.styleSheets[doc.styleSheets.length - 1]; - } - return r; - }()), - - /** - * @typedef {Object} Hyphenator~CSSEdit~changes - * @property {Object} sheet - The StyleSheet where the change was made - * @property {number} index - The index of the changed rule - */ - - /** - * @member {Array.<changes>} Hyphenator~CSSEdit~changes - * @desc - * Sets a CSS rule for a specified selector - * @access private - */ - changes = [], - - /** - * @typedef Hyphenator~CSSEdit~rule - * @property {number} index - The index of the rule - * @property {Object} rule - The style rule - */ - /** - * @method Hyphenator~CSSEdit~findRule - * @desc - * Searches the StyleSheets for a given selector and returns an object containing the rule. - * If nothing can be found, false is returned. - * @param {string} sel - * @return {Hyphenator~CSSEdit~rule|false} - * @access private - */ - findRule = function (sel) { - var s, rule, sheets = w.document.styleSheets, rules, i, j, r = false; - for (i = 0; i < sheets.length; i += 1) { - s = sheets[i]; - try { //FF has issues here with external CSS (s.o.p) - if (!!s.cssRules) { - rules = s.cssRules; - } else if (!!s.rules) { - // IE < 9 - rules = s.rules; - } - } catch (ignore) {} - if (!!rules && !!rules.length) { - for (j = 0; j < rules.length; j += 1) { - rule = rules[j]; - if (rule.selectorText === sel) { - r = { - index: j, - rule: rule - }; - } - } - } - } - return r; - }, - /** - * @method Hyphenator~CSSEdit~addRule - * @desc - * Adds a rule to the {@link Hyphenator~CSSEdit~sheet} - * @param {string} sel - The selector to be added - * @param {string} rulesStr - The rules for the specified selector - * @return {number} index of the new rule - * @access private - */ - addRule = function (sel, rulesStr) { - var i, r; - if (!!sheet.insertRule) { - if (!!sheet.cssRules) { - i = sheet.cssRules.length; - } else { - i = 0; - } - r = sheet.insertRule(sel + '{' + rulesStr + '}', i); - } else if (!!sheet.addRule) { - // IE < 9 - if (!!sheet.rules) { - i = sheet.rules.length; - } else { - i = 0; - } - sheet.addRule(sel, rulesStr, i); - r = i; - } - return r; - }, - /** - * @method Hyphenator~CSSEdit~removeRule - * @desc - * Removes a rule with the specified index from the specified sheet - * @param {Object} sheet - The style sheet - * @param {number} index - the index of the rule - * @access private - */ - removeRule = function (sheet, index) { - if (sheet.deleteRule) { - sheet.deleteRule(index); - } else { - // IE < 9 - sheet.removeRule(index); - } - }; - - return { - /** - * @method Hyphenator~CSSEdit.setRule - * @desc - * Sets a CSS rule for a specified selector - * @access public - * @param {string} sel - Selector - * @param {string} rulesString - CSS-Rules - */ - setRule: function (sel, rulesString) { - var i, existingRule, cssText; - existingRule = findRule(sel); - if (!!existingRule) { - if (!!existingRule.rule.cssText) { - cssText = existingRule.rule.cssText; - } else { - // IE < 9 - cssText = existingRule.rule.style.cssText.toLowerCase(); - } - if (cssText === '.' + hyphenateClass + ' { visibility: hidden; }') { - //browsers w/o IE < 9 and no additional style defs: - //add to [changes] for later removal - changes.push({sheet: existingRule.rule.parentStyleSheet, index: existingRule.index}); - } else if (cssText.indexOf('visibility: hidden') !== -1) { - // IE < 9 or additional style defs: - // add new rule - i = addRule(sel, rulesString); - //add to [changes] for later removal - changes.push({sheet: sheet, index: i}); - // clear existing def - existingRule.rule.style.visibility = ''; - } else { - i = addRule(sel, rulesString); - changes.push({sheet: sheet, index: i}); - } - } else { - i = addRule(sel, rulesString); - changes.push({sheet: sheet, index: i}); - } - }, - /** - * @method Hyphenator~CSSEdit.clearChanges - * @desc - * Removes all changes Hyphenator has made from the StyleSheets - * @access public - */ - clearChanges: function () { - var change = changes.pop(); - while (!!change) { - removeRule(change.sheet, change.index); - change = changes.pop(); - } - } - }; - }, - - /** - * @member {string} Hyphenator~hyphen - * @desc - * A string containing the character for in-word-hyphenation - * @default the soft hyphen - * @access private - * @see {@link Hyphenator.config} - */ - hyphen = String.fromCharCode(173), - - /** - * @member {string} Hyphenator~urlhyphen - * @desc - * A string containing the character for url/mail-hyphenation - * @default the zero width space - * @access private - * @see {@link Hyphenator.config} - * @see {@link Hyphenator~zeroWidthSpace} - */ - urlhyphen = zeroWidthSpace, - - /** - * @method Hyphenator~hyphenateURL - * @desc - * Puts {@link Hyphenator~urlhyphen} (default: zero width space) after each no-alphanumeric char that my be in a URL. - * @param {string} url to hyphenate - * @returns string the hyphenated URL - * @access public - */ - hyphenateURL = function (url) { - var tmp = url.replace(/([:\/\.\?#&\-_,;!@]+)/gi, '$&' + urlhyphen), - parts = tmp.split(urlhyphen), - i; - for (i = 0; i < parts.length; i += 1) { - if (parts[i].length > (2 * min)) { - parts[i] = parts[i].replace(/(\w{3})(\w)/gi, "$1" + urlhyphen + "$2"); - } - } - if (parts[parts.length - 1] === "") { - parts.pop(); - } - return parts.join(urlhyphen); - }, - - /** - * @member {boolean} Hyphenator~safeCopy - * @desc - * Defines wether work-around for copy issues is active or not - * @default true - * @access private - * @see {@link Hyphenator.config} - * @see {@link Hyphenator~registerOnCopy} - */ - safeCopy = true, - - /** - * @member {Object} Hyphenator~hyphRunFor - * @desc - * stores location.href for documents where run() has been executed - * to warn when Hyphenator.run() executed multiple times - * @access private - * @see {@link Hyphenator~runWhenLoaded} - */ - hyphRunFor = {}, - - /** - * @method Hyphenator~runWhenLoaded - * @desc - * A crossbrowser solution for the DOMContentLoaded-Event based on - * <a href = "http://jquery.com/">jQuery</a> - * I added some functionality: e.g. support for frames and iframes… - * @param {Object} w the window-object - * @param {function()} f the function to call when the document is ready - * @access private - */ - runWhenLoaded = function (w, f) { - var toplevel, - add = window.document.addEventListener ? 'addEventListener' : 'attachEvent', - rem = window.document.addEventListener ? 'removeEventListener' : 'detachEvent', - pre = window.document.addEventListener ? '' : 'on', - - init = function (context) { - if (hyphRunFor[context.location.href]) { - onWarning(new Error("Warning: multiple execution of Hyphenator.run() – This may slow down the script!")); - } - contextWindow = context || window; - f(); - hyphRunFor[contextWindow.location.href] = true; - }, - - doScrollCheck = function () { - try { - // If IE is used, use the trick by Diego Perini - // http://javascript.nwbox.com/IEContentLoaded/ - w.document.documentElement.doScroll("left"); - } catch (error) { - window.setTimeout(doScrollCheck, 1); - return; - } - //maybe modern IE fired DOMContentLoaded - if (!hyphRunFor[w.location.href]) { - documentLoaded = true; - init(w); - } - }, - - doOnEvent = function (e) { - var i, fl, haveAccess; - if (!!e && e.type === 'readystatechange' && w.document.readyState !== 'interactive' && w.document.readyState !== 'complete') { - return; - } - - //DOM is ready/interactive, but frames may not be loaded yet! - //cleanup events - w.document[rem](pre + 'DOMContentLoaded', doOnEvent, false); - w.document[rem](pre + 'readystatechange', doOnEvent, false); - - //check frames - fl = w.frames.length; - if (fl === 0 || !doFrames) { - //there are no frames! - //cleanup events - w[rem](pre + 'load', doOnEvent, false); - documentLoaded = true; - init(w); - } else if (doFrames && fl > 0) { - //we have frames, so wait for onload and then initiate runWhenLoaded recursevly for each frame: - if (!!e && e.type === 'load') { - //cleanup events - w[rem](pre + 'load', doOnEvent, false); - for (i = 0; i < fl; i += 1) { - haveAccess = undefined; - //try catch isn't enough for webkit - try { - //opera throws only on document.toString-access - haveAccess = window.frames[i].document.toString(); - } catch (err) { - haveAccess = undefined; - } - if (!!haveAccess) { - runWhenLoaded(w.frames[i], f); - } - } - init(w); - } - } - }; - if (documentLoaded || w.document.readyState === 'complete') { - //Hyphenator has run already (documentLoaded is true) or - //it has been loaded after onLoad - documentLoaded = true; - doOnEvent({type: 'load'}); - } else { - //register events - w.document[add](pre + 'DOMContentLoaded', doOnEvent, false); - w.document[add](pre + 'readystatechange', doOnEvent, false); - w[add](pre + 'load', doOnEvent, false); - toplevel = false; - try { - toplevel = !window.frameElement; - } catch (ignore) {} - if (toplevel && w.document.documentElement.doScroll) { - doScrollCheck(); //calls init() - } - } - }, - - /** - * @method Hyphenator~getLang - * @desc - * 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. - * @return {string} The language of the element - * @access private - */ - getLang = function (el, fallback) { - try { - return !!el.getAttribute('lang') ? el.getAttribute('lang').toLowerCase() : - !!el.getAttribute('xml:lang') ? el.getAttribute('xml:lang').toLowerCase() : - el.tagName.toLowerCase() !== 'html' ? getLang(el.parentNode, fallback) : - fallback ? mainLanguage : - null; - } catch (ignore) {} - }, - - /** - * @method Hyphenator~autoSetMainLanguage - * @desc - * Retrieves the language of the document from the DOM and sets the lang attribute of the html-tag. - * The function looks in the following places: - * <ul> - * <li>lang-attribute in the html-tag</li> - * <li>&lt;meta http-equiv = "content-language" content = "xy" /&gt;</li> - * <li>&lt;meta name = "DC.Language" content = "xy" /&gt;</li> - * <li>&lt;meta name = "language" content = "xy" /&gt;</li> - * </li> - * If nothing can be found a prompt using {@link Hyphenator~languageHint} and a prompt-string is displayed. - * If the retrieved language is in the object {@link Hyphenator~supportedLangs} it is copied to {@link Hyphenator~mainLanguage} - * @access private - */ - autoSetMainLanguage = function (w) { - w = w || contextWindow; - var el = w.document.getElementsByTagName('html')[0], - m = w.document.getElementsByTagName('meta'), - i, - getLangFromUser = function () { - var ml, - text = '', - dH = 300, - dW = 450, - dX = Math.floor((w.outerWidth - dW) / 2) + window.screenX, - dY = Math.floor((w.outerHeight - dH) / 2) + window.screenY, - ul = '', - languageHint; - if (!!window.showModalDialog && (w.location.href.indexOf(basePath) !== -1)) { - ml = window.showModalDialog(basePath + 'modalLangDialog.html', supportedLangs, "dialogWidth: " + dW + "px; dialogHeight: " + dH + "px; dialogtop: " + dY + "; dialogleft: " + dX + "; center: on; resizable: off; scroll: off;"); - } else { - languageHint = (function () { - var k, r = ''; - for (k in supportedLangs) { - if (supportedLangs.hasOwnProperty(k)) { - r += k + ', '; - } - } - r = r.substring(0, r.length - 2); - return r; - }()); - ul = window.navigator.language || window.navigator.userLanguage; - ul = ul.substring(0, 2); - if (!!supportedLangs[ul] && supportedLangs[ul].prompt !== '') { - text = supportedLangs[ul].prompt; - } else { - text = supportedLangs.en.prompt; - } - text += ' (ISO 639-1)\n\n' + languageHint; - ml = window.prompt(window.unescape(text), ul).toLowerCase(); - } - return ml; - }; - mainLanguage = getLang(el, false); - if (!mainLanguage) { - for (i = 0; i < m.length; i += 1) { - //<meta http-equiv = "content-language" content="xy"> - if (!!m[i].getAttribute('http-equiv') && (m[i].getAttribute('http-equiv').toLowerCase() === 'content-language')) { - mainLanguage = m[i].getAttribute('content').toLowerCase(); - } - //<meta name = "DC.Language" content="xy"> - if (!!m[i].getAttribute('name') && (m[i].getAttribute('name').toLowerCase() === 'dc.language')) { - mainLanguage = m[i].getAttribute('content').toLowerCase(); - } - //<meta name = "language" content = "xy"> - 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.frameElement)) { - autoSetMainLanguage(window.parent); - } - //fallback to defaultLang if set - if (!mainLanguage && defaultLanguage !== '') { - mainLanguage = defaultLanguage; - } - //ask user for lang - if (!mainLanguage) { - mainLanguage = getLangFromUser(); - } - el.lang = mainLanguage; - }, - - /** - * @method Hyphenator~gatherDocumentInfos - * @desc - * This method runs through the DOM and executes the process()-function on: - * - every node returned by the {@link Hyphenator~selectorFunction}. - * @access private - */ - gatherDocumentInfos = function () { - var elToProcess, urlhyphenEls, tmp, i = 0, - /** - * @method Hyphenator~gatherDocumentInfos - * @desc - * This method 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 - * @param {Object} el a DOM element - * @param {string} plang the language of the parent element - * @param {boolean} isChild true, if the parent of el has been processed - */ - process = function (el, pLang, isChild) { - isChild = isChild || false; - var n, j = 0, hyphenate = true, eLang, - useCSS3 = function () { - css3hyphenateClassHandle = new CSSEdit(contextWindow); - css3hyphenateClassHandle.setRule('.' + css3hyphenateClass, css3_h9n.property + ': auto;'); - css3hyphenateClassHandle.setRule('.' + dontHyphenateClass, css3_h9n.property + ': manual;'); - if ((eLang !== pLang) && css3_h9n.property.indexOf('webkit') !== -1) { - css3hyphenateClassHandle.setRule('.' + css3hyphenateClass, '-webkit-locale : ' + eLang + ';'); - } - el.className = el.className + ' ' + css3hyphenateClass; - }, - useHyphenator = function () { - //quick fix for test111.html - //better: weight elements - if (isBookmarklet && eLang !== mainLanguage) { - return; - } - if (supportedLangs.hasOwnProperty(eLang)) { - docLanguages[eLang] = true; - } else { - if (supportedLangs.hasOwnProperty(eLang.split('-')[0])) { //try subtag - eLang = eLang.split('-')[0]; - docLanguages[eLang] = true; - } else if (!isBookmarklet) { - hyphenate = false; - onError(new Error('Language "' + eLang + '" is not yet supported.')); - } - } - if (hyphenate) { - if (intermediateState === 'hidden') { - el.className = el.className + ' ' + hideClass; - } - elements.add(el, eLang); - } - }; - - if (el.lang && typeof (el.lang) === 'string') { - eLang = el.lang.toLowerCase(); //copy attribute-lang to internal eLang - } else if (!!pLang && pLang !== '') { - eLang = pLang.toLowerCase(); - } else { - eLang = getLang(el, true); - } - - if (!isChild) { - if (css3 && css3_h9n.support && !!css3_h9n.checkLangSupport(eLang)) { - useCSS3(); - } else { - useHyphenator(); - } - } else { - if (eLang !== pLang) { - if (css3 && css3_h9n.support && !!css3_h9n.checkLangSupport(eLang)) { - useCSS3(); - } else { - useHyphenator(); - } - } else { - if (!css3 || !css3_h9n.support || !css3_h9n.checkLangSupport(eLang)) { - useHyphenator(); - } // else do nothing - } - } - n = el.childNodes[j]; - while (!!n) { - if (n.nodeType === 1 && !dontHyphenate[n.nodeName.toLowerCase()] && - n.className.indexOf(dontHyphenateClass) === -1 && - n.className.indexOf(urlHyphenateClass) === -1 && !elToProcess[n]) { - process(n, eLang, true); - } - j += 1; - n = el.childNodes[j]; - } - }, - processUrlStyled = function (el) { - var n, j = 0; - - n = el.childNodes[j]; - while (!!n) { - if (n.nodeType === 1 && !dontHyphenate[n.nodeName.toLowerCase()] && - n.className.indexOf(dontHyphenateClass) === -1 && - n.className.indexOf(hyphenateClass) === -1 && !urlhyphenEls[n]) { - processUrlStyled(n); - } else if (n.nodeType === 3) { - n.data = hyphenateURL(n.data); - } - j += 1; - n = el.childNodes[j]; - } - }; - - if (css3) { - css3_gethsupport(); - } - if (isBookmarklet) { - elToProcess = contextWindow.document.getElementsByTagName('body')[0]; - process(elToProcess, mainLanguage, false); - } else { - if (!css3 && intermediateState === 'hidden') { - CSSEditors.push(new CSSEdit(contextWindow)); - CSSEditors[CSSEditors.length - 1].setRule('.' + hyphenateClass, 'visibility: hidden;'); - CSSEditors[CSSEditors.length - 1].setRule('.' + hideClass, 'visibility: hidden;'); - CSSEditors[CSSEditors.length - 1].setRule('.' + unhideClass, 'visibility: visible;'); - } - elToProcess = selectElements(); - tmp = elToProcess[i]; - while (!!tmp) { - process(tmp, '', false); - i += 1; - tmp = elToProcess[i]; - } - - urlhyphenEls = mySelectorFunction(urlHyphenateClass); - i = 0; - tmp = urlhyphenEls[i]; - while (!!tmp) { - processUrlStyled(tmp); - i += 1; - tmp = urlhyphenEls[i]; - } - } - if (elements.count === 0) { - //nothing to hyphenate or all hyphenated by css3 - for (i = 0; i < CSSEditors.length; i += 1) { - CSSEditors[i].clearChanges(); - } - onHyphenationDone(contextWindow.location.href); - } - }, - - /** - * @method Hyphenator~convertPatterns - * @desc - * converts patterns of the given language to a trie - * @access private - * @param {Object} language object whose patterns shall be converted - */ - convertPatterns = function (lo) { - var size, - tree = {}, - convert = function (psize, patterns) { - var i = 0, - t = tree, - cc = 0, - points = [], - ppos = 0, - lastwasp = false, - len = 0; - while (i < patterns.length) { - if (len < psize) { - cc = patterns.charCodeAt(i); - if (cc >= 49 && cc <= 57) { - //this is a hpoint (1-9) - points[ppos] = cc - 48; - ppos += 1; - lastwasp = true; - } else { - //this is a alphabetic char --> extend the tree? - if (!t[cc]) { - t[cc] = {}; - } - t = t[cc]; //go to subtree - if (!lastwasp) { - points[ppos] = 0; - ppos += 1; - } - lastwasp = false; - } - len += 1; - i += 1; - } - - if (len === psize) { - //add last point (0) - if (!lastwasp) { - points[ppos] = 0; - } - //write points - t.tpoints = points; - //reset - t = tree; - points = []; - ppos = 0; - lastwasp = false; - len = 0; - } - } - }; - for (size in lo.patterns) { - if (lo.patterns.hasOwnProperty(size)) { - convert(parseInt(size, 10), lo.patterns[size]); - } - } - lo.patterns = tree; - }, - - /** - * @method Hyphenator~recreatePattern - * @desc - * Recreates the pattern for the reducedPatternSet - * @param {string} pattern The pattern (chars) - * @param {string} nodePoints The nodePoints (integers) - * @access private - * @return {string} The pattern (chars and numbers) - */ - recreatePattern = function (pattern, nodePoints) { - var r = [], c = pattern.split(''), i; - for (i = 0; i < nodePoints.length; i += 1) { - if (nodePoints[i] !== 0) { - r.push(nodePoints[i]); - } - if (c[i]) { - r.push(c[i]); - } - } - return r.join(''); - }, - - /** - * @method Hyphenator~convertExceptionsToObject - * @desc - * Converts a list of comma seprated exceptions to an object: - * 'Fortran,Hy-phen-a-tion' -> {'Fortran':'Fortran','Hyphenation':'Hy-phen-a-tion'} - * @access private - * @param {string} exc a comma separated string of exceptions (without spaces) - * @return {Object.<string, string>} - */ - convertExceptionsToObject = function (exc) { - var w = exc.split(', '), - r = {}, - i, - l, - key; - for (i = 0, l = w.length; i < l; i += 1) { - key = w[i].replace(/-/g, ''); - if (!r.hasOwnProperty(key)) { - r[key] = w[i]; - } - } - return r; - }, - - /** - * @method Hyphenator~loadPatterns - * @desc - * Checks if the requested file is available in the network. - * 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~supportedLangs}-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 Bookmarklet impossible. - * @param {string} lang The language to load the patterns for - * @access private - * @see {@link Hyphenator~basePath} - */ - loadPatterns = function (lang) { - var location, xhr, head, script; - if (supportedLangs.hasOwnProperty(lang) && !Hyphenator.languages[lang]) { - location = basePath + 'patterns/' + supportedLangs[lang].file; - } else { - return; - } - if (isLocal && !isBookmarklet) { - //check if 'location' is available: - xhr = null; - try { - // Mozilla, Opera, Safari and Internet Explorer (ab v7) - xhr = new window.XMLHttpRequest(); - } catch (e) { - try { - //IE>=6 - xhr = new window.ActiveXObject("Microsoft.XMLHTTP"); - } catch (e2) { - try { - //IE>=5 - xhr = new window.ActiveXObject("Msxml2.XMLHTTP"); - } catch (e3) { - xhr = null; - } - } - } - - if (xhr) { - xhr.open('HEAD', location, true); - xhr.setRequestHeader('Cache-Control', 'no-cache'); - xhr.onreadystatechange = function () { - if (xhr.readyState === 4) { - if (xhr.status === 404) { - onError(new Error('Could not load\n' + location)); - delete docLanguages[lang]; - return; - } - } - }; - xhr.send(null); - } - } - if (createElem) { - head = window.document.getElementsByTagName('head').item(0); - script = createElem('script', window); - script.src = location; - script.type = 'text/javascript'; - script.charset = 'utf8'; - head.appendChild(script); - } - }, - - /** - * @method Hyphenator~prepareLanguagesObj - * @desc - * Adds some feature to the language object: - * - cache - * - exceptions - * Converts the patterns to a trie using {@link Hyphenator~convertPatterns} - * If storage is active the object is stored there. - * @access private - * @param {string} lang The language of the language object - */ - 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(lo); - wrd = '[\\w' + lo.specialChars + '@' + String.fromCharCode(173) + String.fromCharCode(8204) + '-]{' + min + ',}'; - lo.genRegExp = new RegExp('(' + url + ')|(' + mail + ')|(' + wrd + ')', 'gi'); - lo.prepared = true; - } - if (!!storage) { - storage.setItem(lang, window.JSON.stringify(lo)); - } - - }, - - /**** - * @method Hyphenator~prepare - * @desc - * 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 patternfile is loaded the patterns are - * converted to their object style and the lang-object extended. - * Finally the callback is called. - * @access private - */ - prepare = function (callback) { - var lang, interval, tmp1, tmp2, - languagesLoaded = function () { - var finishedLoading = true, l; - for (l in docLanguages) { - if (docLanguages.hasOwnProperty(l)) { - finishedLoading = false; - if (!!Hyphenator.languages[l]) { - delete docLanguages[l]; - //do conversion while other patterns are loading: - prepareLanguagesObj(l); - callback(l); - } - } - } - return finishedLoading; - }; - - if (!enableRemoteLoading) { - for (lang in Hyphenator.languages) { - if (Hyphenator.languages.hasOwnProperty(lang)) { - prepareLanguagesObj(lang); - } - } - callback('*'); - return; - } - // get all languages that are used and preload the patterns - for (lang in docLanguages) { - if (docLanguages.hasOwnProperty(lang)) { - if (!!storage && storage.test(lang)) { - Hyphenator.languages[lang] = window.JSON.parse(storage.getItem(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) + String.fromCharCode(8204) + '-]{' + min + ',}'; - Hyphenator.languages[lang].genRegExp = new RegExp('(' + url + ')|(' + mail + ')|(' + tmp1 + ')', 'gi'); - - delete docLanguages[lang]; - callback(lang); - } else { - loadPatterns(lang); - } - } - } - // else async wait until patterns are loaded, then hyphenate - if (!languagesLoaded()) { - interval = window.setInterval(function () { - var loadingDone = languagesLoaded(); - if (loadingDone) { - window.clearInterval(interval); - } - }, 100); - } - }, - - /** - * @method Hyphenator~toggleBox - * @desc - * Creates the toggleBox: a small button to turn off/on hyphenation on a page. - * @see {@link Hyphenator.config} - * @access private - */ - toggleBox = function () { - var bdy, myTextNode, - text = (Hyphenator.doHyphenation ? 'Hy-phen-a-tion' : 'Hyphenation'), - myBox = contextWindow.document.getElementById('HyphenatorToggleBox'); - if (!!myBox) { - myBox.firstChild.data = text; - } else { - bdy = contextWindow.document.getElementsByTagName('body')[0]; - myBox = createElem('div', contextWindow); - myBox.setAttribute('id', 'HyphenatorToggleBox'); - myBox.setAttribute('class', dontHyphenateClass); - myTextNode = contextWindow.document.createTextNode(text); - myBox.appendChild(myTextNode); - 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'; - myBox.style.borderBottomLeftRadius = '4px'; - bdy.appendChild(myBox); - } - }, - - - /** - * @method Hyphenator~hyphenateWord - * @desc - * 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 '-' hyphenate the parts. - * The hyphenated word is returned and (if acivated) cached. - * Both special Events onBeforeWordHyphenation and onAfterWordHyphenation are called for the word. - * @param {Object} lo A language object (containing the patterns) - * @param {string} lang The language of the word - * @param {string} word The word - * @returns string The hyphenated word - * @access public - */ - hyphenateWord = function (lo, lang, word) { - var parts, - i, - pattern, - ww, - wwlen, - wwhp = [], - pstart, - plen, - trie = lo.patterns, - node, - nodePoints, - hp, - wordLength = word.length, - hw = '', - doCharSubst = function (w) { - var subst, r; - for (subst in lo.charSubstitution) { - if (lo.charSubstitution.hasOwnProperty(subst)) { - r = w.replace(new RegExp(subst, 'g'), lo.charSubstitution[subst]); - } - } - return r; - }; - word = onBeforeWordHyphenation(word, lang); - if (word === '') { - hw = ''; - } else if (enableCache && lo.cache.hasOwnProperty(word)) { //the word is in the cache - hw = lo.cache[word]; - } else if (word.indexOf(hyphen) !== -1) { - //word already contains shy; -> leave at it is! - hw = word; - } else if (lo.exceptions.hasOwnProperty(word)) { //the word is in the exceptions list - hw = lo.exceptions[word].replace(/-/g, hyphen); - } else if (word.indexOf('-') !== -1) { - //word contains '-' -> hyphenate the parts separated with '-' - parts = word.split('-'); - for (i = 0; i < parts.length; i += 1) { - parts[i] = hyphenateWord(lo, lang, parts[i]); - } - hw = parts.join('-'); - } else { - ww = word.toLowerCase(); - - if (!!lo.charSubstitution) { - ww = doCharSubst(ww); - } - if (word.indexOf("'") !== -1) { - ww = ww.replace("'", "’"); //replace APOSTROPHE with RIGHT SINGLE QUOTATION MARK (since the latter is used in the patterns) - } - ww = '_' + ww + '_'; - wwlen = ww.length; - for (hp = 0; hp < wwlen + 1; hp += 1) { - wwhp[hp] = 0; - } - for (pstart = 0; pstart < wwlen; pstart += 1) { - node = trie; - pattern = ''; - for (plen = pstart; plen < wwlen; plen += 1) { - node = node[ww.charCodeAt(plen)]; //go sub trie - if (node) { - if (enableReducedPatternSet) { - pattern += ww.charAt(plen); - } - nodePoints = node.tpoints; - if (nodePoints) { - if (enableReducedPatternSet) { - if (!lo.redPatSet) { - lo.redPatSet = {}; - } - lo.redPatSet[pattern] = recreatePattern(pattern, nodePoints); - } - for (hp = 0; hp < nodePoints.length; hp += 1) { - wwhp[pstart + hp] = Math.max(wwhp[pstart + hp], nodePoints[hp]); - } - } - } else { - break; - } - } - } - //return wwhp - for (hp = 0; hp < wordLength; hp += 1) { - if (hp >= lo.leftmin && hp <= (wordLength - lo.rightmin) && (wwhp[hp + 1] % 2) !== 0) { - hw += hyphen + word.charAt(hp); - } else { - hw += word.charAt(hp); - } - } - } - hw = onAfterWordHyphenation(hw, lang); - if (enableCache) { //put the word in the cache - lo.cache[word] = hw; - } - return hw; - }, - - /** - * @method Hyphenator~removeHyphenationFromElement - * @desc - * 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. - * @access public - */ - removeHyphenationFromElement = function (el) { - var h, u, i = 0, n; - switch (hyphen) { - case '|': - h = '\\|'; - break; - case '+': - h = '\\+'; - break; - case '*': - h = '\\*'; - break; - default: - h = hyphen; - } - switch (urlhyphen) { - case '|': - u = '\\|'; - break; - case '+': - u = '\\+'; - break; - case '*': - u = '\\*'; - break; - default: - u = urlhyphen; - } - n = el.childNodes[i]; - while (!!n) { - if (n.nodeType === 3) { - n.data = n.data.replace(new RegExp(h, 'g'), ''); - n.data = n.data.replace(new RegExp(u, 'g'), ''); - } else if (n.nodeType === 1) { - removeHyphenationFromElement(n); - } - i += 1; - n = el.childNodes[i]; - } - }, - - copy = (function () { - var Copy = function () { - - this.oncopyHandler = function (e) { - e = e || window.event; - var shadow, selection, range, rangeShadow, restore, - target = e.target || e.srcElement, - currDoc = target.ownerDocument, - bdy = currDoc.getElementsByTagName('body')[0], - targetWindow = currDoc.defaultView || currDoc.parentWindow; - if (target.tagName && dontHyphenate[target.tagName.toLowerCase()]) { - //Safari needs this - return; - } - //create a hidden shadow element - shadow = currDoc.createElement('div'); - //Moving the element out of the screen doesn't work for IE9 (https://connect.microsoft.com/IE/feedback/details/663981/) - //shadow.style.overflow = 'hidden'; - //shadow.style.position = 'absolute'; - //shadow.style.top = '-5000px'; - //shadow.style.height = '1px'; - //doing this instead: - shadow.style.color = window.getComputedStyle ? targetWindow.getComputedStyle(bdy, null).backgroundColor : '#FFFFFF'; - shadow.style.fontSize = '0px'; - bdy.appendChild(shadow); - if (!!window.getSelection) { - //FF3, Webkit, IE9 - e.stopPropagation(); - selection = targetWindow.getSelection(); - range = selection.getRangeAt(0); - shadow.appendChild(range.cloneContents()); - removeHyphenationFromElement(shadow); - selection.selectAllChildren(shadow); - restore = function () { - shadow.parentNode.removeChild(shadow); - selection.removeAllRanges(); //IE9 needs that - selection.addRange(range); - }; - } else { - // IE<9 - e.cancelBubble = true; - selection = targetWindow.document.selection; - range = selection.createRange(); - shadow.innerHTML = range.htmlText; - removeHyphenationFromElement(shadow); - rangeShadow = bdy.createTextRange(); - rangeShadow.moveToElementText(shadow); - rangeShadow.select(); - restore = function () { - shadow.parentNode.removeChild(shadow); - if (range.text !== "") { - range.select(); - } - }; - } - window.setTimeout(restore, 0); - }; - - this.removeOnCopy = function (el) { - var body = el.ownerDocument.getElementsByTagName('body')[0]; - if (!body) { - return; - } - el = el || body; - if (window.removeEventListener) { - el.removeEventListener("copy", this.oncopyHandler, true); - } else { - el.detachEvent("oncopy", this.oncopyHandler); - } - }; - - this.registerOnCopy = function (el) { - var body = el.ownerDocument.getElementsByTagName('body')[0]; - if (!body) { - return; - } - el = el || body; - if (window.addEventListener) { - el.addEventListener("copy", this.oncopyHandler, true); - } else { - el.attachEvent("oncopy", this.oncopyHandler); - } - }; - }; - - return (safeCopy ? new Copy() : false); - }()), - - - /** - * @method Hyphenator~checkIfAllDone - * @desc - * Checks if all elements in {@link Hyphenator~elements} are hyphenated, unhides them and fires onHyphenationDone() - * @access private - */ - checkIfAllDone = function () { - var allDone = true, i, doclist = {}, doc; - elements.each(function (ellist) { - var j, l = ellist.length; - for (j = 0; j < l; j += 1) { - allDone = allDone && ellist[j].hyphenated; - if (!doclist.hasOwnProperty(ellist[j].element.baseURI)) { - doclist[ellist[j].element.ownerDocument.location.href] = true; - } - doclist[ellist[j].element.ownerDocument.location.href] = doclist[ellist[j].element.ownerDocument.location.href] && ellist[j].hyphenated; - } - }); - if (allDone) { - if (intermediateState === 'hidden' && unhide === 'progressive') { - elements.each(function (ellist) { - var j, l = ellist.length, el; - for (j = 0; j < l; j += 1) { - el = ellist[j].element; - el.className = el.className.replace(unhideClassRegExp, ''); - if (el.className === '') { - el.removeAttribute('class'); - } - } - }); - } - for (i = 0; i < CSSEditors.length; i += 1) { - CSSEditors[i].clearChanges(); - } - for (doc in doclist) { - if (doclist.hasOwnProperty(doc)) { - onHyphenationDone(doc); - } - } - } - }, - - - /** - * @method Hyphenator~hyphenateElement - * @desc - * 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 {string} lang - The language-code of the element - * @param {Element} elo - The element to hyphenate {@link Hyphenator~elements~ElementCollection~Element} - * @access private - */ - hyphenateElement = function (lang, elo) { - var el = elo.element, - hyphenate, - n, - i, - lo, - controlOrphans = function (part) { - var h, r; - switch (hyphen) { - case '|': - h = '\\|'; - break; - case '+': - h = '\\+'; - break; - case '*': - h = '\\*'; - break; - default: - h = hyphen; - } - //strip off blank space at the end (omitted closing tags) - part = part.replace(/[\s]*$/, ''); - 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)) { - lo = Hyphenator.languages[lang]; - hyphenate = function (word) { - var r; - if (!Hyphenator.doHyphenation) { - r = word; - } else if (urlOrMailRE.test(word)) { - r = hyphenateURL(word); - } else { - r = hyphenateWord(lo, lang, word); - } - return r; - }; - if (safeCopy && (el.tagName.toLowerCase() !== 'body')) { - copy.registerOnCopy(el); - } - i = 0; - n = el.childNodes[i]; - while (!!n) { - if (n.nodeType === 3 && n.data.length >= min) { //type 3 = #text -> hyphenate! - n.data = n.data.replace(lo.genRegExp, hyphenate); - if (orphanControl !== 1) { - n.data = n.data.replace(/[\S]+ [\S]+[\s]*$/, controlOrphans); - } - } - i += 1; - n = el.childNodes[i]; - } - } - if (intermediateState === 'hidden' && unhide === 'wait') { - el.className = el.className.replace(hideClassRegExp, ''); - if (el.className === '') { - el.removeAttribute('class'); - } - } - if (intermediateState === 'hidden' && unhide === 'progressive') { - el.className = el.className.replace(hideClassRegExp, ' ' + unhideClass); - } - elo.hyphenated = true; - elements.hyCount += 1; - if (elements.count <= elements.hyCount) { - checkIfAllDone(); - } - }, - - /** - * @method Hyphenator~hyphenateLanguageElements - * @desc - * Calls hyphenateElement() for all elements of the specified language. - * If the language is '*' then all elements are hyphenated. - * This is done with a setTimout - * to prevent a "long running Script"-alert when hyphenating large pages. - * Therefore a tricky bind()-function was necessary. - * @param {string} lang The language of the elements to hyphenate - * @access private - */ - hyphenateLanguageElements = function (lang) { - function bind(fun, arg1, arg2) { - return function () { - return fun(arg1, arg2); - }; - } - var i, l; - if (lang === '*') { - elements.each(function (lang, ellist) { - var j, le = ellist.length; - for (j = 0; j < le; j += 1) { - window.setTimeout(bind(hyphenateElement, lang, ellist[j]), 0); - } - }); - } else { - if (elements.list.hasOwnProperty(lang)) { - l = elements.list[lang].length; - for (i = 0; i < l; i += 1) { - window.setTimeout(bind(hyphenateElement, lang, elements.list[lang][i]), 0); - } - } - } - }, - - /** - * @method Hyphenator~removeHyphenationFromDocument - * @desc - * Does what it says and unregisters the onCopyEvent from the elements - * @access private - */ - removeHyphenationFromDocument = function () { - elements.each(function (ellist) { - var i, l = ellist.length; - for (i = 0; i < l; i += 1) { - removeHyphenationFromElement(ellist[i].element); - if (safeCopy) { - copy.removeOnCopy(ellist[i].element); - } - ellist[i].hyphenated = false; - } - }); - }, - - /** - * @method Hyphenator~createStorage - * @desc - * inits the private var {@link Hyphenator~storage) depending of the setting in {@link Hyphenator~storageType} - * and the supported features of the system. - * @access private - */ - createStorage = function () { - var s; - try { - if (storageType !== 'none' && - window.localStorage !== undefined && - window.sessionStorage !== undefined && - window.JSON.stringify !== undefined && - window.JSON.parse !== undefined) { - switch (storageType) { - case 'session': - s = window.sessionStorage; - break; - case 'local': - s = window.localStorage; - break; - default: - s = undefined; - break; - } - //check for private mode - s.setItem('storageTest', '1'); - s.removeItem('storageTest'); - } - } catch (e) { - //FF throws an error if DOM.storage.enabled is set to false - s = undefined; - } - if (s) { - storage = { - prefix: 'Hyphenator_' + Hyphenator.version + '_', - store: s, - test: function (name) { - var val = this.store.getItem(this.prefix + name); - return (!!val) ? true : false; - }, - getItem: function (name) { - return this.store.getItem(this.prefix + name); - }, - setItem: function (name, value) { - try { - this.store.setItem(this.prefix + name, value); - } catch (e) { - onError(e); - } - } - }; - } else { - storage = undefined; - } - }, - - /** - * @method Hyphenator~storeConfiguration - * @desc - * Stores the current config-options in DOM-Storage - * @access private - */ - storeConfiguration = function () { - if (!storage) { - return; - } - var settings = { - 'STORED': true, - 'classname': hyphenateClass, - 'urlclassname': urlHyphenateClass, - 'donthyphenateclassname': dontHyphenateClass, - 'minwordlength': min, - 'hyphenchar': hyphen, - 'urlhyphenchar': urlhyphen, - 'togglebox': toggleBox, - 'displaytogglebox': displayToggleBox, - 'remoteloading': enableRemoteLoading, - 'enablecache': enableCache, - 'enablereducedpatternset': enableReducedPatternSet, - 'onhyphenationdonecallback': onHyphenationDone, - 'onerrorhandler': onError, - 'onwarninghandler': onWarning, - 'intermediatestate': intermediateState, - 'selectorfunction': selectorFunction || mySelectorFunction, - 'safecopy': safeCopy, - 'doframes': doFrames, - 'storagetype': storageType, - 'orphancontrol': orphanControl, - 'dohyphenation': Hyphenator.doHyphenation, - 'persistentconfig': persistentConfig, - 'defaultlanguage': defaultLanguage, - 'useCSS3hyphenation': css3, - 'unhide': unhide, - 'onbeforewordhyphenation': onBeforeWordHyphenation, - 'onafterwordhyphenation': onAfterWordHyphenation - }; - storage.setItem('config', window.JSON.stringify(settings)); - }, - - /** - * @method Hyphenator~restoreConfiguration - * @desc - * Retrieves config-options from DOM-Storage and does configuration accordingly - * @access private - */ - restoreConfiguration = function () { - var settings; - if (storage.test('config')) { - settings = window.JSON.parse(storage.getItem('config')); - Hyphenator.config(settings); - } - }; - - return { - - /** - * @member {string} Hyphenator.version - * @desc - * 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 - * @access public - */ - version: '4.3.0', - - /** - * @member {boolean} Hyphenator.doHyphenation - * @desc - * If doHyphenation is set to false, hyphenateDocument() isn't called. - * All other actions are performed. - * @default true - */ - doHyphenation: true, - - /** - * @typedef {Object} Hyphenator.languages.language - * @property {Number} leftmin - The minimum of chars to remain on the old line - * @property {Number} rightmin - The minimum of chars to go on the new line - * @property {string} specialChars - Non-ASCII chars in the alphabet. - * @property {Object.<number, string>} patterns - the patterns in a compressed format. The key is the length of the patterns in the value string. - * @property {Object.<string, string>} charSubstitution - optional: a hash table with chars that are replaced during hyphenation - * @property {string | Object.<string, string>} exceptions - optional: a csv string containing exceptions - */ - - /** - * @member {Object.<string, Hyphenator.languages.language>} Hyphenator.languages - * @desc - * 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. - * @namespace Hyphenator.languages - * @access public - */ - languages: {}, - - - /** - * @method Hyphenator.config - * @desc - * The Hyphenator.config() function that takes an object as an argument. The object contains key-value-pairs - * containig Hyphenator-settings. - * @param {Hyphenator.config} obj - * @access 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; - */ - config: function (obj) { - var assert = function (name, type) { - var r, t; - t = typeof obj[name]; - if (t === type) { - r = true; - } else { - onError(new Error('Config onError: ' + name + ' must be of type ' + type)); - r = false; - } - return r; - }, - key; - - 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 'urlclassname': - if (assert('urlclassname', 'string')) { - urlHyphenateClass = 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 'onwarninghandler': - if (assert('onwarninghandler', 'function')) { - onWarning = 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; - case 'useCSS3hyphenation': - if (assert('useCSS3hyphenation', 'boolean')) { - css3 = obj[key]; - } - break; - case 'unhide': - if (assert('unhide', 'string')) { - unhide = obj[key]; - } - break; - case 'onbeforewordhyphenation': - if (assert('onbeforewordhyphenation', 'function')) { - onBeforeWordHyphenation = obj[key]; - } - break; - case 'onafterwordhyphenation': - if (assert('onafterwordhyphenation', 'function')) { - onAfterWordHyphenation = obj[key]; - } - break; - default: - onError(new Error('Hyphenator.config: property ' + key + ' not known.')); - } - } - } - if (storage && persistentConfig) { - storeConfiguration(); - } - }, - - /** - * @method Hyphenator.run - * @desc - * Bootstrap function that starts all hyphenation processes when called: - * Tries to create storage if required and calls {@link Hyphenator~runWhenLoaded} on 'window' handing over the callback 'process' - * @access 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; - */ - run: function () { - /** - *@callback Hyphenator.run~process process - The function is called when the DOM has loaded (or called for each frame) - */ - var process = function () { - try { - if (contextWindow.document.getElementsByTagName('frameset').length > 0) { - return; //we are in a frameset - } - autoSetMainLanguage(undefined); - gatherDocumentInfos(); - prepare(hyphenateLanguageElements); - if (displayToggleBox) { - toggleBox(); - } - } catch (e) { - onError(e); - } - }; - - if (!storage) { - createStorage(); - } - runWhenLoaded(window, process); - }, - - /** - * @method Hyphenator.addExceptions - * @desc - * 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. - * @access 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; - */ - addExceptions: function (lang, words) { - if (lang === '') { - lang = 'global'; - } - if (exceptions.hasOwnProperty(lang)) { - exceptions[lang] += ", " + words; - } else { - exceptions[lang] = words; - } - }, - - /** - * @method Hyphenator.hyphenate - * @access public - * @desc - * 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 and undefined (aka nothing) is returned - * @param {string|Object} target the target to be hyphenated - * @param {string} lang the language of the target - * @returns {string|undefined} - * @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; - */ - hyphenate: function (target, lang) { - var hyphenate, n, i, lo; - lo = Hyphenator.languages[lang]; - if (Hyphenator.languages.hasOwnProperty(lang)) { - if (!lo.prepared) { - prepareLanguagesObj(lang); - } - hyphenate = function (word) { - var r; - if (urlOrMailRE.test(word)) { - r = hyphenateURL(word); - } else { - r = hyphenateWord(lo, lang, word); - } - return r; - }; - if (typeof target === 'object' && !(typeof target === 'string' || target.constructor === String)) { - i = 0; - n = target.childNodes[i]; - while (!!n) { - if (n.nodeType === 3 && n.data.length >= min) { //type 3 = #text -> hyphenate! - n.data = n.data.replace(lo.genRegExp, hyphenate); - } else if (n.nodeType === 1) { - if (n.lang !== '') { - Hyphenator.hyphenate(n, n.lang); - } else { - Hyphenator.hyphenate(n, lang); - } - } - i += 1; - n = target.childNodes[i]; - } - } else if (typeof target === 'string' || target.constructor === String) { - return target.replace(lo.genRegExp, hyphenate); - } - } else { - onError(new Error('Language "' + lang + '" is not loaded.')); - } - }, - - /** - * @method Hyphenator.getRedPatternSet - * @desc - * Returns the reduced pattern set: an object looking like: {'patk': pat} - * @param {string} lang the language patterns are stored for - * @returns {Object.<string, string>} - * @access public - */ - getRedPatternSet: function (lang) { - return Hyphenator.languages[lang].redPatSet; - }, - - /** - * @method Hyphenator.isBookmarklet - * @desc - * Returns {@link Hyphenator~isBookmarklet}. - * @returns {boolean} - * @access public - */ - isBookmarklet: function () { - return isBookmarklet; - }, - - /** - * @method Hyphenator.getConfigFromURI - * @desc - * reads and sets configurations from GET parameters in the URI - * @access public - */ - getConfigFromURI: function () { - /*jslint evil: true*/ - var loc = null, re = {}, jsArray = contextWindow.document.getElementsByTagName('script'), i, j, l, s, gp, option; - for (i = 0, l = jsArray.length; i < l; i += 1) { - if (!!jsArray[i].getAttribute('src')) { - loc = jsArray[i].getAttribute('src'); - } - if (loc && (loc.indexOf('Hyphenator.js?') !== -1)) { - s = loc.indexOf('Hyphenator.js?'); - gp = loc.substring(s + 14).split('&'); - for (j = 0; j < gp.length; j += 1) { - option = gp[j].split('='); - if (option[0] !== 'bm') { - if (option[1] === 'true') { - option[1] = true; - } else if (option[1] === 'false') { - option[1] = false; - } else if (isFinite(option[1])) { - option[1] = parseInt(option[1], 10); - } - if (option[0] === 'togglebox' || - option[0] === 'onhyphenationdonecallback' || - option[0] === 'onerrorhandler' || - option[0] === 'selectorfunction' || - option[0] === 'onbeforewordhyphenation' || - option[0] === 'onafterwordhyphenation') { - option[1] = new Function('', option[1]); - } - re[option[0]] = option[1]; - } - } - break; - } - } - return re; - }, - - /** - * @method Hyphenator.toggleHyphenation - * @desc - * Checks the current state of the ToggleBox and removes or does hyphenation. - * @access public - */ - toggleHyphenation: function () { - if (Hyphenator.doHyphenation) { - if (!!css3hyphenateClassHandle) { - css3hyphenateClassHandle.setRule('.' + css3hyphenateClass, css3_h9n.property + ': none;'); - } - removeHyphenationFromDocument(); - Hyphenator.doHyphenation = false; - storeConfiguration(); - toggleBox(); - } else { - if (!!css3hyphenateClassHandle) { - css3hyphenateClassHandle.setRule('.' + css3hyphenateClass, css3_h9n.property + ': auto;'); - } - hyphenateLanguageElements('*'); - Hyphenator.doHyphenation = true; - storeConfiguration(); - toggleBox(); - } - } - }; -}(window)); - -//Export properties/methods (for google closure compiler) -/**** to be moved to external file -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; -*/ - -/* - * call Hyphenator if it is a Bookmarklet - */ -if (Hyphenator.isBookmarklet()) { - Hyphenator.config({displaytogglebox: true, intermediatestate: 'visible', storagetype: 'local', doframes: true, useCSS3hyphenation: true}); - Hyphenator.config(Hyphenator.getConfigFromURI()); - Hyphenator.run(); -}
M content/js/init.jscontent/js/init.js

@@ -1,8 +1,6 @@

$(document).ready(function() { // Manage dates $('.timeago').timeago(); - // Hyphenate contents - Hyphenator.run(); // Search $("#h3rald-search-btn").click(function(){ h3rald_search();
M content/styles/_elements.lesscontent/styles/_elements.less

@@ -175,8 +175,9 @@ .article-info {

font-style: italic; } -.hyphenate { +.hyphenate, .hyphens { text-align: justify; + } article p[style*="right"] {
M layouts/default.erblayouts/default.erb

@@ -36,14 +36,11 @@ <link rel="shortcut icon" href="/favicon.png" type="image/png" />

<meta content="44.388041;9.073248" name="ICBM" /> <link rel="stylesheet" type="text/css" href="/styles/style.css" /> - <!--[if lt IE 9]> - <script src="https://html5shiv.googlecode.com/svn/trunk/html5.js"></script> - <![endif]--> - <script src="https://www.google.com/jsapi?key=ABQIAAAAr6RY1Z6dchG_sX9WDLSy3xRlq2n1sm52B5HDRR5tm6o8XM18FhR56xHNNH6CsX86uN5VoTrglpyOyQ" type="text/javascript"></script> + <!-- <script src="https://www.google.com/jsapi?key=ABQIAAAAr6RY1Z6dchG_sX9WDLSy3xRlq2n1sm52B5HDRR5tm6o8XM18FhR56xHNNH6CsX86uN5VoTrglpyOyQ" type="text/javascript"></script> --> + <script src="js/fingerprint.js"></script> <script src="/js/jquery.js" type="text/javascript"></script> <script src="/js/jquery-timeago.js" type="text/javascript"></script> <script src="/js/date.js" type="text/javascript"></script> - <script src="/js/hyphenator.js" type="text/javascript"></script> <script src="/js/init.js" type="text/javascript"></script> <script src="/js/search.js" type="text/javascript"></script> <script src="/js/highlight.js" type="text/javascript"></script>

@@ -90,16 +87,19 @@ hljs.initHighlightingOnLoad();

</script> <!-- Start Google Analytics --> <script type="text/javascript"> - var _gaq = _gaq || []; - _gaq.push(['_setAccount', 'UA-18587377-1']); - _gaq.push(['_trackPageview']); + (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ + (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), + m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) + })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); + + ga('create', 'UA-18587377-1', { + 'storage': 'none', + 'clientId': new Fingerprint().get() + }); + ga('set', 'anonymizeIp', true); + ga('send', 'pageview'); - (function() { - var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; - ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; - var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); - })(); - </script> + </script> <!-- End Google Analytics --> </div> <!-- End #wrap --> </body>
M layouts/footer.erblayouts/footer.erb

@@ -26,7 +26,7 @@ <h1>License</h1>

<p>Unless stated otherwise, all the articles and content published on this web site is licensed under the <a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/3.0/">Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 Unported License</a>.</p> <p class="license-logo"> - <img alt="Creative Commons License" src="https://i.creativecommons.org/l/by-nc-nd/3.0/88x31.png" /> + <img alt="Creative Commons License" src="/img/by-nc-nd.png" /> </p> <p>The source code of this web site, such as its layout, <span class="caps">LESS/CSS</span> stylesheets, custom rake tasks and code is licensed under the terms of the <a href="http://creativecommons.org/licenses/MIT/"><span class="caps">MIT</span> License</a> and it is available on <a href="https://github.com/h3rald/h3rald">GitHub</a>.</p>