j1m_scroll 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.md +21 -0
  3. data/README.md +41 -0
  4. data/_data/modules/default/j1_scroll-0.0.1/j1_back2top.yml +131 -0
  5. data/_data/modules/default/j1_scroll-0.0.1/j1_smooth_scroll.yml +162 -0
  6. data/_data/resources/default/j1_scroll-0.0.1/resource.yml +43 -0
  7. data/assets/themes/j1/iframe_resizer/.npmignore +9 -0
  8. data/assets/themes/j1/iframe_resizer/.travis.yml +6 -0
  9. data/assets/themes/j1/iframe_resizer/CONTRIBUTING.md +86 -0
  10. data/assets/themes/j1/iframe_resizer/Iframe-resizer by davidjbradshaw.url +2 -0
  11. data/assets/themes/j1/iframe_resizer/LICENSE +21 -0
  12. data/assets/themes/j1/iframe_resizer/README.md +608 -0
  13. data/assets/themes/j1/iframe_resizer/bower.json +45 -0
  14. data/assets/themes/j1/iframe_resizer/example/frame.absolute.html +88 -0
  15. data/assets/themes/j1/iframe_resizer/example/frame.content.html +58 -0
  16. data/assets/themes/j1/iframe_resizer/example/frame.hover.html +51 -0
  17. data/assets/themes/j1/iframe_resizer/example/frame.nested.html +72 -0
  18. data/assets/themes/j1/iframe_resizer/example/frame.textarea.html +46 -0
  19. data/assets/themes/j1/iframe_resizer/example/frame.tolerance.html +79 -0
  20. data/assets/themes/j1/iframe_resizer/example/index.html +70 -0
  21. data/assets/themes/j1/iframe_resizer/example/two.html +71 -0
  22. data/assets/themes/j1/iframe_resizer/gruntfile.js +215 -0
  23. data/assets/themes/j1/iframe_resizer/iframeResizer.jquery.json +41 -0
  24. data/assets/themes/j1/iframe_resizer/index.js +4 -0
  25. data/assets/themes/j1/iframe_resizer/js/_client.js +1131 -0
  26. data/assets/themes/j1/iframe_resizer/js/_server.js +1126 -0
  27. data/assets/themes/j1/iframe_resizer/js/ie8.polyfils.js +85 -0
  28. data/assets/themes/j1/iframe_resizer/js/ie8.polyfils.map +1 -0
  29. data/assets/themes/j1/iframe_resizer/js/ie8.polyfils.min.js +4 -0
  30. data/assets/themes/j1/iframe_resizer/js/iframeResizer.contentWindow.js +1104 -0
  31. data/assets/themes/j1/iframe_resizer/js/iframeResizer.contentWindow.map +1 -0
  32. data/assets/themes/j1/iframe_resizer/js/iframeResizer.contentWindow.min.js +10 -0
  33. data/assets/themes/j1/iframe_resizer/js/iframeResizer.js +1007 -0
  34. data/assets/themes/j1/iframe_resizer/js/iframeResizer.js.modified +1004 -0
  35. data/assets/themes/j1/iframe_resizer/js/iframeResizer.map +1 -0
  36. data/assets/themes/j1/iframe_resizer/js/iframeResizer.min.js +9 -0
  37. data/assets/themes/j1/iframe_resizer/js/index.js +2 -0
  38. data/assets/themes/j1/iframe_resizer/karma.conf.js +92 -0
  39. data/assets/themes/j1/iframe_resizer/package.json +111 -0
  40. data/assets/themes/j1/iframe_resizer/spec/_initSpec.js +63 -0
  41. data/assets/themes/j1/iframe_resizer/spec/anchorSpec.js +62 -0
  42. data/assets/themes/j1/iframe_resizer/spec/childSpec.js +403 -0
  43. data/assets/themes/j1/iframe_resizer/spec/closeSpecSpec.js +44 -0
  44. data/assets/themes/j1/iframe_resizer/spec/getPageInfoSpec.js +32 -0
  45. data/assets/themes/j1/iframe_resizer/spec/initCssSpec.js +28 -0
  46. data/assets/themes/j1/iframe_resizer/spec/initDomSpec.js +27 -0
  47. data/assets/themes/j1/iframe_resizer/spec/initDoubleCallSpec.js +33 -0
  48. data/assets/themes/j1/iframe_resizer/spec/initErrorSpec.js +57 -0
  49. data/assets/themes/j1/iframe_resizer/spec/initJQuerySpec.js +29 -0
  50. data/assets/themes/j1/iframe_resizer/spec/initUndefinedDomSpec.js +25 -0
  51. data/assets/themes/j1/iframe_resizer/spec/javascripts/fixtures/iframe.html +2 -0
  52. data/assets/themes/j1/iframe_resizer/spec/javascripts/fixtures/iframe600.html +4 -0
  53. data/assets/themes/j1/iframe_resizer/spec/javascripts/fixtures/iframe600WithId.html +4 -0
  54. data/assets/themes/j1/iframe_resizer/spec/lib/common.js +59 -0
  55. data/assets/themes/j1/iframe_resizer/spec/parentSpec.js +88 -0
  56. data/assets/themes/j1/iframe_resizer/spec/resources/djb.jpg +0 -0
  57. data/assets/themes/j1/iframe_resizer/spec/resources/frame.content.html +176 -0
  58. data/assets/themes/j1/iframe_resizer/spec/resources/frame.lateload.html +33 -0
  59. data/assets/themes/j1/iframe_resizer/spec/resources/frame.nested.html +40 -0
  60. data/assets/themes/j1/iframe_resizer/spec/scrollSpec.js +53 -0
  61. data/assets/themes/j1/iframe_resizer/spec/sendMessageSpec.js +58 -0
  62. data/assets/themes/j1/iframe_resizer/spec/support/jasmine.json +9 -0
  63. data/assets/themes/j1/iframe_resizer/src/ie8.polyfils.js +64 -0
  64. data/assets/themes/j1/iframe_resizer/src/iframeResizer.contentWindow.js +1123 -0
  65. data/assets/themes/j1/iframe_resizer/src/iframeResizer.js +1002 -0
  66. data/assets/themes/j1/iframe_resizer/test-main.js +33 -0
  67. data/assets/themes/j1/iframe_resizer/test/_init.html +44 -0
  68. data/assets/themes/j1/iframe_resizer/test/_init_once.html +45 -0
  69. data/assets/themes/j1/iframe_resizer/test/_init_once_async.html +72 -0
  70. data/assets/themes/j1/iframe_resizer/test/background.html +47 -0
  71. data/assets/themes/j1/iframe_resizer/test/changePage.html +50 -0
  72. data/assets/themes/j1/iframe_resizer/test/close.html +44 -0
  73. data/assets/themes/j1/iframe_resizer/test/getId.html +44 -0
  74. data/assets/themes/j1/iframe_resizer/test/interval.html +56 -0
  75. data/assets/themes/j1/iframe_resizer/test/jqueryNoConflict.html +47 -0
  76. data/assets/themes/j1/iframe_resizer/test/lateImageLoad.html +90 -0
  77. data/assets/themes/j1/iframe_resizer/test/margin.html +73 -0
  78. data/assets/themes/j1/iframe_resizer/test/mutationObserver.html +63 -0
  79. data/assets/themes/j1/iframe_resizer/test/nested.html +46 -0
  80. data/assets/themes/j1/iframe_resizer/test/resize.contentWidth.html +51 -0
  81. data/assets/themes/j1/iframe_resizer/test/resize.width.html +63 -0
  82. data/assets/themes/j1/iframe_resizer/test/resources/djb.jpg +0 -0
  83. data/assets/themes/j1/iframe_resizer/test/resources/frame.content.html +191 -0
  84. data/assets/themes/j1/iframe_resizer/test/resources/frame.lateload.html +33 -0
  85. data/assets/themes/j1/iframe_resizer/test/resources/frame.nested.html +40 -0
  86. data/assets/themes/j1/iframe_resizer/test/resources/jquery.js +6 -0
  87. data/assets/themes/j1/iframe_resizer/test/resources/qunit.css +244 -0
  88. data/assets/themes/j1/iframe_resizer/test/resources/qunit.js +2212 -0
  89. data/assets/themes/j1/iframe_resizer/test/resources/require.js +2103 -0
  90. data/assets/themes/j1/iframe_resizer/test/resources/testLib.js +9 -0
  91. data/assets/themes/j1/iframe_resizer/test/scrolling.html +65 -0
  92. data/assets/themes/j1/iframe_resizer/test/sendMessage.html +61 -0
  93. data/assets/themes/j1/iframe_resizer/test/setHeightCalculationMethod.html +51 -0
  94. data/assets/themes/j1/iframe_resizer/test/size.html +64 -0
  95. data/assets/themes/j1/iframe_resizer/test/v1.html +189 -0
  96. data/assets/themes/j1/j1/js/adapters/iframe_resizer.js +105 -0
  97. data/exe/console +14 -0
  98. data/exe/setup +8 -0
  99. data/lib/j1m_scroll.rb +5 -0
  100. data/lib/j1m_scroll/version.rb +3 -0
  101. metadata +190 -0
