renalware-core 2.0.0.pre.beta5 → 2.0.0.pre.beta6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/renalware/session_timeout_redirect.js.erb +8 -4
  3. data/app/assets/stylesheets/renalware/partials/_navigation.scss +2 -2
  4. data/app/controllers/renalware/admin/users_controller.rb +3 -3
  5. data/app/helpers/renalware/application_helper.rb +2 -1
  6. data/app/helpers/renalware/layout_helper.rb +2 -2
  7. data/app/views/renalware/clinical/body_compositions/_form.html.slim +6 -2
  8. data/app/views/renalware/clinical/body_compositions/new.html.slim +4 -3
  9. data/app/views/renalware/clinics/clinic_visits/edit.html.slim +5 -2
  10. data/app/views/renalware/events/swabs/edit.html.slim +4 -2
  11. data/app/views/renalware/hd/historical_profiles/show.html.slim +6 -3
  12. data/app/views/renalware/patients/alerts/_form.html.slim +1 -1
  13. data/app/views/renalware/renal/profiles/edit.html.slim +5 -3
  14. data/app/views/renalware/transplants/donor_operations/edit.html.slim +7 -3
  15. data/lib/breadcrumb.rb +8 -0
  16. data/lib/renalware/version.rb +1 -1
  17. data/vendor/assets/fonts/foundation-icons.eot +0 -0
  18. data/vendor/assets/fonts/foundation-icons.scss +594 -0
  19. data/vendor/assets/fonts/foundation-icons.svg +970 -0
  20. data/vendor/assets/fonts/foundation-icons.ttf +0 -0
  21. data/vendor/assets/fonts/foundation-icons.woff +0 -0
  22. data/vendor/assets/javascripts/renalware/iframeResizer.contentWindow.js +1108 -0
  23. data/vendor/assets/javascripts/renalware/iframeResizer.js +1002 -0
  24. data/vendor/assets/javascripts/renalware/jquery-readyselector.js +17 -0
  25. data/vendor/assets/javascripts/renalware/masonry.min.js +9 -0
  26. data/vendor/assets/javascripts/renalware/modernizr.js +3 -0
  27. data/vendor/assets/javascripts/renalware/mousetrap.js +1044 -0
  28. data/vendor/assets/javascripts/renalware/print.min.js +1 -0
  29. data/vendor/assets/javascripts/renalware/rails.validations.js +660 -0
  30. data/vendor/assets/javascripts/renalware/rails.validations.simple_form.js +46 -0
  31. data/vendor/assets/stylesheets/renalware/print.min.css +1 -0
  32. data/vendor/assets/stylesheets/renalware/select2/css/select2.css +431 -0
  33. data/vendor/assets/stylesheets/renalware/select2/css/select2.min.css +1 -0
  34. data/vendor/xsd/ukrdc/README.md +9 -0
  35. data/vendor/xsd/ukrdc/Schema/Allergies/Allergy.xsd +69 -0
  36. data/vendor/xsd/ukrdc/Schema/ClinicalRelationships/ClinicalRelationship.xsd +27 -0
  37. data/vendor/xsd/ukrdc/Schema/Diagnoses/CauseOfDeath.xsd +32 -0
  38. data/vendor/xsd/ukrdc/Schema/Diagnoses/Diagnosis.xsd +41 -0
  39. data/vendor/xsd/ukrdc/Schema/Diagnoses/RenalDiagnosis.xsd +41 -0
  40. data/vendor/xsd/ukrdc/Schema/Documents/Document.xsd +72 -0
  41. data/vendor/xsd/ukrdc/Schema/Encounters/Encounter.xsd +121 -0
  42. data/vendor/xsd/ukrdc/Schema/Encounters/TransplantList.xsd +108 -0
  43. data/vendor/xsd/ukrdc/Schema/Encounters/Treatment.xsd +207 -0
  44. data/vendor/xsd/ukrdc/Schema/FamilyHistories/FamilyHistory.xsd +42 -0
  45. data/vendor/xsd/ukrdc/Schema/LabOrders/LabOrder.xsd +181 -0
  46. data/vendor/xsd/ukrdc/Schema/Medications/Medication.xsd +88 -0
  47. data/vendor/xsd/ukrdc/Schema/Observations/Observation.xsd +65 -0
  48. data/vendor/xsd/ukrdc/Schema/Patient.xsd +87 -0
  49. data/vendor/xsd/ukrdc/Schema/Procedures/DialysisSession.xsd +61 -0
  50. data/vendor/xsd/ukrdc/Schema/Procedures/Procedure.xsd +38 -0
  51. data/vendor/xsd/ukrdc/Schema/Procedures/Transplant.xsd +160 -0
  52. data/vendor/xsd/ukrdc/Schema/Procedures/VascularAccess.xsd +49 -0
  53. data/vendor/xsd/ukrdc/Schema/ProgramMemberships/ProgramMembership.xsd +46 -0
  54. data/vendor/xsd/ukrdc/Schema/README.md +1 -0
  55. data/vendor/xsd/ukrdc/Schema/SocialHistories/SocialHistory.xsd +15 -0
  56. data/vendor/xsd/ukrdc/Schema/Surveys/Survey.xsd +143 -0
  57. data/vendor/xsd/ukrdc/Schema/Types/ActionCode.xsd +37 -0
  58. data/vendor/xsd/ukrdc/Schema/Types/Address.xsd +67 -0
  59. data/vendor/xsd/ukrdc/Schema/Types/CF_DMD.xsd +27 -0
  60. data/vendor/xsd/ukrdc/Schema/Types/CF_EDTA_COD.xsd +343 -0
  61. data/vendor/xsd/ukrdc/Schema/Types/CF_EDTA_PRD.xsd +356 -0
  62. data/vendor/xsd/ukrdc/Schema/Types/CF_HL7_0004.xsd +76 -0
  63. data/vendor/xsd/ukrdc/Schema/Types/CF_HL7_00204.xsd +46 -0
  64. data/vendor/xsd/ukrdc/Schema/Types/CF_HL7_00206.xsd +41 -0
  65. data/vendor/xsd/ukrdc/Schema/Types/CF_RR1.xsd +567 -0
  66. data/vendor/xsd/ukrdc/Schema/Types/CF_RR23.xsd +82 -0
  67. data/vendor/xsd/ukrdc/Schema/Types/CF_RR7_Discharge.xsd +80 -0
  68. data/vendor/xsd/ukrdc/Schema/Types/CF_RR7_Treatment.xsd +241 -0
  69. data/vendor/xsd/ukrdc/Schema/Types/CF_SNOMED.xsd +27 -0
  70. data/vendor/xsd/ukrdc/Schema/Types/Clinician.xsd +27 -0
  71. data/vendor/xsd/ukrdc/Schema/Types/CodeTableDetail.xsd +27 -0
  72. data/vendor/xsd/ukrdc/Schema/Types/CodedField.xsd +27 -0
  73. data/vendor/xsd/ukrdc/Schema/Types/CommonMetadata.xsd +23 -0
  74. data/vendor/xsd/ukrdc/Schema/Types/ContactDetail.xsd +55 -0
  75. data/vendor/xsd/ukrdc/Schema/Types/DrugProduct.xsd +41 -0
  76. data/vendor/xsd/ukrdc/Schema/Types/EthnicGroup.xsd +114 -0
  77. data/vendor/xsd/ukrdc/Schema/Types/FamilyDoctor.xsd +21 -0
  78. data/vendor/xsd/ukrdc/Schema/Types/LabResultItem.xsd +160 -0
  79. data/vendor/xsd/ukrdc/Schema/Types/LabTestItem.xsd +24 -0
  80. data/vendor/xsd/ukrdc/Schema/Types/Language.xsd +981 -0
  81. data/vendor/xsd/ukrdc/Schema/Types/Location.xsd +27 -0
  82. data/vendor/xsd/ukrdc/Schema/Types/NV_RR14.xsd +39 -0
  83. data/vendor/xsd/ukrdc/Schema/Types/Name.xsd +51 -0
  84. data/vendor/xsd/ukrdc/Schema/Types/Occupation.xsd +75 -0
  85. data/vendor/xsd/ukrdc/Schema/Types/Order.xsd +48 -0
  86. data/vendor/xsd/ukrdc/Schema/Types/PatientNumber.xsd +90 -0
  87. data/vendor/xsd/ukrdc/Schema/Types/PersonalContactType.xsd +11 -0
  88. data/vendor/xsd/ukrdc/Schema/Types/Result.xsd +178 -0
  89. data/vendor/xsd/ukrdc/Schema/UKRDC.xsd +148 -0
  90. metadata +78 -5
  91. data/lib/renalware/breadcrumb.rb +0 -10
