webfontloader 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/Gemfile +9 -0
  2. data/LICENSE +201 -0
  3. data/README.md +148 -0
  4. data/Rakefile +243 -0
  5. data/bin/webfontloader-demos +28 -0
  6. data/docs/EVENTS.md +115 -0
  7. data/docs/MODULES.md +49 -0
  8. data/docs/TRANSITIONS.md +107 -0
  9. data/lib/webfontloader.rb +10 -0
  10. data/lib/webfontloader/demo/public/ascender.html +99 -0
  11. data/lib/webfontloader/demo/public/basic.css +9 -0
  12. data/lib/webfontloader/demo/public/custom.html +88 -0
  13. data/lib/webfontloader/demo/public/event-css-active-multiple.html +44 -0
  14. data/lib/webfontloader/demo/public/event-css-active.html +38 -0
  15. data/lib/webfontloader/demo/public/event-css-inactive.html +38 -0
  16. data/lib/webfontloader/demo/public/event-css-loading.html +55 -0
  17. data/lib/webfontloader/demo/public/event-js-active.html +39 -0
  18. data/lib/webfontloader/demo/public/event-js-font-active.html +40 -0
  19. data/lib/webfontloader/demo/public/event-js-loading.html +60 -0
  20. data/lib/webfontloader/demo/public/events-variations.html +130 -0
  21. data/lib/webfontloader/demo/public/events.html +103 -0
  22. data/lib/webfontloader/demo/public/google-css.html +27 -0
  23. data/lib/webfontloader/demo/public/google.html +33 -0
  24. data/lib/webfontloader/demo/public/ie-fast-js.html +47 -0
  25. data/lib/webfontloader/demo/public/ie-slow-js.html +48 -0
  26. data/lib/webfontloader/demo/public/ie-slow-link.html +38 -0
  27. data/lib/webfontloader/demo/public/index.html +70 -0
  28. data/lib/webfontloader/demo/public/typekit-variations.html +50 -0
  29. data/lib/webfontloader/demo/public/typekit.html +41 -0
  30. data/lib/webfontloader/demo/server.rb +92 -0
  31. data/lib/webfontloader/modules.rb +44 -0
  32. data/src-test/ascender/ascender_script_test.js +48 -0
  33. data/src-test/core/cssclassnametest.js +42 -0
  34. data/src-test/core/cssfontfamilynametest.js +54 -0
  35. data/src-test/core/domhelpertest.js +81 -0
  36. data/src-test/core/eventdispatchertest.js +99 -0
  37. data/src-test/core/fontmoduleloadertest.js +30 -0
  38. data/src-test/core/fonttest.js +92 -0
  39. data/src-test/core/fontvariationdescriptiontest.js +76 -0
  40. data/src-test/core/fontwatchertest.js +510 -0
  41. data/src-test/core/useragenttest.js +395 -0
  42. data/src-test/custom/customcsstest.js +30 -0
  43. data/src-test/google/fontapiparsertest.js +92 -0
  44. data/src-test/google/fontapiurlbuildertest.js +28 -0
  45. data/src-test/google/googlefontapitest.js +173 -0
  46. data/src-test/typekit/typekit_script_test.js +171 -0
  47. data/src/ascender/ascender_script.js +84 -0
  48. data/src/async_load.js +3 -0
  49. data/src/closure.js +3 -0
  50. data/src/core/cssclassname.js +21 -0
  51. data/src/core/cssfontfamilyname.js +20 -0
  52. data/src/core/domhelper.js +103 -0
  53. data/src/core/eventdispatcher.js +78 -0
  54. data/src/core/font.js +84 -0
  55. data/src/core/fontmoduleloader.js +25 -0
  56. data/src/core/fontvariationdescription.js +112 -0
  57. data/src/core/fontwatcher.js +121 -0
  58. data/src/core/initialize.js +26 -0
  59. data/src/core/namespace.js +11 -0
  60. data/src/core/useragent.js +41 -0
  61. data/src/core/useragentparser.js +234 -0
  62. data/src/custom/customcss.js +37 -0
  63. data/src/google/fontapiparser.js +94 -0
  64. data/src/google/fontapiurlbuilder.js +39 -0
  65. data/src/google/googlefontapi.js +49 -0
  66. data/src/modules.yml +27 -0
  67. data/src/typekit/typekit_script.js +58 -0
  68. data/tools/compiler/compiler.jar +0 -0
  69. data/tools/jstestdriver/JsTestDriver-1.2.1.jar +0 -0
  70. data/webfontloader.gemspec +144 -0
  71. metadata +191 -0
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+
5
+ $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + "/../lib")
6
+ require 'webfontloader'
7
+
8
+ begin
9
+ require 'webfontloader/demo/server'
10
+ rescue LoadError => e
11
+ abort "Please gem install sinatra"
12
+ end
13
+
14
+ begin
15
+ require 'vegas'
16
+ rescue LoadError => e
17
+ abort "Please gem install vegas"
18
+ end
19
+
20
+ Vegas::Runner.new(WebFontLoader::Demo::Server, 'font-demos') do |runner, opts, app|
21
+ opts.on('--compiled_js FILE', "Dynamically build the JS with the given modules") { |file|
22
+ app.set :compiled_js, File.read(file)
23
+ }
24
+ opts.on('--modules [MODULES]', "Dynamically build the JS with the given modules") { |opt_modules|
25
+ modules = opt_modules ? opt_modules.split(",") : []
26
+ app.set :modules, WebFontLoader::Modules.new(*modules)
27
+ }
28
+ end
data/docs/EVENTS.md ADDED
@@ -0,0 +1,115 @@
1
+ # Events
2
+
3
+ WebFont Loader provides an event system that developers can hook into. It
4
+ gives you notifications of the font loading sequence in both CSS and
5
+ JavaScript.
6
+
7
+ ## The Events
8
+
9
+ * `Loading` - This event is triggered when all fonts have been requested.
10
+ * `Active` - This event is triggered when all of the fonts have rendered.
11
+ * `Inactive` - This event is triggered when the browser does not support
12
+ linked fonts *or* if none of the fonts could be loaded.
13
+ * `Font Loading` - This event is triggered once for each font that's loaded.
14
+ * `Font Active` - This event is triggered once for each font that renders.
15
+ * `Font Inactive` - This event is triggered if the font can't be loaded.
16
+
17
+ ### CSS Flavored
18
+
19
+ CSS events are implemented as classes on the `html` element.
20
+
21
+ html.wf-loading
22
+ html.wf-active
23
+ html.wf-inactive
24
+ html.wf-familyname-fvd-loading
25
+ html.wf-familyname-fvd-active
26
+ html.wf-familyname-fvd-inactive
27
+
28
+ `familyname` is a sanitized version of the name of each font family. Spaces
29
+ and underscores are removed from the name, and all characters are converted to
30
+ lower case. For example, `Droid Sans` becomes `droidsans`.
31
+
32
+ `fvd` is a *Font Variation Description*. Put simply, it's a shorthand for
33
+ describing the style and weight of a particular font. Here are a few examples:
34
+
35
+ @font-face {
36
+ font-style: normal;
37
+ font-weight: normal;
38
+ }
39
+ => n4
40
+
41
+ @font-face {
42
+ font-style: italic;
43
+ font-weight: bold;
44
+ }
45
+ => i7
46
+
47
+ If no style/weight is specified, the default "n4" (font-style: normal;
48
+ font-weight: normal;) will be used.
49
+
50
+
51
+ ### JavaScript Flavored
52
+
53
+ JavaScript events are implemented as callback functions on the `WebFont.load`
54
+ function.
55
+
56
+ WebFont.load({
57
+ loading: function() {
58
+ },
59
+ active: function() {
60
+ },
61
+ inactive: function() {
62
+ },
63
+ fontloading: function(familyName, fvd) {
64
+ },
65
+ fontactive: function(familyName, fvd) {
66
+ },
67
+ fontinactive: function(familyName, fvd) {
68
+ }
69
+ })
70
+
71
+
72
+ ## Error Handling
73
+
74
+ ### Timeouts
75
+
76
+ Since the Internet is not 100% reliable, it's possible that a font fails to
77
+ load. You can use events to gracefully degrade in this situation.
78
+
79
+ > The `Font Inactive` event will be triggered after 5 seconds if the font
80
+ fails to render. If *at least* one font succesfully renders, the `Active`
81
+ event will be triggered, else the `Inative` even will be triggered.
82
+
83
+ ### Browser Support
84
+
85
+ Every web browser has varying levels of support for fonts linked via
86
+ @font-face.
87
+
88
+ > If WebFont Loader determines that the current browser does not support
89
+ `@font-face`, the `Inactive` event will be triggered.
90
+
91
+ When loading fonts from multiple providers, each provider may or may not
92
+ support a given browser.
93
+
94
+ > If WebFont Loader determines that the current browser can support
95
+ `@font-face`, and *at least* one provider is able to serve fonts,
96
+ the fonts from that provide will be loaded. When finished, the `Active` event
97
+ will be triggered.
98
+
99
+ > For fonts loaded from supported providers, the `Font Active` event will be
100
+ triggered. For fonts loaded from a provider that *does not* support the
101
+ current browser, the `Font Inactive` event will be triggered.
102
+
103
+ For example:
104
+
105
+ WebFont.load({
106
+ providerA: 'Family1',
107
+ providerB: 'Family2'
108
+ });
109
+
110
+ > If `providerA` can serve fonts to a browser, but `providerB` cannot, The
111
+ `Font Inactive` event will be triggered for `Family2`. The `Font Active`
112
+ event will be triggered for `Family1` once it loads, as will the `Active`
113
+ event.
114
+
115
+
data/docs/MODULES.md ADDED
@@ -0,0 +1,49 @@
1
+ # Modules
2
+
3
+ WebFont Loader provides a generic module system so that any web font provider
4
+ may be used. The specifics of each provider are documented here.
5
+
6
+
7
+ ## Google
8
+
9
+ Using Google's Font API, name the font families you'd like to load.
10
+
11
+ WebFont.load({
12
+ google: {
13
+ families: ['Droid Sans', 'Droid Serif']
14
+ }
15
+ });
16
+
17
+ Learn more about the [Google Font API][gfontapi].
18
+
19
+
20
+ ## Typekit
21
+
22
+ When using Typekit, specify the Kit to retrieve by its ID. You can find this
23
+ ID within Typekit's Kit Editor interface.
24
+
25
+ WebFont.load({
26
+ typekit: {
27
+ id: 'xxxxxx'
28
+ }
29
+ });
30
+
31
+ Learn more about [Typekit][tk].
32
+
33
+
34
+ ## Custom
35
+
36
+ To load fonts from any external stylesheet, use the `custom` module. Here you'll
37
+ need to specify both the url of the stylesheet as well as the font families it
38
+ provides.
39
+
40
+ WebFont.load({
41
+ custom: {
42
+ families: ['My Font', 'My Other Font'],
43
+ urls: ['/fonts.css']
44
+ }
45
+ });
46
+
47
+
48
+ [gfontapi]: https://code.google.com/apis/webfonts/docs/getting_started.html
49
+ [tk]: http://typekit.com/
@@ -0,0 +1,107 @@
1
+ # Transitions
2
+
3
+ In order to support smooth transitions between webfont providers, WebFont
4
+ Loader provides a common interface to each provider. It also makes it trivial
5
+ to load fonts from multiple providers.
6
+
7
+ This is especially powerful when building your page against the [events][]
8
+ because the same events are triggered regardless of the provider.
9
+
10
+ Here are a few scenarios.
11
+
12
+ ## From Google Fonts to Typekit
13
+
14
+ ### Step 1: Use Google with WebFont Loader
15
+
16
+ You can get started with web fonts quickly and easily by just using Google.
17
+
18
+ <script type="text/javascript" src="http://www.google.com/jsapi"></script>
19
+ <script type="text/javascript">
20
+ WebFont.load({
21
+ google: {
22
+ families: ['Droid Sans']
23
+ }
24
+ });
25
+ </script>
26
+
27
+ ### Step 2: Add Typekit
28
+
29
+ If you discover that Google doesn't have your preferred typeface, you may wish
30
+ to add fonts from Typekit.
31
+
32
+ (first sign up for Typekit, add fonts and retrieve your Kit ID)
33
+
34
+ <script type="text/javascript" src="http://www.google.com/jsapi"></script>
35
+ <script type="text/javascript">
36
+ WebFont.load({
37
+ google: {
38
+ families: ['Droid Sans']
39
+ },
40
+ typekit: {
41
+ id: 'abc1def'
42
+ }
43
+ });
44
+ </script>
45
+
46
+ ### Step 3 Remove Google
47
+
48
+ You may now discover that the number of HTTP requests has increased by pulling
49
+ fonts from both Google and Typekit. Since Typekit has all of the fonts that
50
+ Google has, let's drop that dependency.
51
+
52
+ (first add 'Droid Sans' to your Kit with ID 'abc1def')
53
+
54
+ <script type="text/javascript" src="http://www.google.com/jsapi"></script>
55
+ <script type="text/javascript">
56
+ WebFont.load({,
57
+ typekit: {
58
+ id: 'abc1def'
59
+ }
60
+ });
61
+ </script>
62
+
63
+ ### Step 4: Remove WebFont Loader
64
+
65
+ You may wish to reduce HTTP requests further by dropping the dependency on
66
+ WebFont Loader to work directly with Typekit. Typekit's API is fully
67
+ compatible with WebFont Loader.
68
+
69
+ <script type="text/javascript" src="http://use.typekit.com/abc1def.js"></script>
70
+ <script type="text/javascript">
71
+ WebFont.load();
72
+ </script>
73
+
74
+ Or as pure Typekit
75
+
76
+ <script type="text/javascript" src="http://use.typekit.com/abc1def.js"></script>
77
+ <script type="text/javascript">
78
+ Typekit.load();
79
+ </script>
80
+
81
+
82
+ ## Add events to self-hosted fonts
83
+
84
+ ### Step 1: Link to your own stylesheet
85
+
86
+ If you already have fonts and the `@font-face` rules written, you might
87
+ already be using them in your page.
88
+
89
+ <link type="text/css" rel="stylesheet" href="/fonts.css">
90
+
91
+ ### Step 2: Use WebFont Loader
92
+
93
+ To add [events][] support, use the `custom` module to load your stylesheet,
94
+ and name the font families that the stylesheet provides.
95
+
96
+ <script type="text/javascript" src="http://www.google.com/jsapi"></script>
97
+ <script type="text/javascript">
98
+ WebFont.load({
99
+ default: {
100
+ families: ['My Font'],
101
+ urls: ['/fonts.css']
102
+ }
103
+ });
104
+ </script>
105
+
106
+
107
+ [events]: EVENTS.md
@@ -0,0 +1,10 @@
1
+ require 'yaml'
2
+
3
+ require 'webfontloader/modules'
4
+
5
+ module WebFontLoader
6
+ VERSION = '1.0.5'
7
+
8
+ ProjectRoot = File.expand_path(File.dirname(__FILE__) + "/..")
9
+
10
+ end
@@ -0,0 +1,99 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <title>Ascender Module Demo</title>
5
+ <link href="/basic.css" rel="stylesheet" type="text/css">
6
+ <script type="text/javascript" src="/webfont.js"></script>
7
+ <style type="text/css">
8
+ /* Use classes to prove that Ascender module triggers the event system correctly */
9
+ #demo {
10
+ visibility: hidden;
11
+ line-height:normal;
12
+ }
13
+ .wf-ayitapro-n4-active #demo {
14
+ font-family: 'AyitaPro';
15
+ visibility: visible;
16
+ }
17
+ </style>
18
+ </head>
19
+ <body>
20
+ <div id="demo">
21
+ <h1>Hello World. I am Ayita Pro.</h1>
22
+
23
+ <h2>Regular:</h2>
24
+ <p style="font-weight:normal; font-style:normal;">
25
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur tempus eleifend aliquam. Nullam eu volutpat orci. Sed scelerisque pulvinar lorem, non ornare risus varius sed. Integer in lorem ut tortor rutrum placerat. Duis quis ante nec nulla luctus tincidunt. Aenean lorem metus, venenatis id sagittis eget, sodales ut justo. Donec quis dictum erat. Nunc ac feugiat sapien. In laoreet nisl in nisl ullamcorper porttitor. Ut vitae tortor leo, nec euismod sapien. Vivamus pellentesque, est in vulputate dictum, lectus diam interdum ipsum, sit amet posuere libero dui et sapien. Curabitur sit amet pulvinar massa.
26
+ </p>
27
+
28
+ <h2>Bold:</h2>
29
+ <p style="font-weight:bold; font-style:normal;">
30
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur tempus eleifend aliquam. Nullam eu volutpat orci. Sed scelerisque pulvinar lorem, non ornare risus varius sed. Integer in lorem ut tortor rutrum placerat. Duis quis ante nec nulla luctus tincidunt. Aenean lorem metus, venenatis id sagittis eget, sodales ut justo. Donec quis dictum erat. Nunc ac feugiat sapien. In laoreet nisl in nisl ullamcorper porttitor. Ut vitae tortor leo, nec euismod sapien. Vivamus pellentesque, est in vulputate dictum, lectus diam interdum ipsum, sit amet posuere libero dui et sapien. Curabitur sit amet pulvinar massa.
31
+ </p>
32
+
33
+ <h2>Italic:</h2>
34
+ <p style="font-weight:normal; font-style:italic;">
35
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur tempus eleifend aliquam. Nullam eu volutpat orci. Sed scelerisque pulvinar lorem, non ornare risus varius sed. Integer in lorem ut tortor rutrum placerat. Duis quis ante nec nulla luctus tincidunt. Aenean lorem metus, venenatis id sagittis eget, sodales ut justo. Donec quis dictum erat. Nunc ac feugiat sapien. In laoreet nisl in nisl ullamcorper porttitor. Ut vitae tortor leo, nec euismod sapien. Vivamus pellentesque, est in vulputate dictum, lectus diam interdum ipsum, sit amet posuere libero dui et sapien. Curabitur sit amet pulvinar massa.
36
+ </p>
37
+
38
+ <h2>Bold Italic:</h2>
39
+ <p style="font-weight:bold; font-style:italic;">
40
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur tempus eleifend aliquam. Nullam eu volutpat orci. Sed scelerisque pulvinar lorem, non ornare risus varius sed. Integer in lorem ut tortor rutrum placerat. Duis quis ante nec nulla luctus tincidunt. Aenean lorem metus, venenatis id sagittis eget, sodales ut justo. Donec quis dictum erat. Nunc ac feugiat sapien. In laoreet nisl in nisl ullamcorper porttitor. Ut vitae tortor leo, nec euismod sapien. Vivamus pellentesque, est in vulputate dictum, lectus diam interdum ipsum, sit amet posuere libero dui et sapien. Curabitur sit amet pulvinar massa.
41
+ </p>
42
+ </div>
43
+ <hr>
44
+ <p>
45
+ <a href="#" onclick="document.getElementsByTagName('body')[0].style.color = '#fff';return false;">Hide Page</a> |
46
+ <a href="/ascender.html">Reload Cached</a>
47
+ </p>
48
+ <p>
49
+ Note: use "localhost" when testing web fonts.
50
+ </p>
51
+ <p>
52
+ The goal of this page is to show how fonts load from Ascender.
53
+ </p>
54
+ <h2>JavaScript Event Progress</h2>
55
+ <ol id="events"></ol>
56
+
57
+ <script type="text/javascript">
58
+ function progress(message) {
59
+ var output = document.getElementById('events');
60
+ if (output) {
61
+ var e = document.createElement('li');
62
+ e.innerHTML = message;
63
+ output.appendChild(e);
64
+ }
65
+ if (window.console && window.console.log) {
66
+ window.console.log(message);
67
+ }
68
+ }
69
+
70
+ //Families must match families
71
+ //that are included in provided CSS
72
+ WebFont.load({
73
+ ascender: {
74
+ key:'ec2de397-11ae-4c10-937f-bf94283a70c1',
75
+ families:['AyitaPro:regular,bold,bolditalic,italic']
76
+ },
77
+ loading: function() {
78
+ progress('loading');
79
+ },
80
+ active: function() {
81
+ progress('active');
82
+ },
83
+ inactive: function() {
84
+ progress('inactive');
85
+ },
86
+ fontloading: function(fontFamily, fontDescription) {
87
+ progress('fontloading: ' + fontFamily + ' (' + fontDescription + ')');
88
+ },
89
+ fontactive: function(fontFamily, fontDescription) {
90
+ progress('fontactive: ' + fontFamily + ' (' + fontDescription + ')');
91
+ },
92
+ fontinactive: function(fontFamily, fontDescription) {
93
+ progress('fontinactive: ' + fontFamily + ' (' + fontDescription + ')');
94
+ }
95
+ });
96
+ </script>
97
+
98
+ </body>
99
+ </html>
@@ -0,0 +1,9 @@
1
+ body {
2
+ line-height: 1;
3
+ font-size: 14px;
4
+ margin: 10px;
5
+ }
6
+ h1 {
7
+ font-size: 5em;
8
+ margin: 0;
9
+ }
@@ -0,0 +1,88 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <title>Custom Module</title>
5
+ <script type="text/javascript" src="/webfont.js"></script>
6
+ <style type="text/css">
7
+
8
+ h1 {
9
+ font-family: 'Tagesschrift';
10
+ }
11
+
12
+ /* All Class hooks */
13
+ #classes { color: #ddd; }
14
+ html.wf-loading #classes .Loading,
15
+ html.wf-active #classes .Active,
16
+ html.wf-inactive #classes .Inactive,
17
+ html.wf-tagesschrift-n4-loading #classes .TagesschriftLoading,
18
+ html.wf-tagesschrift-n4-active #classes .TagesschriftActive,
19
+ html.wf-tagesschrift-n4-inactive #classes .TagesschriftInactive {
20
+ color: #000;
21
+ }
22
+
23
+ </style>
24
+ </head>
25
+ <body>
26
+ <h1 class="tagesschrift">
27
+ Hello World. I am Tagesschrift.
28
+ </h1>
29
+ <hr>
30
+ <p>
31
+ <a href="#" onclick="document.getElementsByTagName('body')[0].style.color = '#fff';return false;">Hide Page</a> |
32
+ <a href="/custom.html">Reload Cached</a>
33
+ </p>
34
+ <p>
35
+ The goal of this page is to show how fonts load from a custom module.
36
+ </p>
37
+ <h2>CSS Hook Status</h2>
38
+ <ul id="classes">
39
+ <li class="Loading">Loading</li>
40
+ <li class="Active">Active</li>
41
+ <li class="Inactive">Inactive</li>
42
+ <li class="TagesschriftLoading">Tagesschrift Loading</li>
43
+ <li class="TagesschriftActive">Tagesschrift Active</li>
44
+ <li class="TagesschriftInactive">Tagesschrift Inactive</li>
45
+ </ul>
46
+ <h2>JavaScript Event Progress</h2>
47
+ <ol id="events"></ol>
48
+
49
+ <!-- loading event may fire before page is completely ready -->
50
+ <script type="text/javascript">
51
+ function progress(message) {
52
+ var output = document.getElementById('events');
53
+ if (output) {
54
+ var e = document.createElement('li');
55
+ e.innerHTML = message;
56
+ output.appendChild(e);
57
+ }
58
+ if (window.console && window.console.log) {
59
+ window.console.log(message);
60
+ }
61
+ }
62
+ WebFont.load({
63
+ custom: {
64
+ families: ['Tagesschrift'],
65
+ urls : ['http://paulirish.com/tagesschrift.css']
66
+ },
67
+ loading: function() {
68
+ progress('loading');
69
+ },
70
+ active: function() {
71
+ progress('active');
72
+ },
73
+ inactive: function() {
74
+ progress('inactive');
75
+ },
76
+ fontloading: function(fontFamily, fontDescription) {
77
+ progress('fontloading: ' + fontFamily + ' (' + fontDescription + ')');
78
+ },
79
+ fontactive: function(fontFamily, fontDescription) {
80
+ progress('fontactive: ' + fontFamily + ' (' + fontDescription + ')');
81
+ },
82
+ fontinactive: function(fontFamily, fontDescription) {
83
+ progress('fontinactive: ' + fontFamily + ' (' + fontDescription + ')');
84
+ }
85
+ });
86
+ </script>
87
+ </body>
88
+ </html>