mtl 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/Gemfile +9 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +104 -0
  6. data/Rakefile +6 -0
  7. data/app/assets/javascripts/mtl/clickables.coffee +25 -0
  8. data/app/assets/javascripts/mtl/collapsible.coffee +43 -0
  9. data/app/assets/javascripts/mtl/configuration.coffee.erb +1 -0
  10. data/app/assets/javascripts/mtl/document_modal.coffee +130 -0
  11. data/app/assets/javascripts/mtl/dropdown.coffee +24 -0
  12. data/app/assets/javascripts/mtl/hooks.coffee +14 -0
  13. data/app/assets/javascripts/mtl/icon.coffee.erb +17 -0
  14. data/app/assets/javascripts/mtl/modal.coffee +32 -0
  15. data/app/assets/javascripts/mtl/select.coffee +44 -0
  16. data/app/assets/javascripts/mtl/templates.coffee +4 -0
  17. data/app/assets/javascripts/mtl/toc.coffee +31 -0
  18. data/app/assets/javascripts/mtl.js +42 -0
  19. data/app/assets/stylesheets/mtl/all.scss +69 -0
  20. data/app/assets/stylesheets/mtl/extend/_avatars.scss +37 -0
  21. data/app/assets/stylesheets/mtl/extend/_buttons.scss +31 -0
  22. data/app/assets/stylesheets/mtl/extend/_cards.scss +21 -0
  23. data/app/assets/stylesheets/mtl/extend/_chips.scss +3 -0
  24. data/app/assets/stylesheets/mtl/extend/_collection-files.scss +108 -0
  25. data/app/assets/stylesheets/mtl/extend/_document-modals.scss +95 -0
  26. data/app/assets/stylesheets/mtl/extend/_dropdown.scss +12 -0
  27. data/app/assets/stylesheets/mtl/extend/_forms.scss +66 -0
  28. data/app/assets/stylesheets/mtl/extend/_global.scss +77 -0
  29. data/app/assets/stylesheets/mtl/extend/_grid.scss +25 -0
  30. data/app/assets/stylesheets/mtl/extend/_material-icons.scss +37 -0
  31. data/app/assets/stylesheets/mtl/extend/_mixins.scss +10 -0
  32. data/app/assets/stylesheets/mtl/extend/_roboto-rails.scss +49 -0
  33. data/app/assets/stylesheets/mtl/extend/_side-nav.scss +22 -0
  34. data/app/assets/stylesheets/mtl/extend/_toc.scss +12 -0
  35. data/app/assets/stylesheets/mtl/extend/_typography.scss +32 -0
  36. data/app/assets/stylesheets/mtl/extend/forms/_input-fields.scss +50 -0
  37. data/app/assets/stylesheets/mtl/layouts/_default.scss +220 -0
  38. data/app/assets/stylesheets/mtl/layouts/_single.scss +25 -0
  39. data/app/views/mtl/header.html.erb +25 -0
  40. data/bin/coffeelint.rb +16 -0
  41. data/lib/generators/mtl/install_generator.rb +20 -0
  42. data/lib/generators/mtl/templates/_color.scss +410 -0
  43. data/lib/generators/mtl/templates/_variables.scss +330 -0
  44. data/lib/generators/mtl/templates/mtl.scss +8 -0
  45. data/lib/generators/mtl/templates/simple_form.rb +211 -0
  46. data/lib/mtl/rails/card_file_presenter.rb +70 -0
  47. data/lib/mtl/rails/view_helpers.rb +412 -0
  48. data/lib/mtl/simple_form/suffix.rb +52 -0
  49. data/lib/mtl/version.rb +6 -0
  50. data/lib/mtl.rb +38 -0
  51. data/mtl.gemspec +35 -0
  52. data/package.json +11 -0
  53. data/spec/mtl/rails/card_file_presenter_spec.rb +126 -0
  54. data/spec/mtl/rails/view_helpers_spec.rb +193 -0
  55. data/spec/mtl/simple_form/suffix_spec.rb +39 -0
  56. data/spec/mtl_spec.rb +34 -0
  57. data/spec/spec_helper.rb +18 -0
  58. data/spec/support/dom.rb +15 -0
  59. data/vendor/assets/fonts/material-icons/MaterialIcons-Regular.eot +0 -0
  60. data/vendor/assets/fonts/material-icons/MaterialIcons-Regular.ijmap +1 -0
  61. data/vendor/assets/fonts/material-icons/MaterialIcons-Regular.svg +2373 -0
  62. data/vendor/assets/fonts/material-icons/MaterialIcons-Regular.ttf +0 -0
  63. data/vendor/assets/fonts/material-icons/MaterialIcons-Regular.woff +0 -0
  64. data/vendor/assets/fonts/material-icons/MaterialIcons-Regular.woff2 +0 -0
  65. data/vendor/assets/fonts/roboto/Roboto-Bold.eot +0 -0
  66. data/vendor/assets/fonts/roboto/Roboto-Bold.ttf +0 -0
  67. data/vendor/assets/fonts/roboto/Roboto-Bold.woff +0 -0
  68. data/vendor/assets/fonts/roboto/Roboto-Bold.woff2 +0 -0
  69. data/vendor/assets/fonts/roboto/Roboto-Light.eot +0 -0
  70. data/vendor/assets/fonts/roboto/Roboto-Light.ttf +0 -0
  71. data/vendor/assets/fonts/roboto/Roboto-Light.woff +0 -0
  72. data/vendor/assets/fonts/roboto/Roboto-Light.woff2 +0 -0
  73. data/vendor/assets/fonts/roboto/Roboto-Medium.eot +0 -0
  74. data/vendor/assets/fonts/roboto/Roboto-Medium.ttf +0 -0
  75. data/vendor/assets/fonts/roboto/Roboto-Medium.woff +0 -0
  76. data/vendor/assets/fonts/roboto/Roboto-Medium.woff2 +0 -0
  77. data/vendor/assets/fonts/roboto/Roboto-Regular.eot +0 -0
  78. data/vendor/assets/fonts/roboto/Roboto-Regular.ttf +0 -0
  79. data/vendor/assets/fonts/roboto/Roboto-Regular.woff +0 -0
  80. data/vendor/assets/fonts/roboto/Roboto-Regular.woff2 +0 -0
  81. data/vendor/assets/fonts/roboto/Roboto-Thin.eot +0 -0
  82. data/vendor/assets/fonts/roboto/Roboto-Thin.ttf +0 -0
  83. data/vendor/assets/fonts/roboto/Roboto-Thin.woff +0 -0
  84. data/vendor/assets/fonts/roboto/Roboto-Thin.woff2 +0 -0
  85. data/vendor/assets/javascripts/lodash.js +16607 -0
  86. data/vendor/assets/javascripts/materialize/animation.js +9 -0
  87. data/vendor/assets/javascripts/materialize/buttons.js +91 -0
  88. data/vendor/assets/javascripts/materialize/cards.js +26 -0
  89. data/vendor/assets/javascripts/materialize/carousel.js +454 -0
  90. data/vendor/assets/javascripts/materialize/character_counter.js +72 -0
  91. data/vendor/assets/javascripts/materialize/chips.js +267 -0
  92. data/vendor/assets/javascripts/materialize/collapsible.js +160 -0
  93. data/vendor/assets/javascripts/materialize/date_picker/picker.date.js +1430 -0
  94. data/vendor/assets/javascripts/materialize/date_picker/picker.js +1123 -0
  95. data/vendor/assets/javascripts/materialize/dropdown.js +265 -0
  96. data/vendor/assets/javascripts/materialize/forms.js +681 -0
  97. data/vendor/assets/javascripts/materialize/global.js +45 -0
  98. data/vendor/assets/javascripts/materialize/hammer.min.js +1 -0
  99. data/vendor/assets/javascripts/materialize/init.js +173 -0
  100. data/vendor/assets/javascripts/materialize/initial.js +11 -0
  101. data/vendor/assets/javascripts/materialize/jquery.easing.1.3.js +205 -0
  102. data/vendor/assets/javascripts/materialize/jquery.hammer.js +33 -0
  103. data/vendor/assets/javascripts/materialize/jquery.timeago.min.js +1 -0
  104. data/vendor/assets/javascripts/materialize/leanModal.js +192 -0
  105. data/vendor/assets/javascripts/materialize/materialbox.js +269 -0
  106. data/vendor/assets/javascripts/materialize/parallax.js +58 -0
  107. data/vendor/assets/javascripts/materialize/prism.js +8 -0
  108. data/vendor/assets/javascripts/materialize/pushpin.js +71 -0
  109. data/vendor/assets/javascripts/materialize/scrollFire.js +48 -0
  110. data/vendor/assets/javascripts/materialize/scrollspy.js +283 -0
  111. data/vendor/assets/javascripts/materialize/sideNav.js +352 -0
  112. data/vendor/assets/javascripts/materialize/slider.js +321 -0
  113. data/vendor/assets/javascripts/materialize/tabs.js +148 -0
  114. data/vendor/assets/javascripts/materialize/toasts.js +136 -0
  115. data/vendor/assets/javascripts/materialize/tooltip.js +230 -0
  116. data/vendor/assets/javascripts/materialize/transitions.js +169 -0
  117. data/vendor/assets/javascripts/materialize/velocity.min.js +5 -0
  118. data/vendor/assets/javascripts/materialize/waves.js +338 -0
  119. data/vendor/assets/javascripts/pdfobject.js +254 -0
  120. data/vendor/assets/stylesheets/materialize/_buttons.scss +211 -0
  121. data/vendor/assets/stylesheets/materialize/_cards.scss +185 -0
  122. data/vendor/assets/stylesheets/materialize/_carousel.scss +85 -0
  123. data/vendor/assets/stylesheets/materialize/_chips.scss +74 -0
  124. data/vendor/assets/stylesheets/materialize/_collapsible.scss +90 -0
  125. data/vendor/assets/stylesheets/materialize/_color.scss +412 -0
  126. data/vendor/assets/stylesheets/materialize/_dropdown.scss +57 -0
  127. data/vendor/assets/stylesheets/materialize/_global.scss +781 -0
  128. data/vendor/assets/stylesheets/materialize/_grid.scss +147 -0
  129. data/vendor/assets/stylesheets/materialize/_icons-material-design.scss +5 -0
  130. data/vendor/assets/stylesheets/materialize/_materialbox.scss +42 -0
  131. data/vendor/assets/stylesheets/materialize/_mixins.scss +5 -0
  132. data/vendor/assets/stylesheets/materialize/_modal.scss +90 -0
  133. data/vendor/assets/stylesheets/materialize/_navbar.scss +182 -0
  134. data/vendor/assets/stylesheets/materialize/_normalize.scss +424 -0
  135. data/vendor/assets/stylesheets/materialize/_prefixer.scss +384 -0
  136. data/vendor/assets/stylesheets/materialize/_preloader.scss +334 -0
  137. data/vendor/assets/stylesheets/materialize/_roboto.scss +49 -0
  138. data/vendor/assets/stylesheets/materialize/_sideNav.scss +219 -0
  139. data/vendor/assets/stylesheets/materialize/_slider.scss +92 -0
  140. data/vendor/assets/stylesheets/materialize/_table_of_contents.scss +33 -0
  141. data/vendor/assets/stylesheets/materialize/_tabs.scss +56 -0
  142. data/vendor/assets/stylesheets/materialize/_toast.scss +65 -0
  143. data/vendor/assets/stylesheets/materialize/_tooltip.scss +32 -0
  144. data/vendor/assets/stylesheets/materialize/_typography.scss +61 -0
  145. data/vendor/assets/stylesheets/materialize/_variables.scss +313 -0
  146. data/vendor/assets/stylesheets/materialize/_waves.scss +177 -0
  147. data/vendor/assets/stylesheets/materialize/date_picker/_default.date.scss +435 -0
  148. data/vendor/assets/stylesheets/materialize/date_picker/_default.scss +201 -0
  149. data/vendor/assets/stylesheets/materialize/date_picker/_default.time.scss +125 -0
  150. data/vendor/assets/stylesheets/materialize/forms/_checkboxes.scss +220 -0
  151. data/vendor/assets/stylesheets/materialize/forms/_file-input.scss +38 -0
  152. data/vendor/assets/stylesheets/materialize/forms/_forms.scss +22 -0
  153. data/vendor/assets/stylesheets/materialize/forms/_input-fields.scss +273 -0
  154. data/vendor/assets/stylesheets/materialize/forms/_radio-buttons.scss +119 -0
  155. data/vendor/assets/stylesheets/materialize/forms/_range.scss +159 -0
  156. data/vendor/assets/stylesheets/materialize/forms/_select.scss +116 -0
  157. data/vendor/assets/stylesheets/materialize/forms/_switches.scss +78 -0
  158. metadata +309 -0
