Bug 20554: (follow-up) Add local font files and add method for loading them
authorOwen Leonard <oleonard@myacpl.org>
Fri, 20 Apr 2018 17:08:21 +0000 (17:08 +0000)
committerNick Clemens <nick@bywatersolutions.com>
Fri, 19 Oct 2018 17:27:42 +0000 (17:27 +0000)
This patch adds local copies of the font files specified in the original
patch. A new JavaScript file has been added, fontfaceobserver.min.js,
which helps gracefully load font assets.

https://github.com/bramstein/fontfaceobserver

Information about the new assets has been added to the about page.

When using web fonts, there can be a delay, while the browser loads the
font files, between the time the page loads and the time the fonts
render. Font Face Observer allows us to specify a default font for the
initial page render, and then apply the web font after it has loaded.

To test, apply the patch and regenerate the OPAC css. View any page in
the OPAC and confirm that the custom font renders properly.

View the About page in the staff client and confirm that the new license
information looks correct.

Patch applies and OPAC and license look good. Looking forward to this.
Signed-off-by: Dilan Johnpullé <dilan@calyx.net.au>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>

Signed-off-by: Nick Clemens <nick@bywatersolutions.com>

14 files changed:
koha-tmpl/intranet-tmpl/prog/en/modules/about.tt
koha-tmpl/opac-tmpl/bootstrap/css/fonts/NotoSans-Bold-webfont.woff [new file with mode: 0644]
koha-tmpl/opac-tmpl/bootstrap/css/fonts/NotoSans-Bold-webfont.woff2 [new file with mode: 0644]
koha-tmpl/opac-tmpl/bootstrap/css/fonts/NotoSans-BoldItalic-webfont.woff [new file with mode: 0644]
koha-tmpl/opac-tmpl/bootstrap/css/fonts/NotoSans-BoldItalic-webfont.woff2 [new file with mode: 0644]
koha-tmpl/opac-tmpl/bootstrap/css/fonts/NotoSans-Italic-webfont.woff [new file with mode: 0644]
koha-tmpl/opac-tmpl/bootstrap/css/fonts/NotoSans-Italic-webfont.woff2 [new file with mode: 0644]
koha-tmpl/opac-tmpl/bootstrap/css/fonts/NotoSans-Regular-webfont.woff [new file with mode: 0644]
koha-tmpl/opac-tmpl/bootstrap/css/fonts/NotoSans-Regular-webfont.woff2 [new file with mode: 0644]
koha-tmpl/opac-tmpl/bootstrap/css/src/opac.scss
koha-tmpl/opac-tmpl/bootstrap/en/includes/doc-head-close.inc
koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-bottom.inc
koha-tmpl/opac-tmpl/bootstrap/js/global.js
koha-tmpl/opac-tmpl/bootstrap/lib/fontfaceobserver.min.js [new file with mode: 0644]

index 650e9c2..51a648d 100644 (file)
 
             <h2>C3.js</h2>
             <p><a href="http://c3js.org/">C3.js v0.4.11</a> is a D3-based reusable chart library under the <a href="https://opensource.org/licenses/mit-license.php">MIT licence</a></p>
+
+            <h2>Font Face Observer</h2>
+            <p><a href="https://github.com/bramstein/fontfaceobserver">Font Face Observer</a> is a JavaScript library by Bram Stein licensed under the <a href="https://github.com/bramstein/fontfaceobserver/blob/master/LICENSE">BSD License</a>.</p>
+
+            <h2>Noto fonts</h2>
+            <p><a href="https://github.com/googlei18n/noto-fonts">Noto</a> by Google is a family of fonts licensed under the <a href="http://scripts.sil.org/OFL">SIL Open Font License (OFL) v1.1</a>.</p>
         </div>
 
         <div id="translations">
