Commit cf7e0ca9 authored by julien's avatar julien
Browse files

hyphens example

parent af8ffe35
This diff is collapsed.
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<meta lang="en-US">
<link href="css/main.css" rel="stylesheet">
</head>
<script>
var Hyphenopoly = {
require: {
"en-us": "Supercalifragilisticexpialidocious"
},
paths: {
patterndir: "./js/hyphens/patterns/",
maindir: "./js/hyphens/"
},
};
</script>
<script src="js/hyphens/Hyphenopoly_Loader.js"></script>
<script>
function pagedjs() {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "js/paged.polyfill.js";
document.getElementsByTagName("head")[0].appendChild(script);
}
</script>
<style>
#render {
position: fixed;
right: 3em;
top: 3em;
background: black;
color: red;
font-weight: bold;
border: 3px solid red;
padding: 0.45em 1em 0.5em;
text-transform: uppercase;
}
#render:hover {
box-shadow: 0 0 0 4px black;
}
</style>
<body class="hyphenate" lang="en-US">
<button id="render">render</button>
<div id="cover"> </div>
<section data-type="chapter">
<div class="running-chapter">Running chapter</div>
<div class="running-part">Running part</div>
<p>introduction of Peru’s CCT program, Juntos, a World Bank–supported program intended to tackle the acute impacts of poverty.</p>
<p>CCTs originated in Latin America, and today they are among the most evaluated social programs on the planet. The majority of evidence on CCT impacts comes from the Mexican program now called Progresa, which is one of the earliest, and now largest, CCTs. Regular evaluations were built into the program administration at the outset, and this set a significant precedent. Today, we have a robust body of evidence that policy makers draw on to maintain and expand existing programs and to support implementation of new initiatives. Most of the available evidence derives from quantitative research, especially experimental methods such as randomized control trials and quasi-experimental methods (e.g., regression discontinuity, propensity score matching, instrumental variable, and difference-in- differences; Lagarde et al. 2007; Leroy et al. 2009; Kabeer and Waddington 2015). This literature is largely concerned with measuring primary program objectives related to household consumption and the uptake of health and education services. While acknowledging some variation related to program design, the existing quantitative evidence tells us that CCTs are, overall, effective and efficient mechanisms for altering the health- and education-seeking behavior of poor households.</p>
<p>For instance, regarding health and nutrition, we know that CCTs are effectiveat increasing utilization of health services (Gertler 2000; Attanasio et al. 2005; Levy and Ohls 2007; Galasso 2011) and increasing household food consumption (Hoddinott and Skoufias 2004; Angelucci and Attanasio 2009; Resende and Oliveira 2008; Handa et al. 2009). Where CCT programs have been implemented with the goal of reducing maternal mortality, they have effectively increased pregnant women’s use of health services, including antenatal care and in-facility births (Lim et al. 2010; Glassman et al. 2013). CCTs have been linked to a reduction in neonatal, infant, and child mortality and, in particular, deaths attributable to poverty-related causes such as malnutrition and diarrhea (Barham 2011; Rasella et al. 2013). CCTs have been shown to produce better growth outcomes in children (i.e., reduction in stunting; Gertler 2004; Fernald et al. 2010; Andersen et al. 2015; Kandpal et al. 2016) and improvement in children’s motor skills and cognitive development (Fernald et al. 2008). Both outcomes are likely related to uptake of health services and increased household consumption. CCTs have also been successfully deployed to increase vaccination rates for such diseases as tuberculosis, measles, diphtheria, pertussis, tetanus, and polio (Morris et al. 2004; Barham 2005; Barham and Maluccio 2009).</p>
<p>Regarding the aim of building human capital through education, studies show that CCTs are effective at increasing school enrollment (Schultz 2004; Sadoulet et al. 2004; Behrman et al. 2005; Cardoso and Souza 2003; Dammert 2009; Attanasio et al. 2010). As is the case with health service usage, there is some variability related to gender, age, ethnicity, and location, but overall the evidence indicates a positive </p>
</section>
<section class="chapter" data-type="chapter" contenteditable="true">
<header>
<div class="cn">1</div>
<h1 class="ct">Of the Bookshelf <br> Long title might look like</h1>
<div class="running-chapter">Of the Bookshelf</div>
<div class="cst">A few of my own</div>
</header>
<p>At the most general level, comparison is not a special method, or in any way unique to anthropology. Comparison is implicit in any method of deriving understanding through <em>explanation.</em></p>
</section>
<script>
function show() {
pagedjs();
document.querySelector("#render").style.display = "none";
}
document.querySelector('#render').addEventListener('click', show);
</script>
</body>
</html>
\ No newline at end of file
# Version History
## Version 2.3.0 (Juli 26, 2018)
### Hyphenopoly_Loader.js and Hyphenopoly.js:
* Don't use template strings [#28](https://github.com/mnater/Hyphenopoly/issues/28)
* run feature test for wasm support only if necessary
### hyphenopoly.module.js:
* define node >=8.3.0 as requirement (for util.TextDecoder)
* small refactorings
## Version 2.2.0 (June 26, 2018)
* provide example.js for RunKit
* use tap instead of mocha
* [6f9e539](https://github.com/mnater/Hyphenopoly/commit/6f9e539a5dab2d1eff5bdeb0c7857c6fda9eb41e)
* bugfix: [#24](https://github.com/mnater/Hyphenopoly/issues/24): [aeefe6e](https://github.com/mnater/Hyphenopoly/commit/aeefe6e3a59e8356abc99ca490acabf6c3374d7b)
## Version 2.1.0 (Mai 27, 2018)
* Configure Travis-CI
* bugfixes
## Version 2.0.0 (Mai 27, 2018)
* Provide node module (https://github.com/mnater/Hyphenopoly/wiki/Node-Module)
* default file locations better reflect usual installations [#19](https://github.com/mnater/Hyphenopoly/issues/19)
* Add ability to store results of feature tests (optional) [#22](https://github.com/mnater/Hyphenopoly/issues/22)
* better error handling (f4bbaa7759eed24208e5cd7c744f1131262abb20, 1c7b0b67666b507d6f6b02eea38460562a5835e4)
* correct implementation of e.preventDefault (df988788db6fb7120fc0c8a1cff1c91aac5a3998)
* fix string normalization (a3229f730f79ccdd3054cbac257b2345f5c8e11a)
* Better tooling: minify, eslint, testing (mocha), compiling (https://github.com/mnater/Hyphenopoly/wiki/Usage-of-devDependencies)
## Version 1.0.1 (Mai 13, 2018)
Prevent browsers to force layout on feature test in some cases.
## Version 1.0.0 (Mai 12, 2018)
First release
This diff is collapsed.
/**
* @license Hyphenopoly_Loader 2.4.0 - client side hyphenation
* ©2018 Mathias Nater, Zürich (mathiasnater at gmail dot com)
* https://github.com/mnater/Hyphenopoly
*
* Released under the MIT license
* http://mnater.github.io/Hyphenopoly/LICENSE
*/
(function H9YL() {
"use strict";
const d = document;
const H = Hyphenopoly;
/**
* Create Object without standard Object-prototype
* @returns {Object} empty object
*/
function empty() {
return Object.create(null);
}
(function config() {
// Set H.clientFeat (either from sessionStorage or empty)
if (H.cacheFeatureTests && sessionStorage.getItem("Hyphenopoly_Loader")) {
H.clientFeat = JSON.parse(sessionStorage.getItem("Hyphenopoly_Loader"));
} else {
H.clientFeat = {
"langs": empty(),
"polyfill": false,
"wasm": null
};
}
// Set defaults for paths and setup
if (H.paths) {
if (!H.paths.patterndir) {
H.paths.patterndir = "../Hyphenopoly/patterns/";
}
if (!H.paths.maindir) {
H.paths.maindir = "../Hyphenopoly/";
}
} else {
H.paths = {
"maindir": "../Hyphenopoly/",
"patterndir": "../Hyphenopoly/patterns/"
};
}
if (H.setup) {
if (!H.setup.classnames) {
H.setup.classnames = {"hyphenate": {}};
}
if (!H.setup.timeout) {
H.setup.timeout = 1000;
}
} else {
H.setup = {
"classnames": {"hyphenate": {}},
"timeout": 1000
};
}
}());
(function setupEvents() {
// Events known to the system
const definedEvents = empty();
// Default events, execution deferred to Hyphenopoly.js
const deferred = [];
/*
* Eegister for custom event handlers, where event is not yet defined
* these events will be correctly registered in Hyphenopoly.js
*/
const tempRegister = [];
/**
* Create Event Object
* @param {string} name The Name of the event
* @param {function} defFunc The default method of the event
* @param {boolean} cancellable Is the default cancellable
* @returns {undefined}
*/
function define(name, defFunc, cancellable) {
definedEvents[name] = {
"cancellable": cancellable,
"default": defFunc,
"register": []
};
}
define(
"timeout",
function def(e) {
d.documentElement.style.visibility = "visible";
window.console.info(
"Hyphenopolys 'FOUHC'-prevention timed out after %dms",
e.delay
);
},
false
);
define(
"error",
function def(e) {
window.console.error(e.msg);
},
true
);
define(
"contentLoaded",
function def(e) {
deferred.push({
"data": e,
"name": "contentLoaded"
});
},
false
);
define(
"engineLoaded",
function def(e) {
deferred.push({
"data": e,
"name": "engineLoaded"
});
},
false
);
define(
"hpbLoaded",
function def(e) {
deferred.push({
"data": e,
"name": "hpbLoaded"
});
},
false
);
/**
* Dispatch error <name> with arguments <data>
* @param {string} name The name of the event
* @param {Object|undefined} data Data of the event
* @returns {undefined}
*/
function dispatch(name, data) {
if (!data) {
data = empty();
}
let defaultHasRun = false;
definedEvents[name].register.forEach(function call(currentHandler) {
let defaultPrevented = false;
data.preventDefault = function preventDefault() {
if (definedEvents[name].cancellable) {
defaultPrevented = true;
}
};
currentHandler(data);
if (
!defaultPrevented &&
!defaultHasRun &&
definedEvents[name].default
) {
definedEvents[name].default(data);
defaultHasRun = true;
}
});
if (!defaultHasRun && definedEvents[name].default) {
definedEvents[name].default(data);
}
}
/**
* Add EventListender <handler> to event <name>
* @param {string} name The name of the event
* @param {function} handler Function to register
* @param {boolean} defer If the registration is deferred
* @returns {undefined}
*/
function addListener(name, handler, defer) {
if (definedEvents[name]) {
definedEvents[name].register.push(handler);
} else if (defer) {
tempRegister.push({
"handler": handler,
"name": name
});
} else {
H.events.dispatch(
"error",
{"msg": "unknown Event \"" + name + "\" discarded"}
);
}
}
if (H.handleEvent) {
Object.keys(H.handleEvent).forEach(function add(name) {
addListener(name, H.handleEvent[name], true);
});
}
H.events = empty();
H.events.deferred = deferred;
H.events.tempRegister = tempRegister;
H.events.dispatch = dispatch;
H.events.define = define;
H.events.addListener = addListener;
}());
/**
* Test if wasm is supported
* @returns {undefined}
*/
function featureTestWasm() {
/* eslint-disable max-len, no-magic-numbers, no-prototype-builtins */
/**
* Feature test for wasm
* @returns {boolean} support
*/
function runWasmTest() {
/*
* This is the original test, without webkit workaround
* if (typeof WebAssembly === "object" &&
* typeof WebAssembly.instantiate === "function") {
* const module = new WebAssembly.Module(Uint8Array.from(
* [0, 97, 115, 109, 1, 0, 0, 0]
* ));
* if (WebAssembly.Module.prototype.isPrototypeOf(module)) {
* return WebAssembly.Instance.prototype.isPrototypeOf(
* new WebAssembly.Instance(module)
* );
* }
* }
* return false;
*/
/*
* Wasm feature test with iOS bug detection
* (https://bugs.webkit.org/show_bug.cgi?id=181781)
*/
if (
typeof WebAssembly === "object" &&
typeof WebAssembly.instantiate === "function"
) {
/* eslint-disable array-element-newline */
const module = new WebAssembly.Module(Uint8Array.from([
0, 97, 115, 109, 1, 0, 0, 0, 1, 6, 1, 96, 1, 127, 1, 127,
3, 2, 1, 0, 5, 3, 1, 0, 1, 7, 8, 1, 4, 116, 101, 115,
116, 0, 0, 10, 16, 1, 14, 0, 32, 0, 65, 1, 54, 2, 0, 32,
0, 40, 2, 0, 11
]));
/* eslint-enable array-element-newline */
if (WebAssembly.Module.prototype.isPrototypeOf(module)) {
const inst = new WebAssembly.Instance(module);
return WebAssembly.Instance.prototype.isPrototypeOf(inst) &&
(inst.exports.test(4) !== 0);
}
}
return false;
}
/* eslint-enable max-len, no-magic-numbers, no-prototype-builtins */
if (H.clientFeat.wasm === null) {
H.clientFeat.wasm = runWasmTest();
}
}
const scriptLoader = (function scriptLoader() {
const loadedScripts = empty();
/**
* Load script by adding <script>-tag
* @param {string} path Where the script is stored
* @param {string} filename Filename of the script
* @returns {undefined}
*/
function loadScript(path, filename) {
if (!loadedScripts[filename]) {
const script = d.createElement("script");
loadedScripts[filename] = true;
script.src = path + filename;
if (filename === "hyphenEngine.asm.js") {
script.addEventListener("load", function listener() {
H.events.dispatch("engineLoaded", {"msg": "asm"});
});
}
d.head.appendChild(script);
}
}
return loadScript;
}());
const loadedBins = empty();
/**
* Load binary files either with fetch (on new browsers that support wasm)
* or with xmlHttpRequest
* @param {string} path Where the script is stored
* @param {string} fne Filename of the script with extension
* @param {string} name Name of the ressource
* @param {Object} msg Message
* @returns {undefined}
*/
function binLoader(path, fne, name, msg) {
/**
* Get bin file using fetch
* @param {string} p Where the script is stored
* @param {string} f Filename of the script with extension
* @param {string} n Name of the ressource
* @param {Object} m Message
* @returns {undefined}
*/
function fetchBinary(p, f, n, m) {
if (!loadedBins[f]) {
loadedBins[f] = true;
window.fetch(p + f).then(
function resolve(response) {
if (response.ok) {
if (n === "hyphenEngine") {
H.binaries[n] = response.arrayBuffer().then(
function getModule(buf) {
return new WebAssembly.Module(buf);
}
);
} else {
H.binaries[n] = response.arrayBuffer();
}
H.events.dispatch(m[0], {"msg": m[1]});
}
}
);
}
}
/**
* Get bin file using XHR
* @param {string} p Where the script is stored
* @param {string} f Filename of the script with extension
* @param {string} n Name of the ressource
* @param {Object} m Message
* @returns {undefined}
*/
function requestBinary(p, f, n, m) {
if (!loadedBins[f]) {
loadedBins[f] = true;
const xhr = new XMLHttpRequest();
xhr.open("GET", p + f);
xhr.onload = function onload() {
H.binaries[n] = xhr.response;
H.events.dispatch(m[0], {"msg": m[1]});
};
xhr.responseType = "arraybuffer";
xhr.send();
}
}
if (H.clientFeat.wasm) {
fetchBinary(path, fne, name, msg);
} else {
requestBinary(path, fne, name, msg);
}
}
/**
* Allocate memory for (w)asm
* @param {string} lang Language
* @returns {undefined}
*/
function allocateMemory(lang) {
let wasmPages = 0;
switch (lang) {
case "nl":
wasmPages = 41;
break;
case "de":
wasmPages = 75;
break;
case "nb-no":
wasmPages = 92;
break;
case "hu":
wasmPages = 207;
break;
default:
wasmPages = 32;
}
if (!H.specMems) {
H.specMems = empty();
}
if (H.clientFeat.wasm) {
H.specMems[lang] = new WebAssembly.Memory({
"initial": wasmPages,
"maximum": 256
});
} else {
/**
* Polyfill Math.log2
* @param {number} x argument
* @return {number} Log2(x)
*/
Math.log2 = Math.log2 || function polyfillLog2(x) {
return Math.log(x) * Math.LOG2E;
};
/* eslint-disable no-bitwise */
const asmPages = (2 << Math.floor(Math.log2(wasmPages))) * 65536;
/* eslint-enable no-bitwise */
H.specMems[lang] = new ArrayBuffer(asmPages);
}
}
/**
* Load all ressources for a required <lang> and check if wasm is supported
* @param {string} lang The language
* @returns {undefined}
*/
function loadRessources(lang) {
let filename = lang + ".hpb";
if (H.fallbacks && H.fallbacks[lang]) {
filename = H.fallbacks[lang] + ".hpb";
}
if (!H.binaries) {
H.binaries = empty();
}
featureTestWasm();
scriptLoader(H.paths.maindir, "Hyphenopoly.js");
if (H.clientFeat.wasm) {
binLoader(
H.paths.maindir,
"hyphenEngine.wasm",
"hyphenEngine",
["engineLoaded", "wasm"]
);
} else {
scriptLoader(H.paths.maindir, "hyphenEngine.asm.js");
}
binLoader(H.paths.patterndir, filename, lang, ["hpbLoaded", lang]);
allocateMemory(lang);
}
(function featureTestCSSHyphenation() {
const tester = (function tester() {
let fakeBody = null;
const css = (function createCss() {
/* eslint-disable array-element-newline */
const props = [
"visibility:hidden;",
"-moz-hyphens:auto;",
"-webkit-hyphens:auto;",
"-ms-hyphens:auto;",
"hyphens:auto;",
"width:48px;",
"font-size:12px;",
"line-height:12px;",
"border:none;",
"padding:0;",
"word-wrap:normal"
];
/* eslint-enable array-element-newline */
return props.join("");
}());
/**
* Create and append div with CSS-hyphenated word
* @param {string} lang Language
* @returns {undefined}
*/
function createTest(lang) {
if (H.clientFeat.langs[lang]) {
return;
}
if (!fakeBody) {
fakeBody = d.createElement("body");
}
const testDiv = d.createElement("div");
testDiv.lang = lang;
testDiv.id = lang;
testDiv.style.cssText = css;
testDiv.appendChild(d.createTextNode(H.require[lang]));
fakeBody.appendChild(testDiv);
}
/**
* Append fakeBody with tests to target (document)
* @param {Object} target Where to append fakeBody
* @returns {Object|null} The body element or null, if no tests
*/
function appendTests(target) {