Skip to content
This repository
Browse code

Persistent proportional font-sizing with Formatting#setFontScale.

Additionally, you can now pass a float multiplier into Reader
initialisation options with 'fontScale'.
  • Loading branch information...
commit 2402da9d185601dea22cdc4df607449fb0b8b180 1 parent 3a79afe
Joseph Pearson authored
95 src/core/formatting.js
@@ -14,6 +14,7 @@ Monocle.Formatting = function (reader, optStyles, optScale) {
14 14
15 15
16 16 function initialize() {
  17 + p.fontScale = optScale;
17 18 clampStylesheets(optStyles);
18 19 p.reader.listen('monocle:componentmodify', persistOnComponentChange);
19 20 }
@@ -36,6 +37,7 @@ Monocle.Formatting = function (reader, optStyles, optScale) {
36 37 function persistOnComponentChange(evt) {
37 38 var doc = evt.m['document'];
38 39 doc.documentElement.id = p.reader.properties.systemId;
  40 + adjustFontScaleForDoc(doc, p.fontScale);
39 41 for (var i = 0; i < p.stylesheets.length; ++i) {
40 42 if (p.stylesheets[i]) {
41 43 addPageStylesheet(doc, i);
@@ -59,9 +61,7 @@ Monocle.Formatting = function (reader, optStyles, optScale) {
59 61
60 62 var i = 0, cmpt = null;
61 63 while (cmpt = p.reader.dom.find('component', i++)) {
62   - if (cmpt.contentDocument) {
63 64 addPageStylesheet(cmpt.contentDocument, sheetIndex);
64   - }
65 65 }
66 66 return sheetIndex;
67 67 }, restorePlace);
@@ -122,7 +122,7 @@ Monocle.Formatting = function (reader, optStyles, optScale) {
122 122 function changingStylesheet(callback, restorePlace) {
123 123 restorePlace = (restorePlace === false) ? false : true;
124 124 if (restorePlace) {
125   - p.reader.dispatchEvent("monocle:stylesheetchanging", {});
  125 + dispatchChanging();
126 126 }
127 127 var result = callback();
128 128 if (restorePlace) {
@@ -135,6 +135,11 @@ Monocle.Formatting = function (reader, optStyles, optScale) {
135 135 }
136 136
137 137
  138 + function dispatchChanging() {
  139 + p.reader.dispatchEvent("monocle:stylesheetchanging", {});
  140 + }
  141 +
  142 +
138 143 function dispatchChange() {
139 144 p.reader.dispatchEvent("monocle:stylesheetchange", {});
140 145 }
@@ -175,9 +180,93 @@ Monocle.Formatting = function (reader, optStyles, optScale) {
175 180 }
176 181
177 182
  183 + /* FONT SCALING */
  184 +
  185 + function setFontScale(scale, restorePlace) {
  186 + p.fontScale = scale;
  187 + if (restorePlace) {
  188 + dispatchChanging();
  189 + }
  190 + var i = 0, cmpt = null;
  191 + while (cmpt = p.reader.dom.find('component', i++)) {
  192 + adjustFontScaleForDoc(cmpt.contentDocument, scale);
  193 + }
  194 + if (restorePlace) {
  195 + p.reader.recalculateDimensions(true);
  196 + dispatchChange();
  197 + } else {
  198 + p.reader.recalculateDimensions(false);
  199 + }
  200 + }
  201 +
  202 +
  203 + function adjustFontScaleForDoc(doc, scale) {
  204 + var elems = doc.getElementsByTagName('*');
  205 + if (scale) {
  206 + scale = parseFloat(scale);
  207 + if (!doc.pfsSwept) {
  208 + sweepElements(doc, elems);
  209 + }
  210 +
  211 + // Iterate over each element, applying scale to the original
  212 + // font-size. If a proportional font sizing is already applied to
  213 + // the element, update existing cssText, otherwise append new cssText.
  214 + //
  215 + for (var j = 0, jj = elems.length; j < jj; ++j) {
  216 + var newFs = fsProperty(elems[j].pfsOriginal, scale);
  217 + if (elems[j].pfsApplied) {
  218 + replaceFontSizeInStyle(elems[j], newFs);
  219 + } else {
  220 + elems[j].style.cssText += newFs;
  221 + }
  222 + elems[j].pfsApplied = scale;
  223 + }
  224 + } else if (doc.pfsSwept) {
  225 + // Iterate over each element, removing proportional font-sizing flag
  226 + // and property from cssText.
  227 + for (var j = 0, jj = elems.length; j < jj; ++j) {
  228 + if (elems[j].pfsApplied) {
  229 + var oprop = elems[j].pfsOriginalProp;
  230 + var opropDec = oprop ? 'font-size: '+oprop+' ! important;' : '';
  231 + replaceFontSizeInStyle(elems[j], opropDec);
  232 + elems[j].pfsApplied = null;
  233 + }
  234 + }
  235 +
  236 + // Establish new baselines in case classes have changed.
  237 + sweepElements(doc, elems);
  238 + }
  239 + }
  240 +
  241 +
  242 + function sweepElements(doc, elems) {
  243 + // Iterate over each element, looking at its font size and storing
  244 + // the original value against the element.
  245 + for (var i = 0, ii = elems.length; i < ii; ++i) {
  246 + var currStyle = doc.defaultView.getComputedStyle(elems[i], null);
  247 + var fs = parseFloat(currStyle.getPropertyValue('font-size'));
  248 + elems[i].pfsOriginal = fs;
  249 + elems[i].pfsOriginalProp = elems[i].style.fontSize;
  250 + }
  251 + doc.pfsSwept = true;
  252 + }
  253 +
  254 +
  255 + function fsProperty(orig, scale) {
  256 + return 'font-size: '+(orig*scale)+'px ! important;';
  257 + }
  258 +
  259 +
  260 + function replaceFontSizeInStyle(elem, newProp) {
  261 + var lastFs = /font-size:[^;]/
  262 + elem.style.cssText = elem.style.cssText.replace(lastFs, newProp);
  263 + }
  264 +
  265 +
178 266 API.addPageStyles = addPageStyles;
179 267 API.updatePageStyles = updatePageStyles;
180 268 API.removePageStyles = removePageStyles;
  269 + API.setFontScale = setFontScale;
181 270
182 271 initialize();
183 272
3  src/core/reader.js
@@ -24,6 +24,9 @@
24 24 // stylesheet: A string of CSS rules to apply to the contents of each
25 25 // component loaded into the reader.
26 26 //
  27 +// fontScale: a float to multiply against the default font-size of each
  28 +// element in each component.
  29 +//
27 30 // place: A book locus for the page to open to when the reader is
28 31 // initialized. (See comments at Book#pageNumberAt for more about
29 32 // the locus option).
6 src/core/selection.js
@@ -16,9 +16,8 @@ Monocle.Selection = function (reader) {
16 16
17 17 function pollSelection() {
18 18 var index = 0, frame = null;
19   - while (frame = reader.dom.find('component', index)) {
  19 + while (frame = reader.dom.find('component', index++)) {
20 20 pollSelectionOnWindow(frame.contentWindow, index);
21   - index += 1;
22 21 }
23 22 }
24 23
@@ -60,9 +59,8 @@ Monocle.Selection = function (reader) {
60 59 //
61 60 function deselect() {
62 61 var index = 0, frame = null;
63   - while (frame = reader.dom.find('component', index)) {
  62 + while (frame = reader.dom.find('component', index++)) {
64 63 deselectOnWindow(frame.contentWindow);
65   - index += 1;
66 64 }
67 65 }
68 66
63 test/formatting/index.html
@@ -25,16 +25,34 @@
25 25
26 26 <script type="text/javascript" src="../../dist/scripts/monocore.js"></script>
27 27 <script type="text/javascript">
28   - Monocle.DEBUG = true;
29   -
30   - // Initialize the reader element.
31   - Monocle.Events.listen(window, 'load', function () {
32   - window.reader = Monocle.Reader(
33   - 'reader',
34   - Monocle.bookDataFromIds(['part1', 'part2']),
35   - { stylesheet: "body { color: #090; }" }
36   - );
37   - });
  28 + (function () {
  29 + function init() {
  30 + var bd = Monocle.bookDataFromIds(['part1', 'part2']);
  31 + var opts = { stylesheet: 'body { color: #090; }' };
  32 + window.reader = Monocle.Reader('reader', bd, opts, readerLoaded);
  33 + }
  34 +
  35 +
  36 + function readerLoaded() {
  37 + var sSel = document.getElementById('sizeSelect');
  38 + sSel.addEventListener('change', function (evt) {
  39 + reader.formatting.setFontScale(parseFloat(sSel.value), true);
  40 + });
  41 +
  42 + var cSel = document.getElementById('colorSelect');
  43 + cSel.addEventListener('change', function (evt) {
  44 + reader.formatting.updatePageStyles(
  45 + reader.formatting.properties.initialStyles,
  46 + 'body { color: '+cSel.value+'; }',
  47 + true
  48 + );
  49 + });
  50 + }
  51 +
  52 +
  53 + Monocle.DEBUG = true;
  54 + Monocle.Events.listen(window, 'load', init);
  55 + })();
38 56 </script>
39 57
40 58 </head>
@@ -48,8 +66,31 @@
48 66 turns the component's body text <span style="color: #090;">green</span>.
49 67 </p>
50 68
51   - <div id="reader"></div>
  69 + <p>
  70 + Font-scale:
  71 + <select id="sizeSelect">
  72 + <option value="">&mdash;</option>
  73 + <option value="0.1">10%</option>
  74 + <option value="0.5">50%</option>
  75 + <option value="0.8">80%</option>
  76 + <option value="1.0">100%</option>
  77 + <option value="1.1">110%</option>
  78 + <option value="1.3">130%</option>
  79 + <option value="1.6">160%</option>
  80 + <option value="2.0">200%</option>
  81 + <option value="2.5">250%</option>
  82 + <option value="4.0">400%</option>
  83 + <option value="8.0">800%</option>
  84 + </select>
52 85
  86 + Color:
  87 + <select id="colorSelect">
  88 + <option value="#090">Green</option>
  89 + <option value="#009">Blue</option>
  90 + </select>
  91 + </p>
  92 +
  93 + <div id="reader"></div>
53 94
54 95 <div id="part1">
55 96 <p>

0 comments on commit 2402da9

Please sign in to comment.
Something went wrong with that request. Please try again.