system-7/index_files/playset.js

2 lines
19 KiB
JavaScript

!function(e){var t={};function n(a){if(t[a])return t[a].exports;var r=t[a]={i:a,l:!1,exports:{}};return e[a].call(r.exports,r,r.exports,n),r.l=!0,r.exports}n.m=e,n.c=t,n.d=function(e,t,a){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:a})},n.r=function(e){Object.defineProperty(e,"__esModule",{value:!0})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=138)}({136:function(e,t){e.exports="var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"]) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); } }; }();\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n// Class that iterates over A/V items, playing them in a playlist.\n// JS file can be added to a page and will try to find a place to append a \"Play All\" link.\n// Whatever items the user sees in their page, when they click \"Play All\", will get added to a new\n// playlist and their browser gets redirected to the first item.\n// After each item is finished playing, the browser will redirect to next item, until done.\n// User is free to move around the playlist at any time.\n//\n// xxx better theatre shift code?\n// xxx share/link as modal?\n// xxx cleanup/improve descriptions for description-less items?\n\n\n// convenient, no? Stateless function, global to all Play objects\n// eslint-disable-next-line no-console\nvar log = location.host.substr(0, 4) !== 'www-' ? function () {} : console.log.bind(console);\n\n/* global jwplayer */\n\nvar Playset = function () {\n function Playset() {\n _classCallCheck(this, Playset);\n\n this.id = false;\n this.selector_play_items = false;\n this.selector_playlist = false;\n\n // only proceed for folks w/ modern browsers..\n if (!Playset.is_local_storage_available()) return;\n\n // Check for, in this order:\n // \"SIMILAR ITEMS\" (AKA \"Also Found\") on items /details/ page (at bottom)\n // search results page\n // collection item page\n // We can add a nice \"Play All\" link to any of them.\n //\n // NOTE: for \"SIMILAR ITEMS\", IFF we wanted _more_ than 10, we could add a simple\n // PHP /services/ new script with something like:\n // $rel_ids = (new RelatedItemsFetcher())->fetch($id,$collections,75 0,'5s','production');\n\n this.selector_play_items = $('#also-found h5, #search-actions, .welcome-right');\n this.selector_playlist = $('#theatre-ia-wrap, #search-actions, .welcome-right');\n\n // basically, give up, but in case somehow \"show_playlist()\" fires, dont fatal:\n if (!this.selector_playlist.length) this.selector_playlist = 'body';\n\n if (!this.selector_play_items.length) {\n this.selector_play_items = false;\n } else {\n $(this.selector_play_items).append('<span id=\"playplayset\"/>');\n var htm = React.createElement(\n 'a',\n {\n className: 'stealth',\n href: '#play-items',\n onClick: Playset.create_playlist_goto_first_item,\n 'data-event-click-tracking': 'Playset|PlayAllLink'\n },\n React.createElement('span', { className: 'iconochive-play', 'aria-hidden': 'true' }),\n React.createElement(\n 'span',\n { className: 'sr-only' },\n 'play'\n ),\n React.createElement(\n 'span',\n { className: 'hidden-xs-span' },\n ' Play All'\n ),\n React.createElement('br', null)\n );\n\n ReactDOM.render(htm, $('#playplayset').get(0));\n\n /* this makes it so people can conveniently pass around/share playlists! eg:\n https://archive.org/details/georgeblood&and[]=blues&autoplay=1\n */\n if (Playset.arg('autoplay') && !Playset.arg('playset')) setTimeout(Playset.create_playlist_goto_first_item, 2500);\n }\n\n if (Playset.arg('playset')) {\n var _location$href$match = location.href.match(/archive\\.org\\/details\\/([^/&?]+)/);\n // proceed when item OR collection /details/ page!\n\n\n var _location$href$match2 = _slicedToArray(_location$href$match, 2);\n\n this.id = _location$href$match2[1];\n\n if (!this.id) return;\n\n // setup mobile area\n if (!$('#playset-xs').length) $('#theatre-ia-wrap').after('<div id=\"playset-xs\" class=\"hidden-sm hidden-md hidden-lg\"><div/></div>');\n\n this.show_playlist();\n Playset.skip_unplayable_item();\n\n Playset.resizer();\n }\n\n log('playset ready');\n }\n\n _createClass(Playset, [{\n key: 'show_playlist',\n value: function show_playlist() {\n var _this = this;\n\n var playset = Playset.get_playset();\n var found = false;\n\n var list = '';\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = playset.list[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var v = _step.value;\n\n list += Playset.playlist_item(v[0], v[1], v[2], v[3]);\n if (this.id === v[0]) found = true;\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n if (!found) return; // browser _has_ a playlist, but current item /details/ page isnt in playlist\n\n var htm = '\\n' + Playset.playlist_header(playset) + '\\n<div class=\"playset-list\">\\n' + list + '\\n</div>\\n';\n $('body').addClass('playset');\n $('body').addClass($('#theatre-ia-wrap').length ? '' : ' playset-hdr-only');\n $(this.selector_playlist).prepend('<div id=\"playset-ia\">' + htm + '</div>');\n\n setTimeout(function () {\n _this.autoscroll_playlist();\n }, 500);\n\n // per request, clicking on a bookreader should \"pause\"\n $(document).ready(function () {\n $('#texty iframe').on('load', function () {\n // Make sure iframe is loaded\n $('#texty iframe').contents().click(Playset.pause);\n });\n });\n }\n }, {\n key: 'autoscroll_playlist',\n value: function autoscroll_playlist() {\n // scroll the playlist to the entry that is the /details/item we are are at now\n var off = $('#playset-ia div[data-id=\"' + this.id + '\"').offset();\n if (off) {\n var bump = $('#playset-xs:visible').length ? 10 : $('#navwrap1').height();\n\n var top = off.top - bump - $('#playset-ia .playset-hdr').height();\n\n log('scrolling playset to ', top);\n $('#playset-ia .playset-list').scrollTop(top);\n }\n }\n }], [{\n key: 'create_playlist_goto_first_item',\n value: function create_playlist_goto_first_item(evt) {\n log('create_playlist_goto_first_item()');\n var playlist = [];\n var also_found_clicked = $('#also-found').length;\n var selector_tile_finder = also_found_clicked ? '#also-found .item-ia' : '.item-ia:visible';\n\n $(selector_tile_finder).each(function (key, val) {\n var $val = $(val);\n var id = $val.attr('data-id');\n if (id.match(/^__/)) return; // skip non-items -- eg: __mobile_header__\n\n // find tile title (for either item tile or collection tile)\n var ttl = Playset.truncate($val.find('.item-ttl,.collection-title a').text(), 35);\n var by = Playset.truncate($val.find('.byv').text(), 75);\n var year = $val.attr('data-year');\n var desc = Playset.truncate($val.next().find('.C234 > span:first').text(), 75);\n playlist.push([id, ttl, by.length ? by : desc, year]);\n });\n\n Playset.set_playset(playlist);\n\n if (Playset.mobile) Playset.play_mobile(playlist);else location.href = '/details/' + playlist[0][0] + '&autoplay=1&playset=1';\n\n evt.preventDefault();\n evt.stopPropagation();\n return false;\n }\n }, {\n key: 'play_mobile',\n value: function play_mobile(playlist) {\n // For best experience on iOS, only way to step through a bunch of A/V _automatically_ and in\n // a locked home screen is a (carefully constructed) full-on single M3U playlist.\n // We use a back-end service to construct that for us, and filter out non-audio items\n var ids = [];\n var _iteratorNormalCompletion2 = true;\n var _didIteratorError2 = false;\n var _iteratorError2 = undefined;\n\n try {\n for (var _iterator2 = playlist[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {\n var e = _step2.value;\n // ES6!\n ids.push(e[0]);\n }\n } catch (err) {\n _didIteratorError2 = true;\n _iteratorError2 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion2 && _iterator2.return) {\n _iterator2.return();\n }\n } finally {\n if (_didIteratorError2) {\n throw _iteratorError2;\n }\n }\n }\n\n location.href = 'https://archive.org/services/playset.php?ids=' + ids.join(',');\n }\n }, {\n key: 'resizer',\n value: function resizer() {\n // setup a browser resize / orient change listener\n if (!Playset.resizer_listening) {\n Playset.resizer_listening = true;\n $(window).on('resize orientationchange', function () {\n clearTimeout(Playset.throttler);\n Playset.throttler = setTimeout(Playset.resizer, 250);\n });\n }\n\n // now see where playset \"should be\" -vs- where it is placed right now\n // first see if xs div is visible\n var should_be = $('#playset-xs:visible').length ? 'playset-xs' : 'theatre-ia-wrap';\n var at_now = $('#playset-ia').parent().attr('id');\n log('browser resize: ', should_be, ' -v- ', at_now);\n\n if (should_be === at_now) return; // all set!\n\n if (should_be === 'playset-xs') $('#playset-ia').appendTo('#playset-xs > div');else $('#playset-ia').prependTo('#' + should_be);\n log('playset moved');\n }\n }, {\n key: 'playlist_header',\n value: function playlist_header(playset) {\n var src = playset.src + '&autoplay=1';\n return '\\n<div class=\"playset-hdr\">\\n<div>\\n <a href=' + src + '>Playlist</a>\\n ' + Playset.glyph('beta') + '\\n</div>\\n<div id=\"playset-pp\">\\n <a href=\"#\" onClick=\"return Playset.pause()\">\\n ' + Playset.glyph('Pause') + '\\n </a>\\n <a href=\"#\" onClick=\"return Playset.play()\" style=\"display:none\">\\n ' + Playset.glyph('play') + '\\n </a>\\n</div>\\n<div>\\n <a href=' + src + '>\\n ' + Playset.glyph('share') + '\\n </a>\\n</div>\\n</div>\\n';\n }\n }, {\n key: 'playlist_item',\n value: function playlist_item(id, ttl, desc, year) {\n return '\\n<div class=\"playset-item\" data-id=' + id + '>\\n<a href=\"/details/' + id + '&autoplay=1&playset=1\">\\n <div class=\"topinblock playset-img\">\\n <img src=\"/services/img/' + id + '\"/>\\n </div><div class=\"topinblock\">\\n ' + Playset.item_year(year) + '\\n <b>\\n ' + ttl + '\\n </b><br/>\\n ' + desc + '\\n </div>\\n</a>\\n</div>';\n }\n }, {\n key: 'item_year',\n value: function item_year(year) {\n if (!year) return '';\n\n return '\\n<div style=\"float:right\">\\n(' + year + ')\\n</div>';\n }\n }, {\n key: 'skip_unplayable_item',\n value: function skip_unplayable_item() {\n // after 3 seconds, see if item even tried to load an A/V player.\n // if not, auto-advance to next item\n Playset.unplayable_timer = setTimeout(function () {\n if (typeof jwplayer === 'undefined' || !$(Playset.avplayer).length) Playset.goto_next_item();\n }, 3000);\n }\n }, {\n key: 'goto_next_item',\n value: function goto_next_item() {\n var id = location.href.match(/\\/details\\/([^/&?]+)/)[1];\n var playlist = Playset.get_playlist();\n var prev = '';\n var _iteratorNormalCompletion3 = true;\n var _didIteratorError3 = false;\n var _iteratorError3 = undefined;\n\n try {\n for (var _iterator3 = playlist[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {\n var v = _step3.value;\n\n if (id === prev) location.href = '/details/' + v[0] + '&autoplay=1&playset=1';\n\n var _v = _slicedToArray(v, 1);\n\n prev = _v[0];\n }\n } catch (err) {\n _didIteratorError3 = true;\n _iteratorError3 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion3 && _iterator3.return) {\n _iterator3.return();\n }\n } finally {\n if (_didIteratorError3) {\n throw _iteratorError3;\n }\n }\n }\n }\n }, {\n key: 'onComplete',\n value: function onComplete(jw, evt) {\n // We're in a playlist on an item /details/ page, and A/V player just finished playing a\n // track. If we're \"done\" (whatever that means for an item -- sometimes \"done\" means before\n // all tracks have played!):\n // then auto-advance to next /details/ page item in playlist, with full browser page\n // refresh to it.\n // else noop\n var idx = jw.getPlaylistIndex();\n var len = jw.getPlaylist().length;\n var done = idx + 1 >= len || evt && evt.done;\n if (!done) return; // keep playing until item is finished\n\n Playset.goto_next_item();\n }\n }, {\n key: 'get_playlist',\n value: function get_playlist() {\n // Retrieves current playlist from browser local storage; or null if none or parse errors\n var playset = Playset.get_playset();\n\n if (typeof playset.list === 'undefined') return playset; // version 0.9\n\n return playset.list; // version 1.0\n }\n }, {\n key: 'get_playset',\n value: function get_playset() {\n // Retrieves (entire) playlist (object) from browser local storage;\n // or null if no list or parse errors, etc.\n return JSON.parse(localStorage.getItem('playset'));\n }\n }, {\n key: 'set_playset',\n value: function set_playset(playlist) {\n // Stores playlist into browser local storage.\n // Stamps creation times in case we ever want to expire/trim them if we allow for 2+ playsets.\n var date = new Date();\n var item = {\n version: '1.1',\n src: (location.pathname + location.search).replace(/&autoplay=1/, ''),\n created: date.toJSON(),\n createdTS: Math.round(date.getTime() / 1000),\n list: playlist\n };\n localStorage.setItem('playset', JSON.stringify(item));\n }\n\n // parse a CGI arg\n\n }, {\n key: 'arg',\n value: function arg(theArgName) {\n var try_full = true;\n var sArgs = location.search.slice(1).split('&');\n if (try_full && location.search === '') sArgs = location.href.slice(1).split('&');\n\n var r = '';\n for (var i = 0; i < sArgs.length; i++) {\n if (sArgs[i].slice(0, sArgs[i].indexOf('=')) === theArgName) {\n r = sArgs[i].slice(sArgs[i].indexOf('=') + 1);\n break;\n }\n }\n return r.length > 0 ? unescape(r).split(',') : '';\n }\n }, {\n key: 'pause',\n value: function pause() {\n log('playset pause');\n\n if (typeof jwplayer !== 'undefined' && $(Playset.avplayer).length) {\n var jw = jwplayer(Playset.avplayer.substr(1));\n if (jw && jw.getState()) {\n if (jw.getState().toUpperCase() === 'PLAYING') jw.pause();else jw.play();\n // toggle play to pause icon\n $('#playset-pp a').toggle();\n return false;\n }\n return false;\n }\n\n if (Playset.unplayable_timer) {\n clearTimeout(Playset.unplayable_timer);\n Playset.unplayable_timer = null;\n $('#playset-pp a').toggle();\n }\n\n return false;\n }\n }, {\n key: 'play',\n value: function play() {\n log('play/resume');\n\n if (typeof jwplayer !== 'undefined' && $(Playset.avplayer).length) {\n var jw = jwplayer(Playset.avplayer.substr(1));\n if (jw && jw.getState()) {\n if (jw.getState().toUpperCase() !== 'PLAYING') jw.play();\n // toggle pause to play icon\n $('#playset-pp a').toggle();\n return false;\n }\n return false;\n }\n\n if (!Playset.unplayable_timer) {\n Playset.skip_unplayable_item();\n $('#playset-pp a').toggle();\n }\n\n return false;\n }\n }, {\n key: 'glyph',\n value: function glyph(name) {\n return '<span class=\"iconochive-' + name + '\" aria-hidden=\"true\"></span>\\n <span class=\"sr-only\">' + name + '</span>';\n }\n }, {\n key: 'truncate',\n value: function truncate(str, n) {\n var ret = str.trim().replace(/\\s+/g, ' ');\n if (ret.length <= n) return ret;\n return ret.substr(0, n) + '..';\n }\n\n /**\n * @returns {Boolean}\n */\n\n }, {\n key: 'is_local_storage_available',\n value: function is_local_storage_available() {\n // Catch error when user has disabled third-party cookies/storage.\n try {\n return 'localStorage' in window;\n } catch (error) {\n return false;\n }\n }\n }]);\n\n return Playset;\n}();\n\n// on DOM ready, invoke constructor to setup\n\n\nPlayset.avplayer = '#jw6';\nPlayset.resizer_listening = false;\nPlayset.unplayable_timer = null;\nPlayset.mobile = navigator.userAgent.indexOf('iPhone') > 0 || navigator.userAgent.indexOf('iPad') > 0 || navigator.userAgent.indexOf('iPod') > 0 || navigator.userAgent.indexOf('Android') > 0;\n$(function () {\n return new Playset();\n});"},137:function(e,t,n){n(9)(n(136))},138:function(e,t,n){"use strict";n(137)},9:function(e,t){e.exports=function(e){function t(e){"undefined"!=typeof console&&(console.error||console.log)("[Script Loader]",e)}try{"undefined"!=typeof execScript&&"undefined"!=typeof attachEvent&&"undefined"==typeof addEventListener?execScript(e):"undefined"!=typeof eval?eval.call(null,e):t("EvalError: No eval function available")}catch(e){t(e)}}}});
//# sourceMappingURL=playset.min.js.map