@@ -0,0 +1,1108 @@
1
+ /*
2
+ * File: iframeResizer.contentWindow.js
3
+ * Desc: Include this file in any page being loaded into an iframe
4
+ * to force the iframe to resize to the content size.
5
+ * Requires: iframeResizer.js on host page.
6
+ * Doc: https://github.com/davidjbradshaw/iframe-resizer
7
+ * Author: David J. Bradshaw - dave@bradshaw.net
8
+ * Contributor: Jure Mav - jure.mav@gmail.com
9
+ * Contributor: Ian Caunce - ian@hallnet.co.uk
10
+ */
11
+
12
+
13
+ ;(function(window, undefined) {
14
+ 'use strict';
15
+
16
+ var
17
+ autoResize = true,
18
+ base = 10,
19
+ bodyBackground = '',
20
+ bodyMargin = 0,
21
+ bodyMarginStr = '',
22
+ bodyObserver = null,
23
+ bodyPadding = '',
24
+ calculateWidth = false,
25
+ doubleEventList = {'resize':1,'click':1},
26
+ eventCancelTimer = 128,
27
+ firstRun = true,
28
+ height = 1,
29
+ heightCalcModeDefault = 'bodyOffset',
30
+ heightCalcMode = heightCalcModeDefault,
31
+ initLock = true,
32
+ initMsg = '',
33
+ inPageLinks = {},
34
+ interval = 32,
35
+ intervalTimer = null,
36
+ logging = false,
37
+ msgID = '[iFrameSizer]', //Must match host page msg ID
38
+ msgIdLen = msgID.length,
39
+ myID = '',
40
+ observer = null,
41
+ resetRequiredMethods = {max:1,min:1,bodyScroll:1,documentElementScroll:1},
42
+ resizeFrom = 'child',
43
+ sendPermit = true,
44
+ target = window.parent,
45
+ targetOriginDefault = '*',
46
+ tolerance = 0,
47
+ triggerLocked = false,
48
+ triggerLockedTimer = null,
49
+ throttledTimer = 16,
50
+ width = 1,
51
+ widthCalcModeDefault = 'scroll',
52
+ widthCalcMode = widthCalcModeDefault,
53
+ win = window,
54
+ messageCallback = function(){ warn('MessageCallback function not defined'); },
55
+ readyCallback = function(){},
56
+ pageInfoCallback = function(){},
57
+ customCalcMethods = {
58
+ height: function(){
59
+ warn('Custom height calculation function not defined');
60
+ return document.documentElement.offsetHeight;
61
+ },
62
+ width: function(){
63
+ warn('Custom width calculation function not defined');
64
+ return document.body.scrollWidth;
65
+ }
66
+ };
67
+
68
+
69
+ function addEventListener(el,evt,func){
70
+ /* istanbul ignore else */ // Not testable in phantonJS
71
+ if ('addEventListener' in window){
72
+ el.addEventListener(evt,func, false);
73
+ } else if ('attachEvent' in window){ //IE
74
+ el.attachEvent('on'+evt,func);
75
+ }
76
+ }
77
+
78
+ function removeEventListener(el,evt,func){
79
+ /* istanbul ignore else */ // Not testable in phantonJS
80
+ if ('removeEventListener' in window){
81
+ el.removeEventListener(evt,func, false);
82
+ } else if ('detachEvent' in window){ //IE
83
+ el.detachEvent('on'+evt,func);
84
+ }
85
+ }
86
+
87
+ function capitalizeFirstLetter(string) {
88
+ return string.charAt(0).toUpperCase() + string.slice(1);
89
+ }
90
+
91
+ //Based on underscore.js
92
+ function throttle(func) {
93
+ var
94
+ context, args, result,
95
+ timeout = null,
96
+ previous = 0,
97
+ later = function() {
98
+ previous = getNow();
99
+ timeout = null;
100
+ result = func.apply(context, args);
101
+ if (!timeout) {
102
+ context = args = null;
103
+ }
104
+ };
105
+
106
+ return function() {
107
+ var now = getNow();
108
+
109
+ if (!previous) {
110
+ previous = now;
111
+ }
112
+
113
+ var remaining = throttledTimer - (now - previous);
114
+
115
+ context = this;
116
+ args = arguments;
117
+
118
+ if (remaining <= 0 || remaining > throttledTimer) {
119
+ if (timeout) {
120
+ clearTimeout(timeout);
121
+ timeout = null;
122
+ }
123
+
124
+ previous = now;
125
+ result = func.apply(context, args);
126
+
127
+ if (!timeout) {
128
+ context = args = null;
129
+ }
130
+
131
+ } else if (!timeout) {
132
+ timeout = setTimeout(later, remaining);
133
+ }
134
+
135
+ return result;
136
+ };
137
+ }
138
+
139
+ var getNow = Date.now || function() {
140
+ /* istanbul ignore next */ // Not testable in PhantonJS
141
+ return new Date().getTime();
142
+ };
143
+
144
+ function formatLogMsg(msg){
145
+ return msgID + '[' + myID + ']' + ' ' + msg;
146
+ }
147
+
148
+ function log(msg){
149
+ if (logging && ('object' === typeof window.console)){
150
+ console.log(formatLogMsg(msg));
151
+ }
152
+ }
153
+
154
+ function warn(msg){
155
+ if ('object' === typeof window.console){
156
+ console.warn(formatLogMsg(msg));
157
+ }
158
+ }
159
+
160
+
161
+ function init(){
162
+ readDataFromParent();
163
+ log('Initialising iFrame ('+location.href+')');
164
+ readDataFromPage();
165
+ setMargin();
166
+ setBodyStyle('background',bodyBackground);
167
+ setBodyStyle('padding',bodyPadding);
168
+ injectClearFixIntoBodyElement();
169
+ checkHeightMode();
170
+ checkWidthMode();
171
+ stopInfiniteResizingOfIFrame();
172
+ setupPublicMethods();
173
+ startEventListeners();
174
+ inPageLinks = setupInPageLinks();
175
+ sendSize('init','Init message from host page');
176
+ readyCallback();
177
+ }
178
+
179
+ function readDataFromParent(){
180
+
181
+ function strBool(str){
182
+ return 'true' === str ? true : false;
183
+ }
184
+
185
+ var data = initMsg.substr(msgIdLen).split(':');
186
+
187
+ myID = data[0];
188
+ bodyMargin = (undefined !== data[1]) ? Number(data[1]) : bodyMargin; //For V1 compatibility
189
+ calculateWidth = (undefined !== data[2]) ? strBool(data[2]) : calculateWidth;
190
+ logging = (undefined !== data[3]) ? strBool(data[3]) : logging;
191
+ interval = (undefined !== data[4]) ? Number(data[4]) : interval;
192
+ autoResize = (undefined !== data[6]) ? strBool(data[6]) : autoResize;
193
+ bodyMarginStr = data[7];
194
+ heightCalcMode = (undefined !== data[8]) ? data[8] : heightCalcMode;
195
+ bodyBackground = data[9];
196
+ bodyPadding = data[10];
197
+ tolerance = (undefined !== data[11]) ? Number(data[11]) : tolerance;
198
+ inPageLinks.enable = (undefined !== data[12]) ? strBool(data[12]): false;
199
+ resizeFrom = (undefined !== data[13]) ? data[13] : resizeFrom;
200
+ widthCalcMode = (undefined !== data[14]) ? data[14] : widthCalcMode;
201
+ }
202
+
203
+ function readDataFromPage(){
204
+ function readData(){
205
+ var data = window.iFrameResizer;
206
+
207
+ log('Reading data from page: ' + JSON.stringify(data));
208
+
209
+ messageCallback = ('messageCallback' in data) ? data.messageCallback : messageCallback;
210
+ readyCallback = ('readyCallback' in data) ? data.readyCallback : readyCallback;
211
+ targetOriginDefault = ('targetOrigin' in data) ? data.targetOrigin : targetOriginDefault;
212
+ heightCalcMode = ('heightCalculationMethod' in data) ? data.heightCalculationMethod : heightCalcMode;
213
+ widthCalcMode = ('widthCalculationMethod' in data) ? data.widthCalculationMethod : widthCalcMode;
214
+ }
215
+
216
+ function setupCustomCalcMethods(calcMode, calcFunc){
217
+ if ('function' === typeof calcMode) {
218
+ log('Setup custom ' + calcFunc + 'CalcMethod');
219
+ customCalcMethods[calcFunc] = calcMode;
220
+ calcMode = 'custom';
221
+ }
222
+
223
+ return calcMode;
224
+ }
225
+
226
+ if(('iFrameResizer' in window) && (Object === window.iFrameResizer.constructor)) {
227
+ readData();
228
+ heightCalcMode = setupCustomCalcMethods(heightCalcMode, 'height');
229
+ widthCalcMode = setupCustomCalcMethods(widthCalcMode, 'width');
230
+ }
231
+
232
+ log('TargetOrigin for parent set to: ' + targetOriginDefault);
233
+ }
234
+
235
+
236
+ function chkCSS(attr,value){
237
+ if (-1 !== value.indexOf('-')){
238
+ warn('Negative CSS value ignored for '+attr);
239
+ value='';
240
+ }
241
+ return value;
242
+ }
243
+
244
+ function setBodyStyle(attr,value){
245
+ if ((undefined !== value) && ('' !== value) && ('null' !== value)){
246
+ document.body.style[attr] = value;
247
+ log('Body '+attr+' set to "'+value+'"');
248
+ }
249
+ }
250
+
251
+ function setMargin(){
252
+ //If called via V1 script, convert bodyMargin from int to str
253
+ if (undefined === bodyMarginStr){
254
+ bodyMarginStr = bodyMargin+'px';
255
+ }
256
+
257
+ setBodyStyle('margin',chkCSS('margin',bodyMarginStr));
258
+ }
259
+
260
+ function stopInfiniteResizingOfIFrame(){
261
+ document.documentElement.style.height = '';
262
+ document.body.style.height = '';
263
+ log('HTML & body height set to "auto"');
264
+ }
265
+
266
+
267
+ function manageTriggerEvent(options){
268
+ function handleEvent(){
269
+ sendSize(options.eventName,options.eventType);
270
+ }
271
+
272
+ var listener = {
273
+ add: function(eventName){
274
+ addEventListener(window,eventName,handleEvent);
275
+ },
276
+ remove: function(eventName){
277
+ removeEventListener(window,eventName,handleEvent);
278
+ }
279
+ };
280
+
281
+ if(options.eventNames && Array.prototype.map){
282
+ options.eventName = options.eventNames[0];
283
+ options.eventNames.map(listener[options.method]);
284
+ } else {
285
+ listener[options.method](options.eventName);
286
+ }
287
+
288
+ log(capitalizeFirstLetter(options.method) + ' event listener: ' + options.eventType);
289
+ }
290
+
291
+ function manageEventListeners(method){
292
+ manageTriggerEvent({method:method, eventType: 'Animation Start', eventNames: ['animationstart','webkitAnimationStart'] });
293
+ manageTriggerEvent({method:method, eventType: 'Animation Iteration', eventNames: ['animationiteration','webkitAnimationIteration'] });
294
+ manageTriggerEvent({method:method, eventType: 'Animation End', eventNames: ['animationend','webkitAnimationEnd'] });
295
+ manageTriggerEvent({method:method, eventType: 'Input', eventName: 'input' });
296
+ manageTriggerEvent({method:method, eventType: 'Mouse Up', eventName: 'mouseup' });
297
+ manageTriggerEvent({method:method, eventType: 'Mouse Down', eventName: 'mousedown' });
298
+ manageTriggerEvent({method:method, eventType: 'Orientation Change', eventName: 'orientationchange' });
299
+ manageTriggerEvent({method:method, eventType: 'Print', eventName: ['afterprint', 'beforeprint'] });
300
+ manageTriggerEvent({method:method, eventType: 'Ready State Change', eventName: 'readystatechange' });
301
+ manageTriggerEvent({method:method, eventType: 'Touch Start', eventName: 'touchstart' });
302
+ manageTriggerEvent({method:method, eventType: 'Touch End', eventName: 'touchend' });
303
+ manageTriggerEvent({method:method, eventType: 'Touch Cancel', eventName: 'touchcancel' });
304
+ manageTriggerEvent({method:method, eventType: 'Transition Start', eventNames: ['transitionstart','webkitTransitionStart','MSTransitionStart','oTransitionStart','otransitionstart'] });
305
+ manageTriggerEvent({method:method, eventType: 'Transition Iteration', eventNames: ['transitioniteration','webkitTransitionIteration','MSTransitionIteration','oTransitionIteration','otransitioniteration'] });
306
+ manageTriggerEvent({method:method, eventType: 'Transition End', eventNames: ['transitionend','webkitTransitionEnd','MSTransitionEnd','oTransitionEnd','otransitionend'] });
307
+ if('child' === resizeFrom){
308
+ manageTriggerEvent({method:method, eventType: 'IFrame Resized', eventName: 'resize' });
309
+ }
310
+ }
311
+
312
+ function checkCalcMode(calcMode,calcModeDefault,modes,type){
313
+ if (calcModeDefault !== calcMode){
314
+ if (!(calcMode in modes)){
315
+ warn(calcMode + ' is not a valid option for '+type+'CalculationMethod.');
316
+ calcMode=calcModeDefault;
317
+ }
318
+ log(type+' calculation method set to "'+calcMode+'"');
319
+ }
320
+
321
+ return calcMode;
322
+ }
323
+
324
+ function checkHeightMode(){
325
+ heightCalcMode = checkCalcMode(heightCalcMode,heightCalcModeDefault,getHeight,'height');
326
+ }
327
+
328
+ function checkWidthMode(){
329
+ widthCalcMode = checkCalcMode(widthCalcMode,widthCalcModeDefault,getWidth,'width');
330
+ }
331
+
332
+ function startEventListeners(){
333
+ if ( true === autoResize ) {
334
+ manageEventListeners('add');
335
+ setupMutationObserver();
336
+ }
337
+ else {
338
+ log('Auto Resize disabled');
339
+ }
340
+ }
341
+
342
+ function stopMsgsToParent(){
343
+ log('Disable outgoing messages');
344
+ sendPermit = false;
345
+ }
346
+
347
+ function removeMsgListener(){
348
+ log('Remove event listener: Message');
349
+ removeEventListener(window, 'message', receiver);
350
+ }
351
+
352
+ function disconnectMutationObserver(){
353
+ if (null !== bodyObserver){
354
+ /* istanbul ignore next */ // Not testable in PhantonJS
355
+ bodyObserver.disconnect();
356
+ }
357
+ }
358
+
359
+ function stopEventListeners(){
360
+ manageEventListeners('remove');
361
+ disconnectMutationObserver();
362
+ clearInterval(intervalTimer);
363
+ }
364
+
365
+ function teardown(){
366
+ stopMsgsToParent();
367
+ removeMsgListener();
368
+ if (true === autoResize) stopEventListeners();
369
+ }
370
+
371
+ function injectClearFixIntoBodyElement(){
372
+ var clearFix = document.createElement('div');
373
+ clearFix.style.clear = 'both';
374
+ clearFix.style.display = 'block'; //Guard against this having been globally redefined in CSS.
375
+ document.body.appendChild(clearFix);
376
+ }
377
+
378
+ function setupInPageLinks(){
379
+
380
+ function getPagePosition (){
381
+ return {
382
+ x: (window.pageXOffset !== undefined) ? window.pageXOffset : document.documentElement.scrollLeft,
383
+ y: (window.pageYOffset !== undefined) ? window.pageYOffset : document.documentElement.scrollTop
384
+ };
385
+ }
386
+
387
+ function getElementPosition(el){
388
+ var
389
+ elPosition = el.getBoundingClientRect(),
390
+ pagePosition = getPagePosition();
391
+
392
+ return {
393
+ x: parseInt(elPosition.left,10) + parseInt(pagePosition.x,10),
394
+ y: parseInt(elPosition.top,10) + parseInt(pagePosition.y,10)
395
+ };
396
+ }
397
+
398
+ function findTarget(location){
399
+ function jumpToTarget(target){
400
+ var jumpPosition = getElementPosition(target);
401
+
402
+ log('Moving to in page link (#'+hash+') at x: '+jumpPosition.x+' y: '+jumpPosition.y);
403
+ sendMsg(jumpPosition.y, jumpPosition.x, 'scrollToOffset'); // X&Y reversed at sendMsg uses height/width
404
+ }
405
+
406
+ var
407
+ hash = location.split('#')[1] || location, //Remove # if present
408
+ hashData = decodeURIComponent(hash),
409
+ target = document.getElementById(hashData) || document.getElementsByName(hashData)[0];
410
+
411
+ if (undefined !== target){
412
+ jumpToTarget(target);
413
+ } else {
414
+ log('In page link (#' + hash + ') not found in iFrame, so sending to parent');
415
+ sendMsg(0,0,'inPageLink','#'+hash);
416
+ }
417
+ }
418
+
419
+ function checkLocationHash(){
420
+ if ('' !== location.hash && '#' !== location.hash){
421
+ findTarget(location.href);
422
+ }
423
+ }
424
+
425
+ function bindAnchors(){
426
+ function setupLink(el){
427
+ function linkClicked(e){
428
+ e.preventDefault();
429
+
430
+ /*jshint validthis:true */
431
+ findTarget(this.getAttribute('href'));
432
+ }
433
+
434
+ if ('#' !== el.getAttribute('href')){
435
+ addEventListener(el,'click',linkClicked);
436
+ }
437
+ }
438
+
439
+ Array.prototype.forEach.call( document.querySelectorAll( 'a[href^="#"]' ), setupLink );
440
+ }
441
+
442
+ function bindLocationHash(){
443
+ addEventListener(window,'hashchange',checkLocationHash);
444
+ }
445
+
446
+ function initCheck(){ //check if page loaded with location hash after init resize
447
+ setTimeout(checkLocationHash,eventCancelTimer);
448
+ }
449
+
450
+ function enableInPageLinks(){
451
+ /* istanbul ignore else */ // Not testable in phantonJS
452
+ if(Array.prototype.forEach && document.querySelectorAll){
453
+ log('Setting up location.hash handlers');
454
+ bindAnchors();
455
+ bindLocationHash();
456
+ initCheck();
457
+ } else {
458
+ warn('In page linking not fully supported in this browser! (See README.md for IE8 workaround)');
459
+ }
460
+ }
461
+
462
+ if(inPageLinks.enable){
463
+ enableInPageLinks();
464
+ } else {
465
+ log('In page linking not enabled');
466
+ }
467
+
468
+ return {
469
+ findTarget:findTarget
470
+ };
471
+ }
472
+
473
+ function setupPublicMethods(){
474
+ log('Enable public methods');
475
+
476
+ win.parentIFrame = {
477
+
478
+ autoResize: function autoResizeF(resize){
479
+ if (true === resize && false === autoResize) {
480
+ autoResize=true;
481
+ startEventListeners();
482
+ //sendSize('autoResize','Auto Resize enabled');
483
+ } else if (false === resize && true === autoResize) {
484
+ autoResize=false;
485
+ stopEventListeners();
486
+ }
487
+
488
+ return autoResize;
489
+ },
490
+
491
+ close: function closeF(){
492
+ sendMsg(0,0,'close');
493
+ teardown();
494
+ },
495
+
496
+ getId: function getIdF(){
497
+ return myID;
498
+ },
499
+
500
+ getPageInfo: function getPageInfoF(callback){
501
+ if ('function' === typeof callback){
502
+ pageInfoCallback = callback;
503
+ sendMsg(0,0,'pageInfo');
504
+ } else {
505
+ pageInfoCallback = function(){};
506
+ sendMsg(0,0,'pageInfoStop');
507
+ }
508
+ },
509
+
510
+ moveToAnchor: function moveToAnchorF(hash){
511
+ inPageLinks.findTarget(hash);
512
+ },
513
+
514
+ reset: function resetF(){
515
+ resetIFrame('parentIFrame.reset');
516
+ },
517
+
518
+ scrollTo: function scrollToF(x,y){
519
+ sendMsg(y,x,'scrollTo'); // X&Y reversed at sendMsg uses height/width
520
+ },
521
+
522
+ scrollToOffset: function scrollToF(x,y){
523
+ sendMsg(y,x,'scrollToOffset'); // X&Y reversed at sendMsg uses height/width
524
+ },
525
+
526
+ sendMessage: function sendMessageF(msg,targetOrigin){
527
+ sendMsg(0,0,'message',JSON.stringify(msg),targetOrigin);
528
+ },
529
+
530
+ setHeightCalculationMethod: function setHeightCalculationMethodF(heightCalculationMethod){
531
+ heightCalcMode = heightCalculationMethod;
532
+ checkHeightMode();
533
+ },
534
+
535
+ setWidthCalculationMethod: function setWidthCalculationMethodF(widthCalculationMethod){
536
+ widthCalcMode = widthCalculationMethod;
537
+ checkWidthMode();
538
+ },
539
+
540
+ setTargetOrigin: function setTargetOriginF(targetOrigin){
541
+ log('Set targetOrigin: '+targetOrigin);
542
+ targetOriginDefault = targetOrigin;
543
+ },
544
+
545
+ size: function sizeF(customHeight, customWidth){
546
+ var valString = ''+(customHeight?customHeight:'')+(customWidth?','+customWidth:'');
547
+ //lockTrigger();
548
+ sendSize('size','parentIFrame.size('+valString+')', customHeight, customWidth);
549
+ }
550
+ };
551
+ }
552
+
553
+ function initInterval(){
554
+ if ( 0 !== interval ){
555
+ log('setInterval: '+interval+'ms');
556
+ intervalTimer = setInterval(function(){
557
+ sendSize('interval','setInterval: '+interval);
558
+ },Math.abs(interval));
559
+ }
560
+ }
561
+
562
+ /* istanbul ignore next */ //Not testable in PhantomJS
563
+ function setupBodyMutationObserver(){
564
+ function addImageLoadListners(mutation) {
565
+ function addImageLoadListener(element){
566
+ if (false === element.complete) {
567
+ log('Attach listeners to ' + element.src);
568
+ element.addEventListener('load', imageLoaded, false);
569
+ element.addEventListener('error', imageError, false);
570
+ elements.push(element);
571
+ }
572
+ }
573
+
574
+ if (mutation.type === 'attributes' && mutation.attributeName === 'src'){
575
+ addImageLoadListener(mutation.target);
576
+ } else if (mutation.type === 'childList'){
577
+ Array.prototype.forEach.call(
578
+ mutation.target.querySelectorAll('img'),
579
+ addImageLoadListener
580
+ );
581
+ }
582
+ }
583
+
584
+ function removeFromArray(element){
585
+ elements.splice(elements.indexOf(element),1);
586
+ }
587
+
588
+ function removeImageLoadListener(element){
589
+ log('Remove listeners from ' + element.src);
590
+ element.removeEventListener('load', imageLoaded, false);
591
+ element.removeEventListener('error', imageError, false);
592
+ removeFromArray(element);
593
+ }
594
+
595
+ function imageEventTriggered(event,type,typeDesc){
596
+ removeImageLoadListener(event.target);
597
+ sendSize(type, typeDesc + ': ' + event.target.src, undefined, undefined);
598
+ }
599
+
600
+ function imageLoaded(event) {
601
+ imageEventTriggered(event,'imageLoad','Image loaded');
602
+ }
603
+
604
+ function imageError(event) {
605
+ imageEventTriggered(event,'imageLoadFailed','Image load failed');
606
+ }
607
+
608
+ function mutationObserved(mutations) {
609
+ sendSize('mutationObserver','mutationObserver: ' + mutations[0].target + ' ' + mutations[0].type);
610
+
611
+ //Deal with WebKit asyncing image loading when tags are injected into the page
612
+ mutations.forEach(addImageLoadListners);
613
+ }
614
+
615
+ function createMutationObserver(){
616
+ var
617
+ target = document.querySelector('body'),
618
+
619
+ config = {
620
+ attributes : true,
621
+ attributeOldValue : false,
622
+ characterData : true,
623
+ characterDataOldValue : false,
624
+ childList : true,
625
+ subtree : true
626
+ };
627
+
628
+ observer = new MutationObserver(mutationObserved);
629
+
630
+ log('Create body MutationObserver');
631
+ observer.observe(target, config);
632
+
633
+ return observer;
634
+ }
635
+
636
+ var
637
+ elements = [],
638
+ MutationObserver = window.MutationObserver || window.WebKitMutationObserver,
639
+ observer = createMutationObserver();
640
+
641
+ return {
642
+ disconnect: function (){
643
+ if ('disconnect' in observer){
644
+ log('Disconnect body MutationObserver');
645
+ observer.disconnect();
646
+ elements.forEach(removeImageLoadListener);
647
+ }
648
+ }
649
+ };
650
+ }
651
+
652
+ function setupMutationObserver(){
653
+ var forceIntervalTimer = 0 > interval;
654
+
655
+ /* istanbul ignore if */ // Not testable in PhantomJS
656
+ if (window.MutationObserver || window.WebKitMutationObserver){
657
+ if (forceIntervalTimer) {
658
+ initInterval();
659
+ } else {
660
+ bodyObserver = setupBodyMutationObserver();
661
+ }
662
+ } else {
663
+ log('MutationObserver not supported in this browser!');
664
+ initInterval();
665
+ }
666
+ }
667
+
668
+
669
+ // document.documentElement.offsetHeight is not reliable, so
670
+ // we have to jump through hoops to get a better value.
671
+ function getComputedStyle(prop,el) {
672
+ /* istanbul ignore next */ //Not testable in PhantomJS
673
+ function convertUnitsToPxForIE8(value) {
674
+ var PIXEL = /^\d+(px)?$/i;
675
+
676
+ if (PIXEL.test(value)) {
677
+ return parseInt(value,base);
678
+ }
679
+
680
+ var
681
+ style = el.style.left,
682
+ runtimeStyle = el.runtimeStyle.left;
683
+
684
+ el.runtimeStyle.left = el.currentStyle.left;
685
+ el.style.left = value || 0;
686
+ value = el.style.pixelLeft;
687
+ el.style.left = style;
688
+ el.runtimeStyle.left = runtimeStyle;
689
+
690
+ return value;
691
+ }
692
+
693
+ var retVal = 0;
694
+ el = el || document.body;
695
+
696
+ /* istanbul ignore else */ // Not testable in phantonJS
697
+ if (('defaultView' in document) && ('getComputedStyle' in document.defaultView)) {
698
+ retVal = document.defaultView.getComputedStyle(el, null);
699
+ retVal = (null !== retVal) ? retVal[prop] : 0;
700
+ } else {//IE8
701
+ retVal = convertUnitsToPxForIE8(el.currentStyle[prop]);
702
+ }
703
+
704
+ return parseInt(retVal,base);
705
+ }
706
+
707
+ function chkEventThottle(timer){
708
+ if(timer > throttledTimer/2){
709
+ throttledTimer = 2*timer;
710
+ log('Event throttle increased to ' + throttledTimer + 'ms');
711
+ }
712
+ }
713
+
714
+ //Idea from https://github.com/guardian/iframe-messenger
715
+ function getMaxElement(side,elements) {
716
+ var
717
+ elementsLength = elements.length,
718
+ elVal = 0,
719
+ maxVal = 0,
720
+ Side = capitalizeFirstLetter(side),
721
+ timer = getNow();
722
+
723
+ for (var i = 0; i < elementsLength; i++) {
724
+ elVal = elements[i].getBoundingClientRect()[side] + getComputedStyle('margin'+Side,elements[i]);
725
+ if (elVal > maxVal) {
726
+ maxVal = elVal;
727
+ }
728
+ }
729
+
730
+ timer = getNow() - timer;
731
+
732
+ log('Parsed '+elementsLength+' HTML elements');
733
+ log('Element position calculated in ' + timer + 'ms');
734
+
735
+ chkEventThottle(timer);
736
+
737
+ return maxVal;
738
+ }
739
+
740
+ function getAllMeasurements(dimention){
741
+ return [
742
+ dimention.bodyOffset(),
743
+ dimention.bodyScroll(),
744
+ dimention.documentElementOffset(),
745
+ dimention.documentElementScroll()
746
+ ];
747
+ }
748
+
749
+ function getTaggedElements(side,tag){
750
+ function noTaggedElementsFound(){
751
+ warn('No tagged elements ('+tag+') found on page');
752
+ return height; //current height
753
+ }
754
+
755
+ var elements = document.querySelectorAll('['+tag+']');
756
+
757
+ return 0 === elements.length ? noTaggedElementsFound() : getMaxElement(side,elements);
758
+ }
759
+
760
+ function getAllElements(){
761
+ return document.querySelectorAll('body *');
762
+ }
763
+
764
+ var
765
+ getHeight = {
766
+ bodyOffset: function getBodyOffsetHeight(){
767
+ return document.body.offsetHeight + getComputedStyle('marginTop') + getComputedStyle('marginBottom');
768
+ },
769
+
770
+ offset: function(){
771
+ return getHeight.bodyOffset(); //Backwards compatability
772
+ },
773
+
774
+ bodyScroll: function getBodyScrollHeight(){
775
+ return document.body.scrollHeight;
776
+ },
777
+
778
+ custom: function getCustomWidth(){
779
+ return customCalcMethods.height();
780
+ },
781
+
782
+ documentElementOffset: function getDEOffsetHeight(){
783
+ return document.documentElement.offsetHeight;
784
+ },
785
+
786
+ documentElementScroll: function getDEScrollHeight(){
787
+ return document.documentElement.scrollHeight;
788
+ },
789
+
790
+ max: function getMaxHeight(){
791
+ return Math.max.apply(null,getAllMeasurements(getHeight));
792
+ },
793
+
794
+ min: function getMinHeight(){
795
+ return Math.min.apply(null,getAllMeasurements(getHeight));
796
+ },
797
+
798
+ grow: function growHeight(){
799
+ return getHeight.max(); //Run max without the forced downsizing
800
+ },
801
+
802
+ lowestElement: function getBestHeight(){
803
+ return Math.max(getHeight.bodyOffset(), getMaxElement('bottom',getAllElements()));
804
+ },
805
+
806
+ taggedElement: function getTaggedElementsHeight(){
807
+ return getTaggedElements('bottom','data-iframe-height');
808
+ }
809
+ },
810
+
811
+ getWidth = {
812
+ bodyScroll: function getBodyScrollWidth(){
813
+ return document.body.scrollWidth;
814
+ },
815
+
816
+ bodyOffset: function getBodyOffsetWidth(){
817
+ return document.body.offsetWidth;
818
+ },
819
+
820
+ custom: function getCustomWidth(){
821
+ return customCalcMethods.width();
822
+ },
823
+
824
+ documentElementScroll: function getDEScrollWidth(){
825
+ return document.documentElement.scrollWidth;
826
+ },
827
+
828
+ documentElementOffset: function getDEOffsetWidth(){
829
+ return document.documentElement.offsetWidth;
830
+ },
831
+
832
+ scroll: function getMaxWidth(){
833
+ return Math.max(getWidth.bodyScroll(), getWidth.documentElementScroll());
834
+ },
835
+
836
+ max: function getMaxWidth(){
837
+ return Math.max.apply(null,getAllMeasurements(getWidth));
838
+ },
839
+
840
+ min: function getMinWidth(){
841
+ return Math.min.apply(null,getAllMeasurements(getWidth));
842
+ },
843
+
844
+ rightMostElement: function rightMostElement(){
845
+ return getMaxElement('right', getAllElements());
846
+ },
847
+
848
+ taggedElement: function getTaggedElementsWidth(){
849
+ return getTaggedElements('right', 'data-iframe-width');
850
+ }
851
+ };
852
+
853
+
854
+ function sizeIFrame(triggerEvent, triggerEventDesc, customHeight, customWidth){
855
+
856
+ function resizeIFrame(){
857
+ height = currentHeight;
858
+ width = currentWidth;
859
+
860
+ sendMsg(height,width,triggerEvent);
861
+ }
862
+
863
+ function isSizeChangeDetected(){
864
+ function checkTolarance(a,b){
865
+ var retVal = Math.abs(a-b) <= tolerance;
866
+ return !retVal;
867
+ }
868
+
869
+ currentHeight = (undefined !== customHeight) ? customHeight : getHeight[heightCalcMode]();
870
+ currentWidth = (undefined !== customWidth ) ? customWidth : getWidth[widthCalcMode]();
871
+
872
+ return checkTolarance(height,currentHeight) || (calculateWidth && checkTolarance(width,currentWidth));
873
+ }
874
+
875
+ function isForceResizableEvent(){
876
+ return !(triggerEvent in {'init':1,'interval':1,'size':1});
877
+ }
878
+
879
+ function isForceResizableCalcMode(){
880
+ return (heightCalcMode in resetRequiredMethods) || (calculateWidth && widthCalcMode in resetRequiredMethods);
881
+ }
882
+
883
+ function logIgnored(){
884
+ log('No change in size detected');
885
+ }
886
+
887
+ function checkDownSizing(){
888
+ if (isForceResizableEvent() && isForceResizableCalcMode()){
889
+ resetIFrame(triggerEventDesc);
890
+ } else if (!(triggerEvent in {'interval':1})){
891
+ logIgnored();
892
+ }
893
+ }
894
+
895
+ var currentHeight,currentWidth;
896
+
897
+ if (isSizeChangeDetected() || 'init' === triggerEvent){
898
+ lockTrigger();
899
+ resizeIFrame();
900
+ } else {
901
+ checkDownSizing();
902
+ }
903
+ }
904
+
905
+ var sizeIFrameThrottled = throttle(sizeIFrame);
906
+
907
+ function sendSize(triggerEvent, triggerEventDesc, customHeight, customWidth){
908
+ function recordTrigger(){
909
+ if (!(triggerEvent in {'reset':1,'resetPage':1,'init':1})){
910
+ log( 'Trigger event: ' + triggerEventDesc );
911
+ }
912
+ }
913
+
914
+ function isDoubleFiredEvent(){
915
+ return triggerLocked && (triggerEvent in doubleEventList);
916
+ }
917
+
918
+ if (!isDoubleFiredEvent()){
919
+ recordTrigger();
920
+ sizeIFrameThrottled(triggerEvent, triggerEventDesc, customHeight, customWidth);
921
+ } else {
922
+ log('Trigger event cancelled: '+triggerEvent);
923
+ }
924
+ }
925
+
926
+ function lockTrigger(){
927
+ if (!triggerLocked){
928
+ triggerLocked = true;
929
+ log('Trigger event lock on');
930
+ }
931
+ clearTimeout(triggerLockedTimer);
932
+ triggerLockedTimer = setTimeout(function(){
933
+ triggerLocked = false;
934
+ log('Trigger event lock off');
935
+ log('--');
936
+ },eventCancelTimer);
937
+ }
938
+
939
+ function triggerReset(triggerEvent){
940
+ height = getHeight[heightCalcMode]();
941
+ width = getWidth[widthCalcMode]();
942
+
943
+ sendMsg(height,width,triggerEvent);
944
+ }
945
+
946
+ function resetIFrame(triggerEventDesc){
947
+ var hcm = heightCalcMode;
948
+ heightCalcMode = heightCalcModeDefault;
949
+
950
+ log('Reset trigger event: ' + triggerEventDesc);
951
+ lockTrigger();
952
+ triggerReset('reset');
953
+
954
+ heightCalcMode = hcm;
955
+ }
956
+
957
+ function sendMsg(height,width,triggerEvent,msg,targetOrigin){
958
+ function setTargetOrigin(){
959
+ if (undefined === targetOrigin){
960
+ targetOrigin = targetOriginDefault;
961
+ } else {
962
+ log('Message targetOrigin: '+targetOrigin);
963
+ }
964
+ }
965
+
966
+ function sendToParent(){
967
+ var
968
+ size = height + ':' + width,
969
+ message = myID + ':' + size + ':' + triggerEvent + (undefined !== msg ? ':' + msg : '');
970
+
971
+ log('Sending message to host page (' + message + ')');
972
+ target.postMessage( msgID + message, targetOrigin);
973
+ }
974
+
975
+ if(true === sendPermit){
976
+ setTargetOrigin();
977
+ sendToParent();
978
+ }
979
+ }
980
+
981
+ function receiver(event) {
982
+ function isMessageForUs(){
983
+ return msgID === (''+event.data).substr(0,msgIdLen); //''+ Protects against non-string messages
984
+ }
985
+
986
+ function initFromParent(){
987
+ function fireInit(){
988
+ initMsg = event.data;
989
+ target = event.source;
990
+
991
+ init();
992
+ firstRun = false;
993
+ setTimeout(function(){ initLock = false;},eventCancelTimer);
994
+ }
995
+
996
+ if (document.body){
997
+ fireInit();
998
+ } else {
999
+ log('Waiting for page ready');
1000
+ addEventListener(window,'readystatechange',initFromParent);
1001
+ }
1002
+ }
1003
+
1004
+ function resetFromParent(){
1005
+ if (!initLock){
1006
+ log('Page size reset by host page');
1007
+ triggerReset('resetPage');
1008
+ } else {
1009
+ log('Page reset ignored by init');
1010
+ }
1011
+ }
1012
+
1013
+ function resizeFromParent(){
1014
+ sendSize('resizeParent','Parent window requested size check');
1015
+ }
1016
+
1017
+ function moveToAnchor(){
1018
+ var anchor = getData();
1019
+ inPageLinks.findTarget(anchor);
1020
+ }
1021
+
1022
+ function getMessageType(){
1023
+ return event.data.split(']')[1].split(':')[0];
1024
+ }
1025
+
1026
+ function getData(){
1027
+ return event.data.substr(event.data.indexOf(':')+1);
1028
+ }
1029
+
1030
+ function isMiddleTier(){
1031
+ return ('iFrameResize' in window);
1032
+ }
1033
+
1034
+ function messageFromParent(){
1035
+ var msgBody = getData();
1036
+
1037
+ log('MessageCallback called from parent: ' + msgBody );
1038
+ messageCallback(JSON.parse(msgBody));
1039
+ log(' --');
1040
+ }
1041
+
1042
+ function pageInfoFromParent(){
1043
+ var msgBody = getData();
1044
+ log('PageInfoFromParent called from parent: ' + msgBody );
1045
+ pageInfoCallback(JSON.parse(msgBody));
1046
+ log(' --');
1047
+ }
1048
+
1049
+ function isInitMsg(){
1050
+ //Test if this message is from a child below us. This is an ugly test, however, updating
1051
+ //the message format would break backwards compatibity.
1052
+ return event.data.split(':')[2] in {'true':1,'false':1};
1053
+ }
1054
+
1055
+ function callFromParent(){
1056
+ switch (getMessageType()){
1057
+ case 'reset':
1058
+ resetFromParent();
1059
+ break;
1060
+ case 'resize':
1061
+ resizeFromParent();
1062
+ break;
1063
+ case 'inPageLink':
1064
+ case 'moveToAnchor':
1065
+ moveToAnchor();
1066
+ break;
1067
+ case 'message':
1068
+ messageFromParent();
1069
+ break;
1070
+ case 'pageInfo':
1071
+ pageInfoFromParent();
1072
+ break;
1073
+ default:
1074
+ if (!isMiddleTier() && !isInitMsg()){
1075
+ warn('Unexpected message ('+event.data+')');
1076
+ }
1077
+ }
1078
+ }
1079
+
1080
+ function processMessage(){
1081
+ if (false === firstRun) {
1082
+ callFromParent();
1083
+ } else if (isInitMsg()) {
1084
+ initFromParent();
1085
+ } else {
1086
+ log('Ignored message of type "' + getMessageType() + '". Received before initialization.');
1087
+ }
1088
+ }
1089
+
1090
+ if (isMessageForUs()){
1091
+ processMessage();
1092
+ }
1093
+ }
1094
+
1095
+ //Normally the parent kicks things off when it detects the iFrame has loaded.
1096
+ //If this script is async-loaded, then tell parent page to retry init.
1097
+ function chkLateLoaded(){
1098
+ if('loading' !== document.readyState){
1099
+ window.parent.postMessage('[iFrameResizerChild]Ready','*');
1100
+ }
1101
+ }
1102
+
1103
+ addEventListener(window, 'message', receiver);
1104
+ chkLateLoaded();
1105
+
1106
+
1107
+
1108
+ })(window || {});