diff --git a/koha-tmpl/opac-tmpl/bootstrap/css/fonts/NotoSans-Bold-webfont.woff b/koha-tmpl/opac-tmpl/bootstrap/css/fonts/NotoSans-Bold-webfont.woff
new file mode 100644 (file)
index 0000000..18d9cee
Binary files /dev/null and b/koha-tmpl/opac-tmpl/bootstrap/css/fonts/NotoSans-Bold-webfont.woff differ
diff --git a/koha-tmpl/opac-tmpl/bootstrap/css/fonts/NotoSans-Bold-webfont.woff2 b/koha-tmpl/opac-tmpl/bootstrap/css/fonts/NotoSans-Bold-webfont.woff2
new file mode 100644 (file)
index 0000000..9220249
Binary files /dev/null and b/koha-tmpl/opac-tmpl/bootstrap/css/fonts/NotoSans-Bold-webfont.woff2 differ
diff --git a/koha-tmpl/opac-tmpl/bootstrap/css/fonts/NotoSans-BoldItalic-webfont.woff b/koha-tmpl/opac-tmpl/bootstrap/css/fonts/NotoSans-BoldItalic-webfont.woff
new file mode 100644 (file)
index 0000000..7a29ceb
Binary files /dev/null and b/koha-tmpl/opac-tmpl/bootstrap/css/fonts/NotoSans-BoldItalic-webfont.woff differ
diff --git a/koha-tmpl/opac-tmpl/bootstrap/css/fonts/NotoSans-BoldItalic-webfont.woff2 b/koha-tmpl/opac-tmpl/bootstrap/css/fonts/NotoSans-BoldItalic-webfont.woff2
new file mode 100644 (file)
index 0000000..65cc99c
Binary files /dev/null and b/koha-tmpl/opac-tmpl/bootstrap/css/fonts/NotoSans-BoldItalic-webfont.woff2 differ
diff --git a/koha-tmpl/opac-tmpl/bootstrap/css/fonts/NotoSans-Italic-webfont.woff b/koha-tmpl/opac-tmpl/bootstrap/css/fonts/NotoSans-Italic-webfont.woff
new file mode 100644 (file)
index 0000000..e8f0b08
Binary files /dev/null and b/koha-tmpl/opac-tmpl/bootstrap/css/fonts/NotoSans-Italic-webfont.woff differ
diff --git a/koha-tmpl/opac-tmpl/bootstrap/css/fonts/NotoSans-Italic-webfont.woff2 b/koha-tmpl/opac-tmpl/bootstrap/css/fonts/NotoSans-Italic-webfont.woff2
new file mode 100644 (file)
index 0000000..3956efc
Binary files /dev/null and b/koha-tmpl/opac-tmpl/bootstrap/css/fonts/NotoSans-Italic-webfont.woff2 differ
diff --git a/koha-tmpl/opac-tmpl/bootstrap/css/fonts/NotoSans-Regular-webfont.woff b/koha-tmpl/opac-tmpl/bootstrap/css/fonts/NotoSans-Regular-webfont.woff
new file mode 100644 (file)
index 0000000..2ac0f4c
Binary files /dev/null and b/koha-tmpl/opac-tmpl/bootstrap/css/fonts/NotoSans-Regular-webfont.woff differ
diff --git a/koha-tmpl/opac-tmpl/bootstrap/css/fonts/NotoSans-Regular-webfont.woff2 b/koha-tmpl/opac-tmpl/bootstrap/css/fonts/NotoSans-Regular-webfont.woff2
new file mode 100644 (file)
index 0000000..cae03de
Binary files /dev/null and b/koha-tmpl/opac-tmpl/bootstrap/css/fonts/NotoSans-Regular-webfont.woff2 differ
index 1de79ca..398b6c1 100644 (file)
@@ -1,11 +1,52 @@
 @import "mixins";
 