@@ -0,0 +1,338 @@
1
+ /*!
2
+ * Waves v0.6.4
3
+ * http://fian.my.id/Waves
4
+ *
5
+ * Copyright 2014 Alfiana E. Sibuea and other contributors
6
+ * Released under the MIT license
7
+ * https://github.com/fians/Waves/blob/master/LICENSE
8
+ */
9
+
10
+ ;(function(window) {
11
+ 'use strict';
12
+
13
+ var Waves = Waves || {};
14
+ var $$ = document.querySelectorAll.bind(document);
15
+
16
+ // Find exact position of element
17
+ function isWindow(obj) {
18
+ return obj !== null && obj === obj.window;
19
+ }
20
+
21
+ function getWindow(elem) {
22
+ return isWindow(elem) ? elem : elem.nodeType === 9 && elem.defaultView;
23
+ }
24
+
25
+ function offset(elem) {
26
+ var docElem, win,
27
+ box = {top: 0, left: 0},
28
+ doc = elem && elem.ownerDocument;
29
+
30
+ docElem = doc.documentElement;
31
+
32
+ if (typeof elem.getBoundingClientRect !== typeof undefined) {
33
+ box = elem.getBoundingClientRect();
34
+ }
35
+ win = getWindow(doc);
36
+ return {
37
+ top: box.top + win.pageYOffset - docElem.clientTop,
38
+ left: box.left + win.pageXOffset - docElem.clientLeft
39
+ };
40
+ }
41
+
42
+ function convertStyle(obj) {
43
+ var style = '';
44
+
45
+ for (var a in obj) {
46
+ if (obj.hasOwnProperty(a)) {
47
+ style += (a + ':' + obj[a] + ';');
48
+ }
49
+ }
50
+
51
+ return style;
52
+ }
53
+
54
+ var Effect = {
55
+
56
+ // Effect delay
57
+ duration: 750,
58
+
59
+ show: function(e, element) {
60
+
61
+ // Disable right click
62
+ if (e.button === 2) {
63
+ return false;
64
+ }
65
+
66
+ var el = element || this;
67
+
68
+ // Create ripple
69
+ var ripple = document.createElement('div');
70
+ ripple.className = 'waves-ripple';
71
+ el.appendChild(ripple);
72
+
73
+ // Get click coordinate and element witdh
74
+ var pos = offset(el);
75
+ var relativeY = (e.pageY - pos.top);
76
+ var relativeX = (e.pageX - pos.left);
77
+ var scale = 'scale('+((el.clientWidth / 100) * 10)+')';
78
+
79
+ // Support for touch devices
80
+ if ('touches' in e) {
81
+ relativeY = (e.touches[0].pageY - pos.top);
82
+ relativeX = (e.touches[0].pageX - pos.left);
83
+ }
84
+
85
+ // Attach data to element
86
+ ripple.setAttribute('data-hold', Date.now());
87
+ ripple.setAttribute('data-scale', scale);
88
+ ripple.setAttribute('data-x', relativeX);
89
+ ripple.setAttribute('data-y', relativeY);
90
+
91
+ // Set ripple position
92
+ var rippleStyle = {
93
+ 'top': relativeY+'px',
94
+ 'left': relativeX+'px'
95
+ };
96
+
97
+ ripple.className = ripple.className + ' waves-notransition';
98
+ ripple.setAttribute('style', convertStyle(rippleStyle));
99
+ ripple.className = ripple.className.replace('waves-notransition', '');
100
+
101
+ // Scale the ripple
102
+ rippleStyle['-webkit-transform'] = scale;
103
+ rippleStyle['-moz-transform'] = scale;
104
+ rippleStyle['-ms-transform'] = scale;
105
+ rippleStyle['-o-transform'] = scale;
106
+ rippleStyle.transform = scale;
107
+ rippleStyle.opacity = '1';
108
+
109
+ rippleStyle['-webkit-transition-duration'] = Effect.duration + 'ms';
110
+ rippleStyle['-moz-transition-duration'] = Effect.duration + 'ms';
111
+ rippleStyle['-o-transition-duration'] = Effect.duration + 'ms';
112
+ rippleStyle['transition-duration'] = Effect.duration + 'ms';
113
+
114
+ rippleStyle['-webkit-transition-timing-function'] = 'cubic-bezier(0.250, 0.460, 0.450, 0.940)';
115
+ rippleStyle['-moz-transition-timing-function'] = 'cubic-bezier(0.250, 0.460, 0.450, 0.940)';
116
+ rippleStyle['-o-transition-timing-function'] = 'cubic-bezier(0.250, 0.460, 0.450, 0.940)';
117
+ rippleStyle['transition-timing-function'] = 'cubic-bezier(0.250, 0.460, 0.450, 0.940)';
118
+
119
+ ripple.setAttribute('style', convertStyle(rippleStyle));
120
+ },
121
+
122
+ hide: function(e) {
123
+ TouchHandler.touchup(e);
124
+
125
+ var el = this;
126
+ var width = el.clientWidth * 1.4;
127
+
128
+ // Get first ripple
129
+ var ripple = null;
130
+ var ripples = el.getElementsByClassName('waves-ripple');
131
+ if (ripples.length > 0) {
132
+ ripple = ripples[ripples.length - 1];
133
+ } else {
134
+ return false;
135
+ }
136
+
137
+ var relativeX = ripple.getAttribute('data-x');
138
+ var relativeY = ripple.getAttribute('data-y');
139
+ var scale = ripple.getAttribute('data-scale');
140
+
141
+ // Get delay beetween mousedown and mouse leave
142
+ var diff = Date.now() - Number(ripple.getAttribute('data-hold'));
143
+ var delay = 350 - diff;
144
+
145
+ if (delay < 0) {
146
+ delay = 0;
147
+ }
148
+
149
+ // Fade out ripple after delay
150
+ setTimeout(function() {
151
+ var style = {
152
+ 'top': relativeY+'px',
153
+ 'left': relativeX+'px',
154
+ 'opacity': '0',
155
+
156
+ // Duration
157
+ '-webkit-transition-duration': Effect.duration + 'ms',
158
+ '-moz-transition-duration': Effect.duration + 'ms',
159
+ '-o-transition-duration': Effect.duration + 'ms',
160
+ 'transition-duration': Effect.duration + 'ms',
161
+ '-webkit-transform': scale,
162
+ '-moz-transform': scale,
163
+ '-ms-transform': scale,
164
+ '-o-transform': scale,
165
+ 'transform': scale,
166
+ };
167
+
168
+ ripple.setAttribute('style', convertStyle(style));
169
+
170
+ setTimeout(function() {
171
+ try {
172
+ el.removeChild(ripple);
173
+ } catch(e) {
174
+ return false;
175
+ }
176
+ }, Effect.duration);
177
+ }, delay);
178
+ },
179
+
180
+ // Little hack to make <input> can perform waves effect
181
+ wrapInput: function(elements) {
182
+ for (var a = 0; a < elements.length; a++) {
183
+ var el = elements[a];
184
+
185
+ if (el.tagName.toLowerCase() === 'input') {
186
+ var parent = el.parentNode;
187
+
188
+ // If input already have parent just pass through
189
+ if (parent.tagName.toLowerCase() === 'i' && parent.className.indexOf('waves-effect') !== -1) {
190
+ continue;
191
+ }
192
+
193
+ // Put element class and style to the specified parent
194
+ var wrapper = document.createElement('i');
195
+ wrapper.className = el.className + ' waves-input-wrapper';
196
+
197
+ var elementStyle = el.getAttribute('style');
198
+
199
+ if (!elementStyle) {
200
+ elementStyle = '';
201
+ }
202
+
203
+ wrapper.setAttribute('style', elementStyle);
204
+
205
+ el.className = 'waves-button-input';
206
+ el.removeAttribute('style');
207
+
208
+ // Put element as child
209
+ parent.replaceChild(wrapper, el);
210
+ wrapper.appendChild(el);
211
+ }
212
+ }
213
+ }
214
+ };
215
+
216
+
217
+ /**
218
+ * Disable mousedown event for 500ms during and after touch
219
+ */
220
+ var TouchHandler = {
221
+ /* uses an integer rather than bool so there's no issues with
222
+ * needing to clear timeouts if another touch event occurred
223
+ * within the 500ms. Cannot mouseup between touchstart and
224
+ * touchend, nor in the 500ms after touchend. */
225
+ touches: 0,
226
+ allowEvent: function(e) {
227
+ var allow = true;
228
+
229
+ if (e.type === 'touchstart') {
230
+ TouchHandler.touches += 1; //push
231
+ } else if (e.type === 'touchend' || e.type === 'touchcancel') {
232
+ setTimeout(function() {
233
+ if (TouchHandler.touches > 0) {
234
+ TouchHandler.touches -= 1; //pop after 500ms
235
+ }
236
+ }, 500);
237
+ } else if (e.type === 'mousedown' && TouchHandler.touches > 0) {
238
+ allow = false;
239
+ }
240
+
241
+ return allow;
242
+ },
243
+ touchup: function(e) {
244
+ TouchHandler.allowEvent(e);
245
+ }
246
+ };
247
+
248
+
249
+ /**
250
+ * Delegated click handler for .waves-effect element.
251
+ * returns null when .waves-effect element not in "click tree"
252
+ */
253
+ function getWavesEffectElement(e) {
254
+ if (TouchHandler.allowEvent(e) === false) {
255
+ return null;
256
+ }
257
+
258
+ var element = null;
259
+ var target = e.target || e.srcElement;
260
+
261
+ while (target.parentElement !== null) {
262
+ if (!(target instanceof SVGElement) && target.className.indexOf('waves-effect') !== -1) {
263
+ element = target;
264
+ break;
265
+ } else if (target.classList.contains('waves-effect')) {
266
+ element = target;
267
+ break;
268
+ }
269
+ target = target.parentElement;
270
+ }
271
+
272
+ return element;
273
+ }
274
+
275
+ /**
276
+ * Bubble the click and show effect if .waves-effect elem was found
277
+ */
278
+ function showEffect(e) {
279
+ var element = getWavesEffectElement(e);
280
+
281
+ if (element !== null) {
282
+ Effect.show(e, element);
283
+
284
+ if ('ontouchstart' in window) {
285
+ element.addEventListener('touchend', Effect.hide, false);
286
+ element.addEventListener('touchcancel', Effect.hide, false);
287
+ }
288
+
289
+ element.addEventListener('mouseup', Effect.hide, false);
290
+ element.addEventListener('mouseleave', Effect.hide, false);
291
+ }
292
+ }
293
+
294
+ Waves.displayEffect = function(options) {
295
+ options = options || {};
296
+
297
+ if ('duration' in options) {
298
+ Effect.duration = options.duration;
299
+ }
300
+
301
+ //Wrap input inside <i> tag
302
+ Effect.wrapInput($$('.waves-effect'));
303
+
304
+ if ('ontouchstart' in window) {
305
+ document.body.addEventListener('touchstart', showEffect, false);
306
+ }
307
+
308
+ document.body.addEventListener('mousedown', showEffect, false);
309
+ };
310
+
311
+ /**
312
+ * Attach Waves to an input element (or any element which doesn't
313
+ * bubble mouseup/mousedown events).
314
+ * Intended to be used with dynamically loaded forms/inputs, or
315
+ * where the user doesn't want a delegated click handler.
316
+ */
317
+ Waves.attach = function(element) {
318
+ //FUTURE: automatically add waves classes and allow users
319
+ // to specify them with an options param? Eg. light/classic/button
320
+ if (element.tagName.toLowerCase() === 'input') {
321
+ Effect.wrapInput([element]);
322
+ element = element.parentElement;
323
+ }
324
+
325
+ if ('ontouchstart' in window) {
326
+ element.addEventListener('touchstart', showEffect, false);
327
+ }
328
+
329
+ element.addEventListener('mousedown', showEffect, false);
330
+ };
331
+
332
+ window.Waves = Waves;
333
+
334
+ document.addEventListener('DOMContentLoaded', function() {
335
+ Waves.displayEffect();
336
+ }, false);
337
+
338
+ })(window);
@@ -0,0 +1,254 @@
1
+ /*global ActiveXObject, window, console, define, module, jQuery */
2
+ //jshint unused:false, strict: false
3
+
4
+ /*
5
+ PDFObject v2.0.201604172
6
+ https://github.com/pipwerks/PDFObject
7
+ Copyright (c) 2008-2016 Philip Hutchison
8
+ MIT-style license: http://pipwerks.mit-license.org/
9
+ UMD module pattern from https://github.com/umdjs/umd/blob/master/templates/returnExports.js
10
+ */
11
+
12
+ (function (root, factory) {
13
+ if (typeof define === 'function' && define.amd) {
14
+ // AMD. Register as an anonymous module.
15
+ define([], factory);
16
+ } else if (typeof module === 'object' && module.exports) {
17
+ // Node. Does not work with strict CommonJS, but
18
+ // only CommonJS-like environments that support module.exports,
19
+ // like Node.
20
+ module.exports = factory();
21
+ } else {
22
+ // Browser globals (root is window)
23
+ root.PDFObject = factory();
24
+ }
25
+ }(this, function () {
26
+
27
+ "use strict";
28
+ //jshint unused:true
29
+
30
+ //PDFObject is designed for client-side (browsers), not server-side (node)
31
+ //Will choke on undefined navigator and window vars when run on server
32
+ //Return boolean false and exit function when running server-side
33
+
34
+ if(typeof window === "undefined" || typeof navigator === "undefined"){ return false; }
35
+
36
+ var pdfobjectversion = "2.0.201604172",
37
+ supportsPDFs,
38
+
39
+ //declare functions
40
+ createAXO,
41
+ isIE,
42
+ supportsPdfMimeType = (typeof navigator.mimeTypes['application/pdf'] !== "undefined"),
43
+ supportsPdfActiveX,
44
+ buildFragmentString,
45
+ log,
46
+ embedError,
47
+ embed,
48
+ getTargetElement,
49
+ generatePDFJSiframe,
50
+ isIOS = (function (){ return (/iphone|ipad|ipod/i.test(navigator.userAgent.toLowerCase())); })(),
51
+ generateEmbedElement;
52
+
53
+
54
+ /* ----------------------------------------------------
55
+ Supporting functions
56
+ ---------------------------------------------------- */
57
+
58
+ createAXO = function (type){
59
+ var ax;
60
+ try {
61
+ ax = new ActiveXObject(type);
62
+ } catch (e) {
63
+ ax = null; //ensure ax remains null
64
+ }
65
+ return ax;
66
+ };
67
+
68
+ //IE11 still uses ActiveX for Adobe Reader, but IE 11 doesn't expose
69
+ //window.ActiveXObject the same way previous versions of IE did
70
+ //window.ActiveXObject will evaluate to false in IE 11, but "ActiveXObject" in window evaluates to true
71
+ //so check the first one for older IE, and the second for IE11
72
+ //FWIW, MS Edge (replacing IE11) does not support ActiveX at all, both will evaluate false
73
+ //Constructed as a method (not a prop) to avoid unneccesarry overhead -- will only be evaluated if needed
74
+ isIE = function (){ return !!(window.ActiveXObject || "ActiveXObject" in window); };
75
+
76
+ //If either ActiveX support for "AcroPDF.PDF" or "PDF.PdfCtrl" are found, return true
77
+ //Constructed as a method (not a prop) to avoid unneccesarry overhead -- will only be evaluated if needed
78
+ supportsPdfActiveX = function (){ return !!(createAXO("AcroPDF.PDF") || createAXO("PDF.PdfCtrl")); };
79
+
80
+ //Determines whether PDF support is available
81
+ supportsPDFs = (supportsPdfMimeType || (isIE() && supportsPdfActiveX()));
82
+
83
+ //Create a fragment identifier for using PDF Open parameters when embedding PDF
84
+ buildFragmentString = function(pdfParams){
85
+
86
+ var string = "",
87
+ prop;
88
+
89
+ if(pdfParams){
90
+
91
+ for (prop in pdfParams) {
92
+ if (pdfParams.hasOwnProperty(prop)) {
93
+ string += encodeURIComponent(prop) + "=" + encodeURIComponent(pdfParams[prop]) + "&";
94
+ }
95
+ }
96
+
97
+ //The string will be empty if no PDF Params found
98
+ if(string){
99
+
100
+ string = "#" + string;
101
+
102
+ //Remove last ampersand
103
+ string = string.slice(0, string.length - 1);
104
+
105
+ }
106
+
107
+ }
108
+
109
+ return string;
110
+
111
+ };
112
+
113
+ log = function (msg){
114
+ if(typeof console !== "undefined" && console.log){
115
+ console.log("[PDFObject] " + msg);
116
+ }
117
+ };
118
+
119
+ embedError = function (msg){
120
+ log(msg);
121
+ return false;
122
+ };
123
+
124
+ getTargetElement = function (targetSelector){
125
+
126
+ //Default to body for full-browser PDF
127
+ var targetNode = document.body;
128
+
129
+ //If a targetSelector is specified, check to see whether
130
+ //it's passing a selector, jQuery object, or an HTML element
131
+
132
+ if(typeof targetSelector === "string"){
133
+
134
+ //Is CSS selector
135
+ targetNode = document.querySelector(targetSelector);
136
+
137
+ } else if (typeof jQuery !== "undefined" && targetSelector instanceof jQuery && targetSelector.length) {
138
+
139
+ //Is jQuery element. Extract HTML node
140
+ targetNode = targetSelector.get(0);
141
+
142
+ } else if (typeof targetSelector.nodeType !== "undefined" && targetSelector.nodeType === 1){
143
+
144
+ //Is HTML element
145
+ targetNode = targetSelector;
146
+
147
+ }
148
+
149
+ return targetNode;
150
+
151
+ };
152
+
153
+ generatePDFJSiframe = function (targetNode, url, pdfOpenFragment, PDFJS_URL, id){
154
+
155
+ var fullURL = PDFJS_URL + "?file=" + encodeURIComponent(url) + pdfOpenFragment;
156
+ var scrollfix = (isIOS) ? "-webkit-overflow-scrolling: touch; overflow-y: scroll; " : "overflow: hidden; ";
157
+ var iframe = "<div style='" + scrollfix + "position: absolute; top: 0; right: 0; bottom: 0; left: 0;'><iframe " + id + " src='" + fullURL + "' style='border: none; width: 100%; height: 100%;' frameborder='0'></iframe></div>";
158
+ targetNode.className += " pdfobject-container";
159
+ targetNode.style.position = "relative";
160
+ targetNode.style.overflow = "auto";
161
+ targetNode.innerHTML = iframe;
162
+ return targetNode.getElementsByTagName("iframe")[0];
163
+
164
+ };
165
+
166
+ generateEmbedElement = function (targetNode, targetSelector, url, pdfOpenFragment, width, height, id){
167
+
168
+ var style = "";
169
+
170
+ if(targetSelector && targetSelector !== document.body){
171
+ style = "width: " + width + "; height: " + height + ";";
172
+ } else {
173
+ style = "position: absolute; top: 0; right: 0; bottom: 0; left: 0; width: 100%; height: 100%;";
174
+ }
175
+
176
+ targetNode.className += " pdfobject-container";
177
+ targetNode.innerHTML = "<embed " + id + " class='pdfobject' src='" + url + pdfOpenFragment + "' type='application/pdf' style='overflow: auto; " + style + "'/>";
178
+
179
+ return targetNode.getElementsByTagName("embed")[0];
180
+
181
+ };
182
+
183
+ embed = function(url, targetSelector, options){
184
+
185
+ //Ensure URL is available. If not, exit now.
186
+ if(typeof url !== "string"){ return embedError("URL is not valid"); }
187
+
188
+ //If targetSelector is not defined, convert to boolean
189
+ targetSelector = (typeof targetSelector !== "undefined") ? targetSelector : false;
190
+
191
+ //Ensure options object is not undefined -- enables easier error checking below
192
+ options = (typeof options !== "undefined") ? options : {};
193
+
194
+ //Get passed options, or set reasonable defaults
195
+ var id = (options.id && typeof options.id === "string") ? "id='" + options.id + "'" : "",
196
+ page = (options.page) ? options.page : false,
197
+ pdfOpenParams = (options.pdfOpenParams) ? options.pdfOpenParams : {},
198
+ fallbackLink = (typeof options.fallbackLink !== "undefined") ? options.fallbackLink : true,
199
+ width = (options.width) ? options.width : "100%",
200
+ height = (options.height) ? options.height : "100%",
201
+ forcePDFJS = (typeof options.forcePDFJS === "boolean") ? options.forcePDFJS : false,
202
+ PDFJS_URL = (options.PDFJS_URL) ? options.PDFJS_URL : false,
203
+ targetNode = getTargetElement(targetSelector),
204
+ fallbackHTML = "",
205
+ pdfOpenFragment = "",
206
+ fallbackHTML_default = "<p>This browser does not support inline PDFs. Please download the PDF to view it: <a href='[url]'>Download PDF</a></p>";
207
+
208
+ //If target element is specified but is not valid, exit without doing anything
209
+ if(!targetNode){ return embedError("Target element cannot be determined"); }
210
+
211
+
212
+ //page option overrides pdfOpenParams, if found
213
+ if(page){
214
+ pdfOpenParams.page = page;
215
+ }
216
+
217
+ //Stringify optional Adobe params for opening document (as fragment identifier)
218
+ pdfOpenFragment = buildFragmentString(pdfOpenParams);
219
+
220
+ //Do the dance
221
+ if(forcePDFJS && PDFJS_URL){
222
+
223
+ return generatePDFJSiframe(targetNode, url, pdfOpenFragment, PDFJS_URL, id);
224
+
225
+ } else if(supportsPDFs){
226
+
227
+ return generateEmbedElement(targetNode, targetSelector, url, pdfOpenFragment, width, height, id);
228
+
229
+ } else {
230
+
231
+ if(PDFJS_URL){
232
+
233
+ return generatePDFJSiframe(targetNode, url, pdfOpenFragment, PDFJS_URL, id);
234
+
235
+ } else if(fallbackLink){
236
+
237
+ fallbackHTML = (typeof fallbackLink === "string") ? fallbackLink : fallbackHTML_default;
238
+ targetNode.innerHTML = fallbackHTML.replace(/\[url\]/g, url);
239
+
240
+ }
241
+
242
+ return embedError("This browser does not support embedded PDFs");
243
+
244
+ }
245
+
246
+ };
247
+
248
+ return {
249
+ embed: function (a,b,c){ return embed(a,b,c); },
250
+ pdfobjectversion: (function () { return pdfobjectversion; })(),
251
+ supportsPDFs: (function (){ return supportsPDFs; })()
252
+ };
253
+
254
+ }));