@@ -0,0 +1,1004 @@
1
+ /*
2
+ * File: iframeResizer.js
3
+ * Desc: Force iframes to size to content.
4
+ * Requires: iframeResizer.contentWindow.js to be loaded into the target frame.
5
+ * Doc: https://github.com/davidjbradshaw/iframe-resizer
6
+ * Author: David J. Bradshaw - dave@bradshaw.net
7
+ * Contributor: Jure Mav - jure.mav@gmail.com
8
+ * Contributor: Reed Dadoune - reed@dadoune.com
9
+ */
10
+
11
+
12
+ ;(function(window) {
13
+ 'use strict';
14
+
15
+ var
16
+ count = 0,
17
+ logEnabled = false,
18
+ hiddenCheckEnabled = false,
19
+ msgHeader = 'message',
20
+ msgHeaderLen = msgHeader.length,
21
+ msgId = '[iFrameSizer]', //Must match iframe msg ID
22
+ msgIdLen = msgId.length,
23
+ pagePosition = null,
24
+ requestAnimationFrame = window.requestAnimationFrame,
25
+ resetRequiredMethods = {max:1,scroll:1,bodyScroll:1,documentElementScroll:1},
26
+ settings = {},
27
+ timer = null,
28
+ logId = 'Host Page',
29
+
30
+ defaults = {
31
+ autoResize : true,
32
+ bodyBackground : null,
33
+ bodyMargin : null,
34
+ bodyMarginV1 : 8,
35
+ bodyPadding : null,
36
+ checkOrigin : true,
37
+ inPageLinks : false,
38
+ enablePublicMethods : true,
39
+ heightCalculationMethod : 'bodyOffset',
40
+ id : 'iFrameResizer',
41
+ interval : 32,
42
+ log : false,
43
+ maxHeight : Infinity,
44
+ maxWidth : Infinity,
45
+ minHeight : 0,
46
+ minWidth : 0,
47
+ resizeFrom : 'parent',
48
+ scrolling : false,
49
+ sizeHeight : true,
50
+ sizeWidth : false,
51
+ tolerance : 0,
52
+ widthCalculationMethod : 'scroll',
53
+ closedCallback : function(){},
54
+ initCallback : function(){},
55
+ messageCallback : function(){warn('MessageCallback function not defined');},
56
+ resizedCallback : function(){},
57
+ scrollCallback : function(){return true;}
58
+ };
59
+
60
+ function addEventListener(obj,evt,func){
61
+ /* istanbul ignore else */ // Not testable in PhantonJS
62
+ if ('addEventListener' in window){
63
+ obj.addEventListener(evt,func, false);
64
+ } else if ('attachEvent' in window){//IE
65
+ obj.attachEvent('on'+evt,func);
66
+ }
67
+ }
68
+
69
+ function removeEventListener(el,evt,func){
70
+ /* istanbul ignore else */ // Not testable in phantonJS
71
+ if ('removeEventListener' in window){
72
+ el.removeEventListener(evt,func, false);
73
+ } else if ('detachEvent' in window){ //IE
74
+ el.detachEvent('on'+evt,func);
75
+ }
76
+ }
77
+
78
+ function setupRequestAnimationFrame(){
79
+ var
80
+ vendors = ['moz', 'webkit', 'o', 'ms'],
81
+ x;
82
+
83
+ // Remove vendor prefixing if prefixed and break early if not
84
+ for (x = 0; x < vendors.length && !requestAnimationFrame; x += 1) {
85
+ requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
86
+ }
87
+
88
+ if (!(requestAnimationFrame)){
89
+ log('setup','RequestAnimationFrame not supported');
90
+ }
91
+ }
92
+
93
+ function getMyID(iframeId){
94
+ var retStr = 'Host page: '+iframeId;
95
+
96
+ if (window.top!==window.self){
97
+ if (window.parentIFrame && window.parentIFrame.getId){
98
+ retStr = window.parentIFrame.getId()+': '+iframeId;
99
+ } else {
100
+ retStr = 'Nested host page: '+iframeId;
101
+ }
102
+ }
103
+
104
+ return retStr;
105
+ }
106
+
107
+ function formatLogHeader(iframeId){
108
+ return msgId + '[' + getMyID(iframeId) + ']';
109
+ }
110
+
111
+ function isLogEnabled(iframeId){
112
+ return settings[iframeId] ? settings[iframeId].log : logEnabled;
113
+ }
114
+
115
+ function log(iframeId,msg){
116
+ output('log',iframeId,msg,isLogEnabled(iframeId));
117
+ }
118
+
119
+ function info(iframeId,msg){
120
+ output('info',iframeId,msg,isLogEnabled(iframeId));
121
+ }
122
+
123
+ function warn(iframeId,msg){
124
+ output('warn',iframeId,msg,true);
125
+ }
126
+
127
+ function output(type,iframeId,msg,enabled){
128
+ if (true === enabled && 'object' === typeof window.console){
129
+ console[type](formatLogHeader(iframeId),msg);
130
+ }
131
+ }
132
+
133
+ function iFrameListener(event){
134
+ function resizeIFrame(){
135
+ function resize(){
136
+ setSize(messageData);
137
+ setPagePosition(iframeId);
138
+ }
139
+
140
+ ensureInRange('Height');
141
+ ensureInRange('Width');
142
+
143
+ syncResize(resize,messageData,'init');
144
+ }
145
+
146
+ function processMsg(){
147
+ var data = msg.substr(msgIdLen).split(':');
148
+
149
+ return {
150
+ iframe: settings[data[0]].iframe,
151
+ id: data[0],
152
+ height: data[1],
153
+ width: data[2],
154
+ type: data[3]
155
+ };
156
+ }
157
+
158
+ function ensureInRange(Dimension){
159
+ var
160
+ max = Number(settings[iframeId]['max' + Dimension]),
161
+ min = Number(settings[iframeId]['min' + Dimension]),
162
+ dimension = Dimension.toLowerCase(),
163
+ size = Number(messageData[dimension]);
164
+
165
+ log(iframeId,'Checking ' + dimension + ' is in range ' + min + '-' + max);
166
+
167
+ if (size<min) {
168
+ size=min;
169
+ log(iframeId,'Set ' + dimension + ' to min value');
170
+ }
171
+
172
+ if (size>max) {
173
+ size=max;
174
+ log(iframeId,'Set ' + dimension + ' to max value');
175
+ }
176
+
177
+ messageData[dimension] = '' + size;
178
+ }
179
+
180
+
181
+ function isMessageFromIFrame(){
182
+ function checkAllowedOrigin(){
183
+ function checkList(){
184
+ var
185
+ i = 0,
186
+ retCode = false;
187
+
188
+ log(iframeId,'Checking connection is from allowed list of origins: ' + checkOrigin);
189
+
190
+ for (; i < checkOrigin.length; i++) {
191
+ if (checkOrigin[i] === origin) {
192
+ retCode = true;
193
+ break;
194
+ }
195
+ }
196
+ return retCode;
197
+ }
198
+
199
+ function checkSingle(){
200
+ var remoteHost = settings[iframeId].remoteHost;
201
+ log(iframeId,'Checking connection is from: '+remoteHost);
202
+ return origin === remoteHost;
203
+ }
204
+
205
+ return checkOrigin.constructor === Array ? checkList() : checkSingle();
206
+ }
207
+
208
+ var
209
+ origin = event.origin,
210
+ checkOrigin = settings[iframeId].checkOrigin;
211
+
212
+ if (checkOrigin && (''+origin !== 'null') && !checkAllowedOrigin()) {
213
+ throw new Error(
214
+ 'Unexpected message received from: ' + origin +
215
+ ' for ' + messageData.iframe.id +
216
+ '. Message was: ' + event.data +
217
+ '. This error can be disabled by setting the checkOrigin: false option or by providing of array of trusted domains.'
218
+ );
219
+ }
220
+
221
+ return true;
222
+ }
223
+
224
+ function isMessageForUs(){
225
+ return msgId === (('' + msg).substr(0,msgIdLen)) && (msg.substr(msgIdLen).split(':')[0] in settings); //''+Protects against non-string msg
226
+ }
227
+
228
+ function isMessageFromMetaParent(){
229
+ //Test if this message is from a parent above us. This is an ugly test, however, updating
230
+ //the message format would break backwards compatibity.
231
+ var retCode = messageData.type in {'true':1,'false':1,'undefined':1};
232
+
233
+ if (retCode){
234
+ log(iframeId,'Ignoring init message from meta parent page');
235
+ }
236
+
237
+ return retCode;
238
+ }
239
+
240
+ function getMsgBody(offset){
241
+ return msg.substr(msg.indexOf(':')+msgHeaderLen+offset);
242
+ }
243
+
244
+ function forwardMsgFromIFrame(msgBody){
245
+ log(iframeId,'MessageCallback passed: {iframe: '+ messageData.iframe.id + ', message: ' + msgBody + '}');
246
+ callback('messageCallback',{
247
+ iframe: messageData.iframe,
248
+ message: JSON.parse(msgBody)
249
+ });
250
+ log(iframeId,'--');
251
+ }
252
+
253
+ function getPageInfo(){
254
+ var
255
+ bodyPosition = document.body.getBoundingClientRect(),
256
+ iFramePosition = messageData.iframe.getBoundingClientRect();
257
+
258
+ return JSON.stringify({
259
+ iframeHeight: iFramePosition.height,
260
+ iframeWidth: iFramePosition.width,
261
+ clientHeight: Math.max(document.documentElement.clientHeight, window.innerHeight || 0),
262
+ clientWidth: Math.max(document.documentElement.clientWidth, window.innerWidth || 0),
263
+ offsetTop: parseInt(iFramePosition.top - bodyPosition.top, 10),
264
+ offsetLeft: parseInt(iFramePosition.left - bodyPosition.left, 10),
265
+ scrollTop: window.pageYOffset,
266
+ scrollLeft: window.pageXOffset
267
+ });
268
+ }
269
+
270
+ function sendPageInfoToIframe(iframe,iframeId){
271
+ function debouncedTrigger(){
272
+ trigger(
273
+ 'Send Page Info',
274
+ 'pageInfo:' + getPageInfo(),
275
+ iframe,
276
+ iframeId
277
+ );
278
+ }
279
+
280
+ debouce(debouncedTrigger,32);
281
+ }
282
+
283
+
284
+ function startPageInfoMonitor(){
285
+ function setListener(type,func){
286
+ function sendPageInfo(){
287
+ if (settings[id]){
288
+ sendPageInfoToIframe(settings[id].iframe,id);
289
+ } else {
290
+ stop();
291
+ }
292
+ }
293
+
294
+ ['scroll','resize'].forEach(function(evt){
295
+ log(id, type + evt + ' listener for sendPageInfo');
296
+ func(window,evt,sendPageInfo);
297
+ });
298
+ }
299
+
300
+ function stop(){
301
+ setListener('Remove ', removeEventListener);
302
+ }
303
+
304
+ function start(){
305
+ setListener('Add ', addEventListener);
306
+ }
307
+
308
+ var id = iframeId; //Create locally scoped copy of iFrame ID
309
+
310
+ start();
311
+
312
+ settings[id].stopPageInfo = stop;
313
+ }
314
+
315
+ function stopPageInfoMonitor(){
316
+ if (settings[iframeId] && settings[iframeId].stopPageInfo){
317
+ settings[iframeId].stopPageInfo();
318
+ delete settings[iframeId].stopPageInfo;
319
+ }
320
+ }
321
+
322
+ function checkIFrameExists(){
323
+ var retBool = true;
324
+
325
+ if (null === messageData.iframe) {
326
+ warn(iframeId,'IFrame ('+messageData.id+') not found');
327
+ retBool = false;
328
+ }
329
+ return retBool;
330
+ }
331
+
332
+ function getElementPosition(target){
333
+ var iFramePosition = target.getBoundingClientRect();
334
+
335
+ getPagePosition(iframeId);
336
+
337
+ return {
338
+ x: Math.floor( Number(iFramePosition.left) + Number(pagePosition.x) ),
339
+ y: Math.floor( Number(iFramePosition.top) + Number(pagePosition.y) )
340
+ };
341
+ }
342
+
343
+ function scrollRequestFromChild(addOffset){
344
+ /* istanbul ignore next */ //Not testable in Karma
345
+ function reposition(){
346
+ pagePosition = newPosition;
347
+ scrollTo();
348
+ log(iframeId,'--');
349
+ }
350
+
351
+ function calcOffset(){
352
+ return {
353
+ x: Number(messageData.width) + offset.x,
354
+ y: Number(messageData.height) + offset.y
355
+ };
356
+ }
357
+
358
+ function scrollParent(){
359
+ if (window.parentIFrame){
360
+ window.parentIFrame['scrollTo'+(addOffset?'Offset':'')](newPosition.x,newPosition.y);
361
+ } else {
362
+ warn(iframeId,'Unable to scroll to requested position, window.parentIFrame not found');
363
+ }
364
+ }
365
+
366
+ var
367
+ offset = addOffset ? getElementPosition(messageData.iframe) : {x:0,y:0},
368
+ newPosition = calcOffset();
369
+
370
+ log(iframeId,'Reposition requested from iFrame (offset x:'+offset.x+' y:'+offset.y+')');
371
+
372
+ if(window.top!==window.self){
373
+ scrollParent();
374
+ } else {
375
+ reposition();
376
+ }
377
+ }
378
+
379
+ function scrollTo(){
380
+ if (false !== callback('scrollCallback',pagePosition)){
381
+ setPagePosition(iframeId);
382
+ } else {
383
+ unsetPagePosition();
384
+ }
385
+ }
386
+
387
+ function findTarget(location){
388
+ function jumpToTarget(){
389
+ var jumpPosition = getElementPosition(target);
390
+
391
+ log(iframeId,'Moving to in page link (#'+hash+') at x: '+jumpPosition.x+' y: '+jumpPosition.y);
392
+ pagePosition = {
393
+ x: jumpPosition.x,
394
+ y: jumpPosition.y
395
+ };
396
+
397
+ scrollTo();
398
+ log(iframeId,'--');
399
+ }
400
+
401
+ function jumpToParent(){
402
+ if (window.parentIFrame){
403
+ window.parentIFrame.moveToAnchor(hash);
404
+ } else {
405
+ log(iframeId,'In page link #'+hash+' not found and window.parentIFrame not found');
406
+ }
407
+ }
408
+
409
+ var
410
+ hash = location.split('#')[1] || '',
411
+ hashData = decodeURIComponent(hash),
412
+ target = document.getElementById(hashData) || document.getElementsByName(hashData)[0];
413
+
414
+ if (target){
415
+ jumpToTarget();
416
+ } else if(window.top!==window.self){
417
+ jumpToParent();
418
+ } else {
419
+ log(iframeId,'In page link #'+hash+' not found');
420
+ }
421
+ }
422
+
423
+ function callback(funcName,val){
424
+ return chkCallback(iframeId,funcName,val);
425
+ }
426
+
427
+ function actionMsg(){
428
+
429
+ if(settings[iframeId].firstRun) firstRun();
430
+
431
+ switch(messageData.type){
432
+ case 'close':
433
+ closeIFrame(messageData.iframe);
434
+ break;
435
+ case 'message':
436
+ forwardMsgFromIFrame(getMsgBody(6));
437
+ break;
438
+ case 'scrollTo':
439
+ scrollRequestFromChild(false);
440
+ break;
441
+ case 'scrollToOffset':
442
+ scrollRequestFromChild(true);
443
+ break;
444
+ case 'pageInfo':
445
+ sendPageInfoToIframe(settings[iframeId].iframe,iframeId);
446
+ startPageInfoMonitor();
447
+ break;
448
+ case 'pageInfoStop':
449
+ stopPageInfoMonitor();
450
+ break;
451
+ case 'inPageLink':
452
+ findTarget(getMsgBody(9));
453
+ break;
454
+ case 'reset':
455
+ resetIFrame(messageData);
456
+ break;
457
+ case 'init':
458
+ resizeIFrame();
459
+ callback('initCallback',messageData.iframe);
460
+ callback('resizedCallback',messageData);
461
+ break;
462
+ default:
463
+ resizeIFrame();
464
+ callback('resizedCallback',messageData);
465
+ }
466
+ }
467
+
468
+ function hasSettings(iframeId){
469
+ var retBool = true;
470
+
471
+ if (!settings[iframeId]){
472
+ retBool = false;
473
+ warn(messageData.type + ' No settings for ' + iframeId + '. Message was: ' + msg);
474
+ }
475
+
476
+ return retBool;
477
+ }
478
+
479
+ function iFrameReadyMsgReceived(){
480
+ for (var iframeId in settings){
481
+ trigger('iFrame requested init',createOutgoingMsg(iframeId),document.getElementById(iframeId),iframeId);
482
+ }
483
+ }
484
+
485
+ function firstRun() {
486
+ settings[iframeId].firstRun = false;
487
+ }
488
+
489
+ var
490
+ msg = event.data,
491
+ messageData = {},
492
+ iframeId = null;
493
+
494
+ if('[iFrameResizerChild]Ready' === msg){
495
+ iFrameReadyMsgReceived();
496
+ } else if (isMessageForUs()){
497
+ messageData = processMsg();
498
+ iframeId = logId = messageData.id;
499
+
500
+ if (!isMessageFromMetaParent() && hasSettings(iframeId)){
501
+ log(iframeId,'Received: '+msg);
502
+
503
+ if ( checkIFrameExists() && isMessageFromIFrame() ){
504
+ actionMsg();
505
+ }
506
+ }
507
+ } else {
508
+ info(iframeId,'Ignored: '+msg);
509
+ }
510
+
511
+ }
512
+
513
+
514
+ function chkCallback(iframeId,funcName,val){
515
+ var
516
+ func = null,
517
+ retVal = null;
518
+
519
+ if(settings[iframeId]){
520
+ func = settings[iframeId][funcName];
521
+
522
+ if( 'function' === typeof func){
523
+ retVal = func(val);
524
+ } else {
525
+ throw new TypeError(funcName+' on iFrame['+iframeId+'] is not a function');
526
+ }
527
+ }
528
+
529
+ return retVal;
530
+ }
531
+
532
+ function closeIFrame(iframe){
533
+ var iframeId = iframe.id;
534
+
535
+ log(iframeId,'Removing iFrame: '+iframeId);
536
+ iframe.parentNode.removeChild(iframe);
537
+ chkCallback(iframeId,'closedCallback',iframeId);
538
+ log(iframeId,'--');
539
+ delete settings[iframeId];
540
+ }
541
+
542
+ function getPagePosition(iframeId){
543
+ if(null === pagePosition){
544
+ pagePosition = {
545
+ x: (window.pageXOffset !== undefined) ? window.pageXOffset : document.documentElement.scrollLeft,
546
+ y: (window.pageYOffset !== undefined) ? window.pageYOffset : document.documentElement.scrollTop
547
+ };
548
+ log(iframeId,'Get page position: '+pagePosition.x+','+pagePosition.y);
549
+ }
550
+ }
551
+
552
+ function setPagePosition(iframeId){
553
+ if(null !== pagePosition){
554
+ window.scrollTo(pagePosition.x,pagePosition.y);
555
+ log(iframeId,'Set page position: '+pagePosition.x+','+pagePosition.y);
556
+ unsetPagePosition();
557
+ }
558
+ }
559
+
560
+ function unsetPagePosition(){
561
+ pagePosition = null;
562
+ }
563
+
564
+ function resetIFrame(messageData){
565
+ function reset(){
566
+ setSize(messageData);
567
+ trigger('reset','reset',messageData.iframe,messageData.id);
568
+ }
569
+
570
+ log(messageData.id,'Size reset requested by '+('init'===messageData.type?'host page':'iFrame'));
571
+ getPagePosition(messageData.id);
572
+ syncResize(reset,messageData,'reset');
573
+ }
574
+
575
+ function setSize(messageData){
576
+ function setDimension(dimension){
577
+ messageData.iframe.style[dimension] = messageData[dimension] + 'px';
578
+ log(
579
+ messageData.id,
580
+ 'IFrame (' + iframeId +
581
+ ') ' + dimension +
582
+ ' set to ' + messageData[dimension] + 'px'
583
+ );
584
+ }
585
+
586
+ function chkZero(dimension){
587
+ //FireFox sets dimension of hidden iFrames to zero.
588
+ //So if we detect that set up an event to check for
589
+ //when iFrame becomes visible.
590
+
591
+ /* istanbul ignore next */ //Not testable in PhantomJS
592
+ if (!hiddenCheckEnabled && '0' === messageData[dimension]){
593
+ hiddenCheckEnabled = true;
594
+ log(iframeId,'Hidden iFrame detected, creating visibility listener');
595
+ fixHiddenIFrames();
596
+ }
597
+ }
598
+
599
+ function processDimension(dimension){
600
+ setDimension(dimension);
601
+ chkZero(dimension);
602
+ }
603
+
604
+ var iframeId = messageData.iframe.id;
605
+
606
+ if(settings[iframeId]){
607
+ if( settings[iframeId].sizeHeight) { processDimension('height'); }
608
+ if( settings[iframeId].sizeWidth ) { processDimension('width'); }
609
+ }
610
+ }
611
+
612
+ function syncResize(func,messageData,doNotSync){
613
+ /* istanbul ignore if */ //Not testable in PhantomJS
614
+ if(doNotSync!==messageData.type && requestAnimationFrame){
615
+ log(messageData.id,'Requesting animation frame');
616
+ requestAnimationFrame(func);
617
+ } else {
618
+ func();
619
+ }
620
+ }
621
+
622
+ function trigger(calleeMsg,msg,iframe,id){
623
+ function postMessageToIFrame(){
624
+ var target = settings[id].targetOrigin;
625
+ log(id,'[' + calleeMsg + '] Sending msg to iframe['+id+'] ('+msg+') targetOrigin: '+target);
626
+ iframe.contentWindow.postMessage( msgId + msg, target );
627
+ }
628
+
629
+ function iFrameNotFound(){
630
+ info(id,'[' + calleeMsg + '] IFrame('+id+') not found');
631
+ if(settings[id]) {
632
+ delete settings[id];
633
+ }
634
+ }
635
+
636
+ function chkAndSend(){
637
+ if(iframe && 'contentWindow' in iframe && (null !== iframe.contentWindow)){ //Null test for PhantomJS
638
+ postMessageToIFrame();
639
+ } else {
640
+ iFrameNotFound();
641
+ }
642
+ }
643
+
644
+ id = id || iframe.id;
645
+
646
+ if(settings[id]) {
647
+ chkAndSend();
648
+ }
649
+
650
+ }
651
+
652
+ function createOutgoingMsg(iframeId){
653
+ return iframeId +
654
+ ':' + settings[iframeId].bodyMarginV1 +
655
+ ':' + settings[iframeId].sizeWidth +
656
+ ':' + settings[iframeId].log +
657
+ ':' + settings[iframeId].interval +
658
+ ':' + settings[iframeId].enablePublicMethods +
659
+ ':' + settings[iframeId].autoResize +
660
+ ':' + settings[iframeId].bodyMargin +
661
+ ':' + settings[iframeId].heightCalculationMethod +
662
+ ':' + settings[iframeId].bodyBackground +
663
+ ':' + settings[iframeId].bodyPadding +
664
+ ':' + settings[iframeId].tolerance +
665
+ ':' + settings[iframeId].inPageLinks +
666
+ ':' + settings[iframeId].resizeFrom +
667
+ ':' + settings[iframeId].widthCalculationMethod;
668
+ }
669
+
670
+ function setupIFrame(iframe,options){
671
+ function setLimits(){
672
+ function addStyle(style){
673
+ if ((Infinity !== settings[iframeId][style]) && (0 !== settings[iframeId][style])){
674
+ iframe.style[style] = settings[iframeId][style] + 'px';
675
+ log(iframeId,'Set '+style+' = '+settings[iframeId][style]+'px');
676
+ }
677
+ }
678
+
679
+ function chkMinMax(dimension){
680
+ if (settings[iframeId]['min'+dimension]>settings[iframeId]['max'+dimension]){
681
+ throw new Error('Value for min'+dimension+' can not be greater than max'+dimension);
682
+ }
683
+ }
684
+
685
+ chkMinMax('Height');
686
+ chkMinMax('Width');
687
+
688
+ addStyle('maxHeight');
689
+ addStyle('minHeight');
690
+ addStyle('maxWidth');
691
+ addStyle('minWidth');
692
+ }
693
+
694
+ function newId(){
695
+ var id = ((options && options.id) || defaults.id + count++);
696
+ if (null!==document.getElementById(id)){
697
+ id = id + count++;
698
+ }
699
+ return id;
700
+ }
701
+
702
+ function ensureHasId(iframeId){
703
+ logId=iframeId;
704
+ if (''===iframeId){
705
+ iframe.id = iframeId = newId();
706
+ logEnabled = (options || {}).log;
707
+ logId=iframeId;
708
+ log(iframeId,'Added missing iframe ID: '+ iframeId +' (' + iframe.src + ')');
709
+ }
710
+
711
+
712
+ return iframeId;
713
+ }
714
+
715
+ function setScrolling(){
716
+ log(iframeId,'IFrame scrolling ' + (settings[iframeId].scrolling ? 'enabled' : 'disabled') + ' for ' + iframeId);
717
+ iframe.style.overflow = false === settings[iframeId].scrolling ? 'hidden' : 'auto';
718
+ iframe.scrolling = false === settings[iframeId].scrolling ? 'no' : 'yes';
719
+ }
720
+
721
+ //The V1 iFrame script expects an int, where as in V2 expects a CSS
722
+ //string value such as '1px 3em', so if we have an int for V2, set V1=V2
723
+ //and then convert V2 to a string PX value.
724
+ function setupBodyMarginValues(){
725
+ if (('number'===typeof(settings[iframeId].bodyMargin)) || ('0'===settings[iframeId].bodyMargin)){
726
+ settings[iframeId].bodyMarginV1 = settings[iframeId].bodyMargin;
727
+ settings[iframeId].bodyMargin = '' + settings[iframeId].bodyMargin + 'px';
728
+ }
729
+ }
730
+
731
+ function checkReset(){
732
+ // Reduce scope of firstRun to function, because IE8's JS execution
733
+ // context stack is borked and this value gets externally
734
+ // changed midway through running this function!!!
735
+ var
736
+ firstRun = settings[iframeId].firstRun,
737
+ resetRequertMethod = settings[iframeId].heightCalculationMethod in resetRequiredMethods;
738
+
739
+ if (!firstRun && resetRequertMethod){
740
+ resetIFrame({iframe:iframe, height:0, width:0, type:'init'});
741
+ }
742
+ }
743
+
744
+ function setupIFrameObject(){
745
+ if(Function.prototype.bind){ //Ignore unpolyfilled IE8.
746
+ settings[iframeId].iframe.iFrameResizer = {
747
+
748
+ close : closeIFrame.bind(null,settings[iframeId].iframe),
749
+
750
+ resize : trigger.bind(null,'Window resize', 'resize', settings[iframeId].iframe),
751
+
752
+ moveToAnchor : function(anchor){
753
+ trigger('Move to anchor','moveToAnchor:'+anchor, settings[iframeId].iframe,iframeId);
754
+ },
755
+
756
+ sendMessage : function(message){
757
+ message = JSON.stringify(message);
758
+ trigger('Send Message','message:'+message, settings[iframeId].iframe,iframeId);
759
+ }
760
+ };
761
+ }
762
+ }
763
+
764
+ //We have to call trigger twice, as we can not be sure if all
765
+ //iframes have completed loading when this code runs. The
766
+ //event listener also catches the page changing in the iFrame.
767
+ function init(msg){
768
+ function iFrameLoaded(){
769
+ trigger('iFrame.onload',msg,iframe);
770
+ checkReset();
771
+ }
772
+
773
+ addEventListener(iframe,'load',iFrameLoaded);
774
+ trigger('init',msg,iframe);
775
+ }
776
+
777
+ function checkOptions(options){
778
+ if ('object' !== typeof options){
779
+ throw new TypeError('Options is not an object');
780
+ }
781
+ }
782
+
783
+ function copyOptions(options){
784
+ for (var option in defaults) {
785
+ if (defaults.hasOwnProperty(option)){
786
+ settings[iframeId][option] = options.hasOwnProperty(option) ? options[option] : defaults[option];
787
+ }
788
+ }
789
+ }
790
+
791
+ function getTargetOrigin (remoteHost){
792
+ return ('' === remoteHost || 'file://' === remoteHost) ? '*' : remoteHost;
793
+ }
794
+
795
+ function processOptions(options){
796
+ options = options || {};
797
+ settings[iframeId] = {
798
+ firstRun : true,
799
+ iframe : iframe,
800
+ remoteHost : iframe.src.split('/').slice(0,3).join('/')
801
+ };
802
+
803
+ checkOptions(options);
804
+ copyOptions(options);
805
+
806
+ settings[iframeId].targetOrigin = true === settings[iframeId].checkOrigin ? getTargetOrigin(settings[iframeId].remoteHost) : '*';
807
+ }
808
+
809
+ function beenHere(){
810
+ return (iframeId in settings && 'iFrameResizer' in iframe);
811
+ }
812
+
813
+ var iframeId = ensureHasId(iframe.id);
814
+
815
+ if (!beenHere()){
816
+ processOptions(options);
817
+ setScrolling();
818
+ setLimits();
819
+ setupBodyMarginValues();
820
+ init(createOutgoingMsg(iframeId));
821
+ setupIFrameObject();
822
+ } else {
823
+ warn(iframeId,'Ignored iFrame, already setup.');
824
+ }
825
+ }
826
+
827
+ function debouce(fn,time){
828
+ if (null === timer){
829
+ timer = setTimeout(function(){
830
+ timer = null;
831
+ fn();
832
+ }, time);
833
+ }
834
+ }
835
+
836
+ /* istanbul ignore next */ //Not testable in PhantomJS
837
+ function fixHiddenIFrames(){
838
+ function checkIFrames(){
839
+ function checkIFrame(settingId){
840
+ function chkDimension(dimension){
841
+ return '0px' === settings[settingId].iframe.style[dimension];
842
+ }
843
+
844
+ function isVisible(el) {
845
+ return (null !== el.offsetParent);
846
+ }
847
+
848
+ if (isVisible(settings[settingId].iframe) && (chkDimension('height') || chkDimension('width'))){
849
+ trigger('Visibility change', 'resize', settings[settingId].iframe,settingId);
850
+ }
851
+ }
852
+
853
+ for (var settingId in settings){
854
+ checkIFrame(settingId);
855
+ }
856
+ }
857
+
858
+ function mutationObserved(mutations){
859
+ log('window','Mutation observed: ' + mutations[0].target + ' ' + mutations[0].type);
860
+ debouce(checkIFrames,16);
861
+ }
862
+
863
+ function createMutationObserver(){
864
+ var
865
+ target = document.querySelector('body'),
866
+
867
+ config = {
868
+ attributes : true,
869
+ attributeOldValue : false,
870
+ characterData : true,
871
+ characterDataOldValue : false,
872
+ childList : true,
873
+ subtree : true
874
+ },
875
+
876
+ observer = new MutationObserver(mutationObserved);
877
+
878
+ observer.observe(target, config);
879
+ }
880
+
881
+ var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
882
+
883
+ if (MutationObserver) createMutationObserver();
884
+ }
885
+
886
+
887
+ function resizeIFrames(event){
888
+ function resize(){
889
+ sendTriggerMsg('Window '+event,'resize');
890
+ }
891
+
892
+ log('window','Trigger event: '+event);
893
+ debouce(resize,16);
894
+ }
895
+
896
+ /* istanbul ignore next */ //Not testable in PhantomJS
897
+ function tabVisible() {
898
+ function resize(){
899
+ sendTriggerMsg('Tab Visable','resize');
900
+ }
901
+
902
+ if('hidden' !== document.visibilityState) {
903
+ log('document','Trigger event: Visiblity change');
904
+ debouce(resize,16);
905
+ }
906
+ }
907
+
908
+ function sendTriggerMsg(eventName,event){
909
+ function isIFrameResizeEnabled(iframeId) {
910
+ return 'parent' === settings[iframeId].resizeFrom &&
911
+ settings[iframeId].autoResize &&
912
+ !settings[iframeId].firstRun;
913
+ }
914
+
915
+ for (var iframeId in settings){
916
+ if(isIFrameResizeEnabled(iframeId)){
917
+ trigger(eventName,event,document.getElementById(iframeId),iframeId);
918
+ }
919
+ }
920
+ }
921
+
922
+ function setupEventListeners(){
923
+ addEventListener(window,'message',iFrameListener);
924
+
925
+ addEventListener(window,'resize', function(){resizeIFrames('resize');});
926
+
927
+ addEventListener(document,'visibilitychange',tabVisible);
928
+ addEventListener(document,'-webkit-visibilitychange',tabVisible); //Andriod 4.4
929
+ addEventListener(window,'focusin',function(){resizeIFrames('focus');}); //IE8-9
930
+ addEventListener(window,'focus',function(){resizeIFrames('focus');});
931
+ }
932
+
933
+
934
+ function factory(){
935
+ function init(options,element){
936
+ function chkType(){
937
+ if(!element.tagName) {
938
+ throw new TypeError('Object is not a valid DOM element');
939
+ } else if ('IFRAME' !== element.tagName.toUpperCase()) {
940
+ throw new TypeError('Expected <IFRAME> tag, found <'+element.tagName+'>');
941
+ }
942
+ }
943
+
944
+ if(element) {
945
+ chkType();
946
+ setupIFrame(element, options);
947
+ iFrames.push(element);
948
+ }
949
+ }
950
+
951
+ var iFrames;
952
+
953
+ setupRequestAnimationFrame();
954
+ setupEventListeners();
955
+
956
+ return function iFrameResizeF(options,target){
957
+ iFrames = []; //Only return iFrames past in on this call
958
+
959
+ switch (typeof(target)){
960
+ case 'undefined':
961
+ case 'string':
962
+ Array.prototype.forEach.call(
963
+ document.querySelectorAll( target || 'iframe' ),
964
+ init.bind(undefined, options)
965
+ );
966
+ break;
967
+ case 'object':
968
+ init(options,target);
969
+ break;
970
+ default:
971
+ throw new TypeError('Unexpected data type ('+typeof(target)+')');
972
+ }
973
+
974
+ return iFrames;
975
+ };
976
+ }
977
+
978
+ function createJQueryPublicMethod($){
979
+ if (!$.fn) {
980
+ info('','Unable to bind to jQuery, it is not fully loaded.');
981
+ } else {
982
+ $.fn.iFrameResize = function $iFrameResizeF(options) {
983
+ function init(index, element) {
984
+ setupIFrame(element, options);
985
+ }
986
+
987
+ return this.filter('iframe').each(init).end();
988
+ };
989
+ }
990
+ }
991
+
992
+ if (window.jQuery) { createJQueryPublicMethod(jQuery); }
993
+
994
+ if (typeof define === 'function' && define.amd) {
995
+ // define([],factory);
996
+ // https://github.com/davidjbradshaw/iframe-resizer/issues/385
997
+ define('iFrameResize',[],factory);
998
+ } else if (typeof module === 'object' && typeof module.exports === 'object') { //Node for browserfy
999
+ module.exports = factory();
1000
+ } else {
1001
+ window.iFrameResize = window.iFrameResize || factory();
1002
+ }
1003
+
1004
+ })(window || {});