+@font-face {
+    font-family: 'NotoSans';
+    font-style: normal;
+    font-weight: 400;
+    src: local('Noto Sans Regular'),
+        url('fonts/NotoSans-Regular-webfont.woff2') format('woff2'),
+        url('fonts/NotoSans-Regular-webfont.woff') format('woff');
+}
+
+@font-face {
+    font-family: 'NotoSans';
+    font-style: bold;
+    font-weight: 700;
+    src: local('Noto Sans Bold'),
+        url('fonts/NotoSans-Bold-webfont.woff2') format('woff2'),
+        url('fonts/NotoSans-Bold-webfont.woff') format('woff');
+}
+
+@font-face {
+    font-family: 'NotoSans';
+    font-style: italic;
+    font-weight: 400;
+    src: local('Noto Sans Italic'),
+        url('fonts/NotoSans-Italic-webfont.woff2') format('woff2'),
+        url('fonts/NotoSans-Italic-webfont.woff') format('woff');
+}
+
+@font-face {
+    font-family: 'NotoSans';
+    font-style: italic;
+    font-weight: 700;
+    src: local('Noto Sans Bold Italic'),
+        url('fonts/NotoSans-BoldItalic-webfont.woff2') format('woff2'),
+        url('fonts/NotoSans-BoldItalic-webfont.woff') format('woff');
+}
+
+
 body {
     background: #FCF9FC none;
-    font-family: 'NotoSansRegular';
+    font-family: sans-serif;
     font-size: 16px;
 }
 
