broadcast2html.js 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. // sadly embedding this into broadcast2html.xslt doesn't work for Opera -
  2. // the 'if( now < dtstart )' ends up html escaped...
  3. function amendClickableURLsInHTML(html) {
  4. // inspired by http://stackoverflow.com/a/3809435
  5. // Does not pick up naked domains, because they're hard to distinguish from domains in email addresses (see below).
  6. // Also requires a 2-4 character TLD, so the new 'hip' domains fail.
  7. var pat = /[-_.a-z0-9]{2,256}\.[a-z]{2,4}(?:\/[a-z0-9:%_\+.~#?&\/=]*)?/;
  8. var url_pat = new RegExp(/([\s\(\/])/.source + '(' + /(?:http(s?):\/\/)?/.source + '(' + pat.source + ')' + ')', 'gi');
  9. html = html.replace(url_pat, '$1<a href="http$3://$4" class="magic">$2</a>');
  10. var pat1 = /[-a-z0-9%_\+.~#\/=]+@[-a-z0-9%_\+.~#?&\/=]{2,256}\.[a-z]{2,4}(?:\?[-a-z0-9:%_\+.~#?&\/=]*)?/;
  11. var mail_pat = new RegExp(/(?:mailto:)?/.source + '(' + pat1.source + ')', 'gi');
  12. html = html.replace(mail_pat, '<a href="mailto:$1?subject=' + encodeURI(document.location) + '" class="magic">$&</a>');
  13. return html;
  14. }
  15. function amendClickableURLs(element) {
  16. if( null == element )
  17. return;
  18. element.innerHTML = amendClickableURLsInHTML(element.innerHTML)
  19. }
  20. amendClickableURLs(document.getElementById('content'));
  21. // moment.lang("de");
  22. var canonical_url = ('' + window.location).replace(/(\.xml)?(\.gz)?(#.*)?$/,'');
  23. {
  24. var x = document.querySelectorAll('.canonical-url');
  25. for(var i = x.length - 1; i >= 0; i--)
  26. x[i].textContent = canonical_url;
  27. }
  28. {
  29. var x = document.querySelectorAll('.base-url');
  30. for(var i = x.length - 1; i >= 0; i--)
  31. x[i].textContent = canonical_url.replace(/\/stations\/[^\/]+\/\d{4}\/\d{2}\/\d{2}\/(index|\d{4}%20.+)$/, '');
  32. }
  33. var canonical_path = window.location.pathname.replace(/\.xml$/,'');
  34. var dtstart = moment( document.querySelectorAll("meta[name='DC.format.timestart']")[0].getAttribute('content') );
  35. var dtend = moment( document.querySelectorAll("meta[name='DC.format.timeend']")[0].getAttribute('content') );
  36. var now = moment();
  37. {
  38. var clz = 'is_past';
  39. if( now < dtstart )
  40. clz = 'is_future';
  41. else if( now < dtend )
  42. clz = 'is_current';
  43. document.getElementsByTagName('html')[0].classList.add(clz);
  44. }
  45. console.log('display podcast links');
  46. var podasts_json_url = canonical_path + '.json';
  47. var httpRequest = new XMLHttpRequest();
  48. httpRequest.onreadystatechange = function(data0) {
  49. if (httpRequest.readyState == 4) {
  50. if (httpRequest.status >= 200 && httpRequest.status < 300) {
  51. console.log('display mp3/enclosure dir link');
  52. var enclosure_mp3_url = canonical_path.replace(/\/stations\//,'/enclosures/') + '.mp3';
  53. var enclosure_dir_url = enclosure_mp3_url.replace(/[^\/]+$/,'');
  54. document.getElementById('enclosure_link').setAttribute('href', enclosure_dir_url);
  55. // next check the existence of the mp3:
  56. var http1 = new XMLHttpRequest();
  57. http1.onreadystatechange = function(data1) {
  58. if (http1.readyState == 4) {
  59. if (http1.status >= 200 && http1.status < 300) {
  60. console.log('Yikes, there is a mp3!');
  61. document.getElementsByTagName('html')[0].classList.add('has_enclosure_mp3');
  62. document.getElementById('enclosure_link').setAttribute('href', enclosure_mp3_url);
  63. document.getElementById('enclosure_link').setAttribute('title', "Download: Rechte Maustaste + 'Speichern unter...'");
  64. // document.querySelectorAll('#enclosure audio source')[0].setAttribute('src', enclosure_mp3_url);
  65. document.getElementById('enclosure').setAttribute('style', 'display:block');
  66. }
  67. }
  68. }
  69. http1.open('HEAD', enclosure_mp3_url);
  70. http1.send(null);
  71. // and also care about the other (recording etc.) buttons
  72. var data = JSON.parse(httpRequest.responseText);
  73. var has_ad_hoc = false;
  74. var names = data.podcasts.map( function(pc) {
  75. has_ad_hoc = has_ad_hoc || (pc.name == 'ad_hoc');
  76. return '<a href="../../../../../podcasts/' + pc.name + '/">' + pc.name + '</a>';
  77. });
  78. document.getElementById('podcasts').innerHTML = names.join(', ');
  79. if( names.length == 0 ) {
  80. ;
  81. } else {
  82. // $( 'p#enclosure' ).attr('style', 'display:block');
  83. document.getElementsByTagName('html')[0].classList.add('has_podcast');
  84. if( has_ad_hoc ) {
  85. document.getElementById('ad_hoc_action').setAttribute('name', 'remove');
  86. document.getElementById('ad_hoc_submit').setAttribute('value', 'Nicht Aufnehmen');
  87. } else {
  88. document.getElementById('ad_hoc_submit').setAttribute('style', 'display:none');
  89. }
  90. }
  91. }
  92. }
  93. }
  94. httpRequest.open('GET', podasts_json_url);
  95. httpRequest.send(null);
  96. console.log('make date time human readable');
  97. function timeFromTitle(selector, fmt) {
  98. var elems = document.querySelectorAll(selector);
  99. for(var i = elems.length - 1; i >= 0; i--)
  100. elems[i].textContent = moment( elems[i].getAttribute('title') ).format(fmt);
  101. }
  102. timeFromTitle('.moment_date_time', 'ddd D[.] MMM YYYY HH:mm');
  103. timeFromTitle('.moment_date', 'ddd D[.] MMM YYYY');
  104. timeFromTitle('.moment_time', 'HH:mm');
  105. console.log('rewrite today/tomorrow links');
  106. document.getElementById('prev_week').setAttribute('href', '../../../' + moment(dtstart).subtract(7, 'days').format() );
  107. document.getElementById('yesterday').setAttribute('href', '../../../' + moment(dtstart).subtract(1, 'days').format() );
  108. document.getElementById('tomorrow' ).setAttribute('href', '../../../' + moment(dtstart).add(1, 'days').format() );
  109. document.getElementById('next_week').setAttribute('href', '../../../' + moment(dtstart).add(7, 'days').format() );
  110. // todo: mark current station
  111. // step 1: what is the current station?
  112. // step 2: iterate all ul#whatsonnow li and mark the according on with class is_current
  113. function finishAlldayCurrentEntry(a) {
  114. // a.removeClass('is_past').addClass('is_current').append( jQuery('<span/>').text('jetzt') );
  115. a.classList.remove('is_past');
  116. a.classList.add('is_current');
  117. var span = document.createElement('span');
  118. span.textContent = 'jetzt';
  119. a.appendChild(span);
  120. }
  121. console.log('add other broadcasts of the day (same station)');
  122. var http2 = new XMLHttpRequest();
  123. http2.onload = function() {
  124. // console.log('GET ' + http2.responseURL + ' ' + http2.status);
  125. if (http2.status >= 200 && http2.status < 400) {
  126. var parent = document.getElementById('allday');
  127. parent.removeChild(parent.firstChild);
  128. var hasRecording = false;
  129. var pastBC = null;
  130. var allA = new DOMParser().parseFromString(http2.responseText, 'text/html').getElementsByTagName('a');
  131. for(var i = 0; i < allA.length; i++) {
  132. var src = allA[i];
  133. var href = src.getAttribute('href');
  134. var me = document.createElement('a');
  135. me.textContent = src.textContent;
  136. var li = document.createElement('li');
  137. li.appendChild(me);
  138. // console.log(i + ' ' + href);
  139. if( '../' === href ) // ignore parent link
  140. continue;
  141. if( hasRecording ) // previous entry was a .json recording marker
  142. me.classList.add('has_podcast');
  143. if( hasRecording = href.endsWith('.json') ) // remember and swallow .json
  144. continue;
  145. var txt = me.textContent.replace(/\.xml$/i, '');
  146. var ma = txt.match(/^(\d{2})(\d{2})\s+(.*?)$/); // extract time and title
  147. if( ma ) {
  148. var t0 = dtstart.hours(ma[1]).minutes(ma[2]).seconds(0); // assumes same day
  149. me.getAttribute('title', t0.format());
  150. me.textContent = t0.format('HH:mm') + ' ' + ma[3];
  151. // set past/current/future class
  152. if( now < t0 ) {
  153. if(pastBC) {
  154. finishAlldayCurrentEntry(pastBC);
  155. pastBC = null;
  156. }
  157. me.classList.add('is_future');
  158. } else {
  159. pastBC = me;
  160. me.classList.add('is_past');
  161. }
  162. } else {
  163. me.textContent = txt; // index usually.
  164. }
  165. me.setAttribute('href', href.replace(/\.xml$/i, '') ); // make canonical url
  166. parent.appendChild(li);
  167. }
  168. if( pastBC && now < dtstart.hours(24).minutes(0).seconds(0) )
  169. finishAlldayCurrentEntry(pastBC)
  170. parent.setAttribute('style', 'display:block');
  171. }
  172. }
  173. http2.open('GET', '.');
  174. http2.send();