+.fonts-loaded body {
+    font-family: 'NotoSans';
+}
+
 /* Sticky footer styles */
 html,
 body {
@@ -414,7 +455,7 @@ th {
         background-color: #85ca11;
         color: #FFF;
         display: inline;
-        font-family: 'NotoSansRegular';
+        font-family: 'NotoSans';
         font-size: 80%;
         font-weight: normal;
         margin: 0 0 0 .9em;
@@ -659,7 +700,7 @@ th {
     background-color: #85ca11;
     background-image: linear-gradient(to bottom, #85ca11, #77b50f);
     background-position: 0;
-    font-family: 'NotoSansRegular';
+    font-family: 'NotoSans';
     &:hover {
         background-color: #85ca11;
         background-image: linear-gradient(to bottom, #85ca11, #77b50f);
@@ -726,6 +767,7 @@ input[type="text"]:focus {
             > a {
                 color: #727272;
                 font-weight: bold;
+                text-shadow: none;
                 &:hover {
                     color: #85ca11;
                 }
@@ -819,7 +861,7 @@ input[type="text"]:focus {
 .ui-widget select,
 .ui-widget textarea,
 .ui-widget button {
-    font-family: 'NotoSansRegular';
+    font-family: 'NotoSans';
     font-size: inherit;
 }
 
index bb6da32..4dfd532 100644 (file)
     [% Asset.css("lib/jquery/jquery-ui.css") | $raw %]
 [% END %]
 
-<!--Fonts -->
-<link rel="stylesheet" media="screen" href="https://fontlibrary.org/face/noto-sans-condensed" type="text/css"/>
-<link rel="stylesheet" media="screen" href="https://fontlibrary.org/face/noto-sans-normal" type="text/css"/>
-
 [% SET opaclayoutstylesheet='opac_' _ KOHA_VERSION _ '.css' UNLESS opaclayoutstylesheet %]
 [% IF (opaclayoutstylesheet.match('^https?:|^\/')) %]
     <link rel="stylesheet" type="text/css" href="[% opaclayoutstylesheet | html %]" />
index 20d92f7..3f374b5 100644 (file)
@@ -87,6 +87,7 @@
 $.widget.bridge('uitooltip', $.ui.tooltip);
 </script>
 [% Asset.js("lib/bootstrap/js/bootstrap.min.js") | $raw %]
+[% Asset.js("lib/fontfaceobserver.min.js") | $raw %]
 [% Asset.js("js/global.js") | $raw %]
 <script>
     Modernizr.load([
index 402026a..8de2e70 100644 (file)
@@ -1,3 +1,19 @@
+(function( w ){
+    // if the class is already set, the font has already been loaded
+    if( w.document.documentElement.className.indexOf( "fonts-loaded" ) > -1 ){
+        return;
+    }
+    var PrimaryFont = new w.FontFaceObserver( "NotoSans", {
+        weight: 400
+    });
+
+    PrimaryFont.load(null, 5000).then(function(){
+        w.document.documentElement.className += " fonts-loaded";
+    }, function(){
+        console.log("Failed");
+    });
+}( this ));
+
 // http://stackoverflow.com/questions/1038746/equivalent-of-string-format-in-jquery/5341855#5341855
 String.prototype.format = function() { return formatstr(this, arguments) }
 function formatstr(str, col) {
diff --git a/koha-tmpl/opac-tmpl/bootstrap/lib/fontfaceobserver.min.js b/koha-tmpl/opac-tmpl/bootstrap/lib/fontfaceobserver.min.js
new file mode 100644 (file)
index 0000000..8767ed0
--- /dev/null
@@ -0,0 +1,12 @@
+/* Font Face Observer v2.0.13 - © Bram Stein. License: BSD-3-Clause */(function(){'use strict';var f,g=[];function l(a){g.push(a);1==g.length&&f()}function m(){for(;g.length;)g[0](),g.shift()}f=function(){setTimeout(m)};function n(a){this.a=p;this.b=void 0;this.f=[];var b=this;try{a(function(a){q(b,a)},function(a){r(b,a)})}catch(c){r(b,c)}}var p=2;function t(a){return new n(function(b,c){c(a)})}function u(a){return new n(function(b){b(a)})}function q(a,b){if(a.a==p){if(b==a)throw new TypeError;var c=!1;try{var d=b&&b.then;if(null!=b&&"object"==typeof b&&"function"==typeof d){d.call(b,function(b){c||q(a,b);c=!0},function(b){c||r(a,b);c=!0});return}}catch(e){c||r(a,e);return}a.a=0;a.b=b;v(a)}}
+function r(a,b){if(a.a==p){if(b==a)throw new TypeError;a.a=1;a.b=b;v(a)}}function v(a){l(function(){if(a.a!=p)for(;a.f.length;){var b=a.f.shift(),c=b[0],d=b[1],e=b[2],b=b[3];try{0==a.a?"function"==typeof c?e(c.call(void 0,a.b)):e(a.b):1==a.a&&("function"==typeof d?e(d.call(void 0,a.b)):b(a.b))}catch(h){b(h)}}})}n.prototype.g=function(a){return this.c(void 0,a)};n.prototype.c=function(a,b){var c=this;return new n(function(d,e){c.f.push([a,b,d,e]);v(c)})};
+function w(a){return new n(function(b,c){function d(c){return function(d){h[c]=d;e+=1;e==a.length&&b(h)}}var e=0,h=[];0==a.length&&b(h);for(var k=0;k<a.length;k+=1)u(a[k]).c(d(k),c)})}function x(a){return new n(function(b,c){for(var d=0;d<a.length;d+=1)u(a[d]).c(b,c)})};window.Promise||(window.Promise=n,window.Promise.resolve=u,window.Promise.reject=t,window.Promise.race=x,window.Promise.all=w,window.Promise.prototype.then=n.prototype.c,window.Promise.prototype["catch"]=n.prototype.g);}());
+
+(function(){function l(a,b){document.addEventListener?a.addEventListener("scroll",b,!1):a.attachEvent("scroll",b)}function m(a){document.body?a():document.addEventListener?document.addEventListener("DOMContentLoaded",function c(){document.removeEventListener("DOMContentLoaded",c);a()}):document.attachEvent("onreadystatechange",function k(){if("interactive"==document.readyState||"complete"==document.readyState)document.detachEvent("onreadystatechange",k),a()})};function r(a){this.a=document.createElement("div");this.a.setAttribute("aria-hidden","true");this.a.appendChild(document.createTextNode(a));this.b=document.createElement("span");this.c=document.createElement("span");this.h=document.createElement("span");this.f=document.createElement("span");this.g=-1;this.b.style.cssText="max-width:none;display:inline-block;position:absolute;height:100%;width:100%;overflow:scroll;font-size:16px;";this.c.style.cssText="max-width:none;display:inline-block;position:absolute;height:100%;width:100%;overflow:scroll;font-size:16px;";
+this.f.style.cssText="max-width:none;display:inline-block;position:absolute;height:100%;width:100%;overflow:scroll;font-size:16px;";this.h.style.cssText="display:inline-block;width:200%;height:200%;font-size:16px;max-width:none;";this.b.appendChild(this.h);this.c.appendChild(this.f);this.a.appendChild(this.b);this.a.appendChild(this.c)}
+function t(a,b){a.a.style.cssText="max-width:none;min-width:20px;min-height:20px;display:inline-block;overflow:hidden;position:absolute;width:auto;margin:0;padding:0;top:-999px;white-space:nowrap;font-synthesis:none;font:"+b+";"}function y(a){var b=a.a.offsetWidth,c=b+100;a.f.style.width=c+"px";a.c.scrollLeft=c;a.b.scrollLeft=a.b.scrollWidth+100;return a.g!==b?(a.g=b,!0):!1}function z(a,b){function c(){var a=k;y(a)&&a.a.parentNode&&b(a.g)}var k=a;l(a.b,c);l(a.c,c);y(a)};function A(a,b){var c=b||{};this.family=a;this.style=c.style||"normal";this.weight=c.weight||"normal";this.stretch=c.stretch||"normal"}var B=null,C=null,E=null,F=null;function G(){if(null===C)if(J()&&/Apple/.test(window.navigator.vendor)){var a=/AppleWebKit\/([0-9]+)(?:\.([0-9]+))(?:\.([0-9]+))/.exec(window.navigator.userAgent);C=!!a&&603>parseInt(a[1],10)}else C=!1;return C}function J(){null===F&&(F=!!document.fonts);return F}
+function K(){if(null===E){var a=document.createElement("div");try{a.style.font="condensed 100px sans-serif"}catch(b){}E=""!==a.style.font}return E}function L(a,b){return[a.style,a.weight,K()?a.stretch:"","100px",b].join(" ")}
+A.prototype.load=function(a,b){var c=this,k=a||"BESbswy",q=0,D=b||3E3,H=(new Date).getTime();return new Promise(function(a,b){if(J()&&!G()){var M=new Promise(function(a,b){function e(){(new Date).getTime()-H>=D?b():document.fonts.load(L(c,'"'+c.family+'"'),k).then(function(c){1<=c.length?a():setTimeout(e,25)},function(){b()})}e()}),N=new Promise(function(a,c){q=setTimeout(c,D)});Promise.race([N,M]).then(function(){clearTimeout(q);a(c)},function(){b(c)})}else m(function(){function u(){var b;if(b=-1!=
+f&&-1!=g||-1!=f&&-1!=h||-1!=g&&-1!=h)(b=f!=g&&f!=h&&g!=h)||(null===B&&(b=/AppleWebKit\/([0-9]+)(?:\.([0-9]+))/.exec(window.navigator.userAgent),B=!!b&&(536>parseInt(b[1],10)||536===parseInt(b[1],10)&&11>=parseInt(b[2],10))),b=B&&(f==v&&g==v&&h==v||f==w&&g==w&&h==w||f==x&&g==x&&h==x)),b=!b;b&&(d.parentNode&&d.parentNode.removeChild(d),clearTimeout(q),a(c))}function I(){if((new Date).getTime()-H>=D)d.parentNode&&d.parentNode.removeChild(d),b(c);else{var a=document.hidden;if(!0===a||void 0===a)f=e.a.offsetWidth,
+g=n.a.offsetWidth,h=p.a.offsetWidth,u();q=setTimeout(I,50)}}var e=new r(k),n=new r(k),p=new r(k),f=-1,g=-1,h=-1,v=-1,w=-1,x=-1,d=document.createElement("div");d.dir="ltr";t(e,L(c,"sans-serif"));t(n,L(c,"serif"));t(p,L(c,"monospace"));d.appendChild(e.a);d.appendChild(n.a);d.appendChild(p.a);document.body.appendChild(d);v=e.a.offsetWidth;w=n.a.offsetWidth;x=p.a.offsetWidth;I();z(e,function(a){f=a;u()});t(e,L(c,'"'+c.family+'",sans-serif'));z(n,function(a){g=a;u()});t(n,L(c,'"'+c.family+'",serif'));
+z(p,function(a){h=a;u()});t(p,L(c,'"'+c.family+'",monospace'))})})};"object"===typeof module?module.exports=A:(window.FontFaceObserver=A,window.FontFaceObserver.prototype.load=A.prototype.load);}());