(function($, Drupal, drupalSettings) { EdlpTheme = function(){ var _origin = window.location.origin; var _base_url = drupalSettings.path.baseUrl; var _ajax_settings = drupalSettings.edlp_ajax; var _$body = $('body'); // var _is_front = drupalSettings.path.isFront; var _corpus_ready = false; var _$corpus_canvas; var _$row = $('main[role="main"]>.layout-content>.row'); var _$ajaxLinks; var _audioPlayer; var _randomPlayer; var _compoPlayer; var _ajax_timing = { start:0, end:0 }; var _corpus_promise; var _is_mobile = edlp_mobile.device_is_mobile; var _is_loggedin = drupalSettings.user.uid === 0 ? false : true; var _$log_form; var _user_tokens; var _states_history = []; var _is_expo = $('body').hasClass('domain-expo-encyclopediedelaparole-org'); // ___ _ _ // |_ _|_ _ (_) |_ // | || ' \| | _| // |___|_||_|_|\__| function init(){ console.log("EdlpTheme init()"); if (!_is_loggedin) { initLogForm(); } if(_is_mobile){ initMobile(); }else if(drupalSettings.path.isFront){ initDesktopHome(); } initEvents(); _audioPlayer = new AudioPlayer(); _compoPlayer = new CompoPlayer(); initAjaxLinks(); initHistory(); if(!_is_mobile){ checkLayout(); initAudioLinksHover(); } if(_is_mobile){ if(drupalSettings.path.isFront){ initHomeMobile(); } _$body.attr('booted', 'booted'); } }; // _ ___ // | | ___ __ _ | __|__ _ _ _ __ // | |__/ _ \/ _` | | _/ _ \ '_| ' \ // |____\___/\__, | |_|\___/_| |_|_|_| // |___/ function initLogForm(){ console.log('initLogForm'); _$log_form = $('#user-login-form:not(ajax-enebled)') .on('submit', onSubmitLogForm) .addClass('ajax-enabled'); }; function onSubmitLogForm(e){ e.preventDefault(); // console.log('onSubmitLogForm', e); var args = { name : $('input#edit-name[type="text"]', this).val(), pass : $('input#edit-pass[type="password"]', this).val() }; // console.log(args); logIn(args).then(logedin); return false; }; function logIn(args){ console.log('logIn', args); _$log_form.addClass('ajax-loading'); _$body.addClass('ajax-loading'); return $.ajax({ type: 'POST', headers: {'Content-Type': 'application/json'}, xhrFields: { withCredentials: true }, // accessToken : 'tokenvaluehere', url: _origin+_base_url+"user/login?_format=json", data: JSON.stringify(args), // name: args.mail, // pass: args.pass, success: function(response){ // console.log('sucess', response); _user_tokens = response; }, error: function (xhr, ajaxOptions, thrownError){ console.log(xhr.status); console.log(thrownError); } }); }; function logedin(){ $('body').addClass('user-logged-in'); getStudioLinkBlock(); }; function getStudioLinkBlock(){ var path = _origin+_base_url+'edlp/ajax/blocks/json/'; $.getJSON(path+"studiolinkblock", {}) .done(onStudioLinkBlockLoaded) .fail(function(jqxhr, textStatus, error){ console.warn('Studio ink block load failed', jqxhr.responseText); }); }; function onStudioLinkBlockLoaded(data){ console.log('onStudioLinkBlockLoaded', data); $('#block-studiouserlogin').replaceWith(data.blocks.studiolinkblock.rendered); initAjaxLinks(); refreshFavoritesLinks(); _$log_form.removeClass('ajax-loading'); _$body.removeClass('ajax-loading'); } // __ __ _ _ _ // | \/ |___| |__(_) |___ // | |\/| / _ \ '_ \ | / -_) // |_| |_\___/_.__/_|_\___| function initMobile(){ console.log('initMobile'); // $('[data-drupal-link-system-path=""]','#block-mainnavigation') // .removeClass('is-active') // .attr('href', '#collection'); // edlp_mobile.mobile_home_path.replace(/^\//, '') // TODO: remove collection from mobile home // TODO: replace ajax link to only collection for mobile $('h2, a', '#block-mainnavigation') .add('h2, a', '#block-mainnavigation-2') .on('click', onclickHomeMobileMenu); } function onclickHomeMobileMenu(e){ // $('#block-mainnavigation').toggleClass('opened'); $('#block-mainnavigation-2').toggleClass('opened'); }; function initHomeMobile(){ // taxonomy-term.vocabulary-entrees.home_mobile // $('.field--name-field-notice, .index', '.entrees .taxonomy-term.vocabulary-entrees') // .addClass('closed'); // $('.field--name-field-notice>.field__label', '.entrees .taxonomy-term.vocabulary-entrees') // .on('click', onClickHomeMobileNotice); // $('.index>.field__label', '.entrees .taxonomy-term.vocabulary-entrees') // .on('click', onClickHomeMobileIndex); }; // function onClickHomeMobileNotice(e){ // // console.log('onClickHomeMobileNotice'); // // var $part = $(this).parent();//parents('.taxonomy-term'); // toggleEntreeOpening($(this).parent(), 'notice'); // }; // function onClickHomeMobileIndex(e){ // // console.log('onClickHomeMobileIndex'); // // var $part = $(this).parent();//parents('.taxonomy-term'); // toggleEntreeOpening($(this).parent(), 'index'); // }; // function toggleEntreeOpening($e, part){ // $e.toggleClass('closed') // .parents('.taxonomy-term.vocabulary-entrees.home_mobile').toggleClass(part+'-opened'); // } function initDesktopHome(){ console.log('initDesktopHome'); // allow multiple prods on home but display only one randomly var $prods = $('.grid .col .node--type-page'); $r = Math.floor(Math.random() * $prods.length) $prods.each(function(index) { if(index != $r){ $(this).parents('.col').remove(); } }); console.log('$prods', $prods); } // ___ _ // | __|_ _____ _ _| |_ ___ // | _|\ V / -_) ' \ _(_-< // |___|\_/\___|_||_\__/__/ function initEvents(){ // https://www.html5rocks.com/en/tutorials/async/deferred/ var $corpus_df = $.Deferred(); _corpus_promise = $corpus_df.promise(); _$body .on('corpus-map-ready', function(e){ onCorpusMapReady(e); $corpus_df.resolve(); }) .on('on-studio-chutier-updated', initAjaxLinks) .on('studio-initialized', function(e){ _compoPlayer.newCompo(); }) .on('studio-not-active', function(e){ _compoPlayer.deactivate(); }) .on('on-studio-compo-updated', function(e){ initAjaxLinks(); _compoPlayer.refresh(); }) .on('on-studio-compo-opened', function(e){ initAjaxLinks(); _compoPlayer.newCompo(); }) .on('search-results-loaded', function(e){ initAjaxLinks(); initAudioLinksHover(); checkVisibleCorpusMapSpace(); }) // do not close index or notice modale on entree click .on('open_entree', function(e){ console.log('on_open_entree : e', e); closeAllModals(); checkLayout(); // add body class for currently loaded content // var body_classes = [ // 'path-'+sys_path.replace(/\//g, '-'), // 'entity-type-'+data.entity_type, // 'bundle-'+data.bundle, // 'view-mode-'+data.view_mode // ]; _$body.removeClass();//.addClass(body_classes.join(' ')); // record new history state if(typeof e.url != 'undefined'){ var state = getSysPathState(e.sys_path); history.pushState(state, null, e.url); // piwik if(typeof _paq !== 'undefined'){ // page tracking // https://matomo.org/blog/2017/02/how-to-track-single-page-websites-using-piwik-analytics/ _paq.push(['setCustomUrl', e.url]); _paq.push(['setDocumentTitle', e.title]); _paq.push(['trackPageView']); } } }) .on('close_entree', function(e){ backToFrontPage(); checkLayout(); }); window.addEventListener('resize', checkLayout, false); } // __ ___ _ ___ _ // \ \ / (_)_ _ __| |_____ __ __ | _ \___ __(_)______ // \ \/\/ /| | ' \/ _` / _ \ V V / | / -_|_-< |_ / -_) // \_/\_/ |_|_||_\__,_\___/\_/\_/ |_|_\___/__/_/__\___| function checkLayout(){ var $audioplayer = $("#audio-player"); if($audioplayer.length){ var navpos = $('#block-mainnavigation').position(); // console.log('navpos', navpos); if(typeof navpos != 'undefined'){ $audioplayer.css({ 'width':navpos.left+'px' }); } } checkGridBlockHeight(); checkGridBlockVisible(); // entrees // TODO: center the entrees menu }; // ___ _ _ ___ // / __| __ _ _ ___| | | _ ) __ _ _ _ ___ // \__ \/ _| '_/ _ \ | | _ \/ _` | '_(_-< // |___/\__|_| \___/_|_|___/\__,_|_| /__/ function initScrollbars(){ // console.log("initScrollbars"); // TODO: find a better js scroll than overlayScrollbars which does not handle well max-height + overflow-y:auto; // $('.os-scroll').overlayScrollbars({ // overflowBehavior:{ // x:'h', // y:'scroll', // clipAlways:false // } // }); }; // _ _ // /_\ (_)__ ___ __ // / _ \ | / _` \ \ / // /_/ \_\/ \__,_/_\_\ // |__/ function getSysPathState(sys_path, view_mode){ // console.log('Theme : getSysPathState', sys_path); var state = { 'sys_path':sys_path, 'ajax_path': sys_path }; // convert node link to edlp_ajax_node module links var node_match = state.ajax_path.match(/^\/?(node\/(\d+))$/i); console.log('node_match', node_match); var term_match = state.ajax_path.match(/^\/?(taxonomy\/term\/(\d+))$/i); console.log('term_match', term_match); if(node_match){ // TODO: detect audio links which will open audioplayer and wont load any ajax content unless view_mode "article" or "transcript" state.ajax_path = _ajax_settings.entityjson_path+'/'+node_match[1]; state.node_nid = node_match[2]; // check for viewmode attribute if(view_mode){ state.ajax_path += '/'+view_mode; state.view_mode = view_mode; } }else if(term_match){ // terms are always entrees, there's no other vocabulary links in front state.ajax_path = _ajax_settings.entityjson_path+'/'+term_match[1]; state.ajax_path = state.ajax_path.replace(/taxonomy\/term/, 'taxonomy_term'); state.entree_tid = term_match[2]; // check for viewmode attribute if(view_mode){ state.ajax_path += '/'+view_mode; state.view_mode = view_mode; }else{ state.ajax_path = null; } }else{ // convert other link to ajax // TODO: we assume that other links (no node, no term) are all from own modules (e.g. productions) !! may not be true !! state.ajax_path += '/ajax' } return state; }; function ajaxLoadContent(state){ console.log('ajaxLoadContent : state', state); _$body.addClass('ajax-loading'); _ajax_timing.start = performance.now(); var path = _origin + Drupal.url(state.ajax_path); $.getJSON(path, {}) .done(function(data){ onAjaxLoaded(data, state); }) .fail(function(jqxhr, textStatus, error){ onAjaxLoadError(jqxhr, textStatus, error, state.sys_path); }); }; function onAjaxLoadError(jqxhr, textStatus, error, sys_path){ console.warn('ajaxlink load failed for '+sys_path+' : '+error, jqxhr.responseText); $('.ajax-loading').removeClass('ajax-loading'); _$body.removeClass('ajax-loading'); }; function onAjaxLoaded(data, state){ console.log('ajax loaded', state, data); var $rendered = $(data.rendered); $rendered.attr({ 'sys_path':state.sys_path, 'view_mode': state.view_mode }); // console.log(data); // reset all style may been added by other pages (like masonry for productions) // and replace all content with newly loaded // TODO: build a system to replace or append contents (like studio + search) if(data.entity_type == "node" && data.bundle == "evenement"){ if(_$row.find('.col.event').length){ _$row.find('.col.event').replaceWith($rendered); }else if(_$row.find('.col.aside').length){ _$row.find('.col.aside').replaceWith($rendered); }else{ _$row.append($rendered); } } else if( (state.context == 'document-transcript' || state.context == 'document-artcile') && state.caller == "search" ){ _$row.append($rendered); } else{ _$row.removeAttr('style').html($rendered); } // remove article is-active class is static content loaded if ((data.entity_type == "node" && data.bundle == "static") || state.sys_path == "docsindex") { $('.ajax-link.is-active.articles-link').removeClass('is-active'); } // add body class for currently loaded content var body_classes = [ 'path-'+state.sys_path.replace(/\//g, '-'), 'entity-type-'+data.entity_type, 'bundle-'+data.bundle, 'view-mode-'+data.view_mode ]; _$body.removeClass().addClass(body_classes.join(' ')); // id node add a generic path-node class to body // m = state.sys_path.match(/^\/?(node\/\d+)$/g); // if(m) if(state.node_nid) _$body.addClass('path-edlp-node'); // handle clicked link classes $('.ajax-loading').removeClass('ajax-loading'); $('.ajax-link.is-active:not(.articles-link)').removeClass('is-active'); $('.is-active-trail').removeClass('is-active-trail'); if(typeof state.selector != 'undefined'){ // in case of entree link (actualy, selector is used only for entries links) // TODO: unfortunatly on initFirstLoad there is no selector property console.log('selector', state.selector); $('a[selector="'+state.selector+'"]').addClass('is-active'); initAudioLinksHover(); }else{ if(typeof state.view_mode != 'undefined'){ $('a[viewmode="'+state.view_mode+'"][data-drupal-link-system-path="'+state.sys_path+'"]').addClass('is-active'); }else{ // wait for corpus map beeing ready (e.g. for articles link) _corpus_promise.done(function(){ $('a[data-drupal-link-system-path="'+state.sys_path+'"]').addClass('is-active'); }); } // as new content is not related to entree, we trigger close entree _$body.trigger({'type':'new-content-not-entree-ajax-loaded'}); } // if bundle page (productions) activate production links if (typeof data.bundle != 'undefined' && data.bundle == "page") { $('a[data-drupal-link-system-path="productions"]').addClass('is-active-trail'); } // if node is in production menu tree, set first level of tree active, e.g. pieces sonores if (typeof data.menu_parents != 'undefined') { for (var i = 0; i < data.menu_parents.length; i++) { var menu_sys_path = data.menu_parents[i]; $('a[data-drupal-link-system-path="'+menu_sys_path+'"]').addClass('is-active-trail'); } } // if entity has corpus-map's linked document call a filter to corpus map if(typeof data.documents_lies != 'undefined'){ if(_corpus_ready){ _$body.trigger({ type:'ajax-node-loaded-linked-documents', nids:data.documents_lies }); }else{ _corpus_promise.done(function(){ _$body.trigger({ type:'ajax-node-loaded-linked-documents', nids:data.documents_lies }); }); } } // if block attached (eg : from edlp_productions module) // not used anymore as production block is always present (but not visible) if(typeof data.block != 'undefined'){ // if block not already added if(!$('#'+data.block.id, '.region-'+data.block.region).length){ $('.region-'+data.block.region).append(data.block.rendered); } } // initScrollbars(); if(state.sys_path == "productions"){ // initProductions(); initGrid(); }else{ addCloseModalBtnToCols(); } if(state.sys_path == "collection"){ // only for mobile version of collection initCollectionNav(); } // enregistrement transcription if(data.entity_type == "node" && data.bundle == "enregistrement" && data.view_mode == "transcript"){ // window.requestAnimationFrame(initEnregistrementTranscript); initEnregistrementTranscript(); } if(state.sys_path == "search"){ initSearch(); } // update the language switcher block if it comes in the response if(typeof data.translations_links != 'undefined'){ console.log('state',state); var lang_code = drupalSettings.path.currentLanguage; var $links = $(data.translations_links); // set active link $links.find('li[hreflang="'+lang_code+'"]').addClass('is-active').find('a').addClass('is-active'); if(state.view_mode){ $links.find('a').each(function(i,e){ var $a = $(this); $a.attr('href', $a.attr('href')+'#'+state.view_mode); }); } // if(state.selector){ // $links.find('a').attr('selector', state.selector); // } $('ul','.block.language-switcher-language-url').replaceWith($links); } initAjaxLinks(); initAudioLinksHover(); checkVisibleCorpusMapSpace(); // trigger other modules behaviours _$body.trigger({'type':'new-content-ajax-loaded'}); // and call drupal behaviours Drupal.attachBehaviors(_$row[0]); _$body.attr('booted', 'booted'); _$body.removeClass('ajax-loading'); // record the states history as we can't get them from history api _states_history.unshift(state); // url is null means that we are loading content on popState event // so we don't record the state again if(state.url){ // /!\ we can not pushestate with absolute url /!\ history.pushState(state, null, state.url); // piwik if(typeof _paq !== 'undefined'){ // page tracking // https://matomo.org/blog/2017/02/how-to-track-single-page-websites-using-piwik-analytics/ _paq.push(['setCustomUrl', state.url]); _paq.push(['setDocumentTitle', data.title]); // TODO: piwik track load time _ajax_timing.end = performance.now(); _paq.push(['setGenerationTimeMs', _ajax_timing.end-_ajax_timing.start]); _paq.push(['trackPageView']); // js event // trackEvent(category, action, [name], [value]) // _paq.push(['trackEvent', 'AjaxNav', 'loaded', state.url]); } } }; function initAudioLinksHover(){ console.log("initAudioLinksHover()"); _$row.find('a.audio-link') .not('article.node--view-mode-docsindex a.audio-link') .on('mouseover', function(event) { event.preventDefault(); if(_corpus_ready){ _$corpus_canvas.trigger({ type:'mouseover-audio-link', nid:$(this).attr('nid') }); } }) .on('mouseout', function(event) { event.preventDefault(); if(_corpus_ready){ _$corpus_canvas.trigger({ type:'mouseout-audio-link', nid:$(this).attr('nid') }); } }); }; function addCloseModalBtnToCols(){ if(_is_mobile) return; $('.col', _$row).each(function(index, el) { if($('span.close-col-btn', this).length) return true; $(this).children('.wrapper').prepend($('') .addClass('close-col-btn') .on('click', onCloseModal) ); }); }; function onCloseModal(e){ console.log("onCloseModal"); // check from production to audio text back to production console.log("onCloseModal _states_history",_states_history); if(['document-transcript', 'document-article'].indexOf(_states_history[0].context) != -1) { if (_states_history[0].caller == "production") { for (var i = 0; i < _states_history.length; i++) { if (_states_history[i].context == "production") { // history.go(i*-1-1); console.log("onCloseModal return to production", _states_history[i]); ajaxLoadContent(_states_history[i]); return; } } } if (_states_history[0].caller == "entree-index") { for (var i = 0; i < _states_history.length; i++) { if (_states_history[i].context == "entree-index") { console.log("onCloseModal return to entree-index", _states_history[i]); ajaxLoadContent(_states_history[i]); return; } } } if (_states_history[0].caller == "entree-notice") { for (var i = 0; i < _states_history.length; i++) { if (_states_history[i].context == "entree-notice") { console.log("onCloseModal return to entree-notice", _states_history[i]); ajaxLoadContent(_states_history[i]); return; } } } } // return to productions home when closing a prod // if(['production'].indexOf(_states_history[0].context) != -1) // { // var i = 0; // while (_states_history[i].caller == "production-home") { // if (_states_history[i].context == "production-home") { // // history.go(i*-1-1); // console.log("onCloseModal return to productions home", _states_history[i]); // ajaxLoadContent(_states_history[i]); // return; // } // i++; // } // } // check for theme attribute and emmit event var $col = $(this).parents('.col'); var theme = $col.attr('theme'); if(theme != ''){ _$body.trigger({'type':theme+'-col-closed'}); } if(_$body.is('.entity-type-node.bundle-page') && $(this).next().is('.node--type-page')){ // remove all the col (prod page and agenda in case) only if closing the main page col // if closing the aside col (agenda) leave the main col in place $col.add($col.siblings('.col')).remove(); }else{ // remove the col $col.remove(); } checkRowEmpty(); checkVisibleCorpusMapSpace(); // set links to this modal to not active (tested on articles from audio cartel) if( $col.attr('view_mode') && $col.attr('sys_path')){ $('a[data-drupal-link-system-path="'+$col.attr('sys_path')+'"][viewmode="'+$col.attr('view_mode')+'"]').removeClass('is-active'); } }; // _ _ ___ _ _ // /_\ (_)__ ___ __ | _ ) |___ __| |__ ___ // / _ \ | / _` \ \ / | _ \ / _ \/ _| / /(_-< // /_/ \_\/ \__,_/_\_\ |___/_\___/\__|_\_\/__/ // |__/ // NOT USED (YET) // function refreshAllBlocks(){ // var path = _origin + Drupal.url(_ajax_settings.blocksjson_path); // $.getJSON(path, {}) // .done(function(data){ // onAjaxBlockLoaded(data); // }) // .fail(function(jqxhr, textStatus, error){ // onAjaxBlockLoadError(jqxhr, textStatus, error); // }); // }; // function onAjaxBlockLoadError(jqxhr, textStatus, error){ // console.warn('ajax block load failed: '+error, jqxhr.responseText); // }; // function onAjaxBlockLoaded(data){ // console.log('onAjaxBlockLoaded', data); // // TODO: update each blocks (exepted language switcher) // for (var blockname in data.blocks) { // var block = data.blocks[blockname]; // console.log(blockname, block); // $(block.id).replaceWith(block.rendered); // } // }; // _ _ _ _ // | || (_)__| |_ ___ _ _ _ _ // | __ | (_-< _/ _ \ '_| || | // |_||_|_/__/\__\___/_| \_, | // |__/ function initHistory(){ initFirstLoad(); window.addEventListener('popstate', onHistoryPopState); }; function initFirstLoad(){ console.log('theme : initFirstLoad()'); console.log('window.location', window.location); // var origin_sys_path = window.localStorage.getItem('edlp_origin_path'); var edlp_origin = JSON.parse(window.localStorage.getItem('edlp_origin')); console.log('edlp_origin', edlp_origin); if(edlp_origin != null && edlp_origin.sys_path){ // hash is used as viewmode for taxonomy term entrees load (index or notice) // and for audio contents (article|transcript) var hash = edlp_origin.hash.replace('#', ''); // create history state var state = getSysPathState(edlp_origin.sys_path, hash); // add historic_index 0 to state state.historic_index = 0; // open entree tray in case of entree index|notice // (index or notice will be opened with ajaxLoadContent) // refactorized with new infos from edlp_origin // if(hash){ if(edlp_origin.entity_type == "taxonomy_term" && edlp_origin.entity_bundle == "entrees" && hash){ // var $link = $('[href="'+edlp_origin.url+'"][viewmode="'+hash+'"]'); // var selector = $link.attr('selector') || null; // record the selector in the state for actions after ajaxContentLoaded state.selector = 'entree-'+hash+'-link-'+edlp_origin.entity_id; // entree-index-link-125 // if(selector){ // in case of entree link (actualy, selector is used only for entries links) // TODO: use a promise // TODO: but what if corpus ready before onAjaxLoaded >> use a promise !! if(_corpus_ready){ _$corpus_canvas.trigger({ type:'open-entree', // tid:$link.attr('tid') tid:edlp_origin.entity_id }); }else{ // else : EdlpCorpus will check when ready if entry item (notice or index) is already .is-active // .is-active class is added by onAjaxLoaded() (when content is loaded) // $('li.entree[tid="'+$link.attr('tid')+'"] a.term-link').addClass('is-active'); $('li.entree[tid="'+edlp_origin.entity_id+'"] a.term-link').addClass('is-active'); } // } } // check if audio link // only if not random link if(edlp_origin.audio_url){ var node = { nid:edlp_origin.entity_id, audio_url:edlp_origin.audio_url }; _audioPlayer.openDocument(node, 'history_first_load'); // close home closeAllModals(); if(hash == "" || hash == 'random'){ console.log('first load hash', hash); // if hash is random, RandomPlayer will be started when playlist sent by corpus.js // if audio only record in state state.audio = true; state.node = node; if(!_is_mobile){ // if not mobile we don't laod ajax content so we boot the home _$body.attr('booted', 'booted'); }else{ ajaxLoadContent(state); } }else{ console.log('first load load content'); // ajax load content for audio only if article or transcript ajaxLoadContent(state); } } // only if not entree path // only if not audio (without article or transcript) path else if(state.ajax_path){ // load content through ajax // ajaxLoadContent(null, state.sys_path, state.ajax_path, selector); ajaxLoadContent(state); } if(state.entree_tid){ openEntree(state.entree_tid); } // record history state history.replaceState(state, null, edlp_origin.url+edlp_origin.hash); // reset the storage window.localStorage.removeItem("edlp_origin"); // window.localStorage.removeItem("edlp_origin_url"); }else{ // if(window.location.hash == "#random"){ // // } history.replaceState({home:true}, null, window.location.pathname+window.location.hash); // initHome(); initGrid(); _$body.attr('booted', 'booted'); } }; function onHistoryPopState(e){ console.log('onHistoryPopState',e.state); if(e.state.home){ backToFrontPage(true); } else if (e.state.audio) { console.log('popstate audio : e.state', e.state); _audioPlayer.openDocument(e.state.node, 'popstate', e.state.historic_index); if(_is_mobile){ ajaxLoadContent(e.state) } } else{ if(e.state.entree_tid){ openEntree(e.state.entree_tid); } if(e.state.ajax_path){ e.state.url = null; // ajaxLoadContent(null, e.state.sys_path, e.state.ajax_path) ajaxLoadContent(e.state); } } }; // _ _ _ _ _ // /_\ (_)__ ___ _| | (_)_ _ | |__ ___ // / _ \ | / _` \ \ / |__| | ' \| / /(_-< // /_/ \_\/ \__,_/_\_\____|_|_||_|_\_\/__/ // |__/ function initAjaxLinks(){ // console.log('initAjaxLinks'); $('a', '#block-edlptheme-mainnavigation') .add('a', '#block-mainnavigation-2') // .add('a', '.block.language-switcher-language-url') .add('a', '#block-footer.menu--footer') .add('a', '#block-productions') .add('a', 'article.node:not(.node--type-enregistrement) h2.node-title') // .add('a', 'article.node--type-evenement.node--view-mode-teaser .field--name-field-page-liee') .add('a', '.productions-subtree') .add('a', '.productions-parent') // .add('a.index-link, a.notice-link', '#block-edlpentreesblock') .add('a', '.field--name-field-son') .addClass('ajax-link'); if(!_is_mobile){ $('a.site-name', '#block-edlptheme-branding').addClass('ajax-link'); } _$ajaxLinks = $('.ajax-link'); activateAjaxLinks(); }; function activateAjaxLinks(){ // $('.ajax-link:not(.ajax-enabled)') _$ajaxLinks.each(function(i,e){ var $this = $(this); // avoid already ajaxified links if($this.is('.ajax-enable')) return; if($this.attr('data-drupal-link-system-path') || $this.is('[type^="audio"]')){ $this.on('click', onClickAjaxLink).addClass('ajax-enable'); } }); }; function onClickAjaxLink(e){ e.preventDefault(); var $link = $(this); // let the site-name link going through as it will shuffle the map if already active if($link.is('.is-active') && !$link.is('.site-name')) return false; // Audio links // launch audio player and stop here if($link.is('.audio-link')){ // check if caller is lastdocs block caller = $link.parents('.lastdocs, .lastdocs-home').length ? 'lastdocs' : null; // check if caller is studio composition if(!caller){ caller = $link.parents('.composition_ui').length ? 'studio-compo' : null; } // open audio player if(caller == 'studio-compo'){ var index = $link.parents('.field__item').index(); console.log('audio link caller', caller, index); // _compoPlayer.setIndex(index); _compoPlayer.start(index); }else{ _audioPlayer .emmit('stop-shuffle') .openDocument({ nid:$link.attr('nid'), audio_url:$link.attr('audio_url'), title:$link.find('.field--name-title').html() }, caller); } return false; } // other sounds playing if($link.is('[type^="audio"]')){ _audioPlayer .emmit('stop-shuffle') .openSound($link.attr('href'), $link.html()); return false; } // NOT USED ( YET ? ) // if($link.is('.language-link')){ // TODO: change global site current language // load all blocks translated (exepted language switcher) ... :/ // refreshAllBlocks(); // TODO: use a promise to initAjaxLinks again after blocks updated // then let load the content // } // other links var sys_path = $(this).attr('data-drupal-link-system-path'); // front page // just remove contents and stop here if(sys_path == ''){ if(!_is_mobile){ if($link.is('.is-active') && _corpus_ready){ _$corpus_canvas.trigger({'type':'shuffle-collection'}); }else{ backToFrontPage(); } return false; } // else{ // sys_path = edlp_mobile.mobile_home_path.replace(/^\//, ''); // } } var view_mode = $link.attr('viewmode'); var state = getSysPathState(sys_path, view_mode); state.url = $(this).attr('href'); if(view_mode){ state.url += "#"+view_mode; } // get context for navigation purpose // var contexts = state.url.match(/^.*\/(productions)\/.*/g); var contexts = /^.*\/(productions|documents|entrees|search)(\/.*)?/g.exec(state.url); console.log("onClickAjaxLink contexts", contexts); if(contexts){ switch (contexts[1]) { case 'productions': // console.log("onClickAjaxLink is production"); // if (typeof contexts[2] !== 'undefined') { state.context = "production" // }else{ // state.context = "production-home" // } break; case 'entrees': switch(view_mode) { case 'index': state.context = "entree-index"; break; case 'notice': state.context = "entree-notice"; break; } break; case 'search': state.context = "search"; break; case 'documents': // console.log("onClickAjaxLink is production"); switch (view_mode) { case 'transcript': state.context = "document-transcript"; break; case 'article': state.context = "document-article"; break; default: state.context = "document"; } // get the caller from pecedent context if(typeof _states_history[0] != "undefined"){ if(_states_history[0].caller){ state.caller = _states_history[0].caller }else{ state.caller = _states_history[0].context } }else{ state.caller = null; } break; } }else{ state.context = null; // state.context = caller; } if($link.is('[selector]')){ state.selector = $link.attr('selector'); } $link.addClass('ajax-loading'); // ajaxLoadContent(url, sys_path, state.ajax_path, selector); ajaxLoadContent(state); return false; }; function refreshFavoritesLinks(){ console.log("refreshFavoritesLinks", _states_history); // reload the active audioPlayer cartel _audioPlayer.reloadNode(); // current content (index) if(_states_history[0].view_mode == 'index' || _states_history[0].sys_path == "docsindex"){ ajaxLoadContent(_states_history[0]); } } // ___ // / __|___ _ _ _ __ _ _ ___ // | (__/ _ \ '_| '_ \ || (_-< // \___\___/_| | .__/\_,_/__/ // |_| function onCorpusMapReady(e){ //console.log('theme : onCorpusReady', e); _corpus_ready = true; _$corpus_canvas = $('canvas#corpus-map'); _$corpus_canvas .on('corpus-cliked-on-map', function(e) { //console.log('theme : corpus-cliked-on-map'); backToFrontPage(); }) .on('corpus-cliked-on-node', function(e) { //console.log('theme : corpus-cliked-on-node', e); _audioPlayer .emmit('stop-shuffle') // .setAutoOpenArticle(e.article) .openDocument(e.target_node); }); _randomPlayer = new RandomPlayer(e.playlist); if (_is_expo) { initExpo(); } // mainly for articles link initAjaxLinks(); _$body.attr('corpus-map', 'ready'); } function openEntree(tid){ if(tid){ closeAllModals(); _$body.removeClass();//.addClass(body_classes.join(' ')); // open entree if(_corpus_ready){ _$corpus_canvas.trigger({ type:'open-entree', tid:tid }); }else{ // else : EdlpCorpus will check when ready if entry item (notice or index) is already .is-active $('li.entree[tid="'+tid+'"] a.term-link').addClass('is-active'); } } }; function checkVisibleCorpusMapSpace(){ var left_limit = 0, right_limit = 0; _$row.find('.col').each(function(i,e){ var $col = $(this); var offset = $col.offset(); console.log('$col', $col); switch(true){ case $col.is('.float-right'): right_limit = Math.max(right_limit, Math.abs(offset.left-15-window.innerWidth)); break; default: left_limit = Math.max(left_limit, offset.left+$col.width()+15); break; } }); console.log('checkVisibleCorpusMapSpace left_limit:'+left_limit+" right_limit:"+right_limit); if(_corpus_ready){ _$body.trigger({ type:'visible-space-changed', left_limit:left_limit, right_limit:right_limit }); }else{ _corpus_promise.done(function(){ _$body.trigger({ type:'visible-space-changed', left_limit:left_limit, right_limit:right_limit }); }); } }; // _ _ _ // /_\ _ _ __| (_)___ // / _ \ || / _` | / _ \ // /_/ \_\_,_\__,_|_\___/ // // https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement // https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/samples/gg589528%28v%3dvs.85%29 // https://www.binarytides.com/using-html5-audio-element-javascript/ function AudioPlayer(){ var that = this; this.fid; this.audio = new Audio(); // audio events this.audio_events = ["loadedmetadata","playing","pause","timeupdate","ended","error"]; // ,"canplay" // UI dom objects this.$container = $('
'); // btns this.$btns = $('
').addClass('btns').appendTo(this.$container); this.$previous = $('
').addClass('previous').appendTo(this.$btns); this.$playpause = $('
').addClass('play-pause').appendTo(this.$btns); this.$next = $('
').addClass('next').appendTo(this.$btns); // timeline this.$timelinecont= $('
').addClass('time-line-container').appendTo(this.$container); this.$timeline = $('
').addClass('time-line').appendTo(this.$timelinecont); this.$loader = $('
').addClass('loader').appendTo(this.$timeline); this.$cursor = $('
').addClass('cursor').appendTo(this.$timeline); // time this.$time = $('
').addClass('time').appendTo(this.$container); this.$currentTime = $('
').addClass('current-time').html('00:00').appendTo(this.$time); this.$duration = $('
').addClass('duration').html('00:00').appendTo(this.$time); // favoris this.$fav = $('
').addClass('favoris').appendTo(this.$container); // cartel this.$cartel = $('
').addClass('cartel').appendTo(this.$container); this.scndCartel_visible = 0; this.cartelSwitchIntervalMS = 7000; this.cartelSwitchInterval = false; // hiding this.visible = false; this.hideTimer = false; this.hideTimeMS = 15000; // history this.currentHistoricIndex = null; this.historic = []; this.shuffle_is_active = false; // artciles this.auto_open_article = false; // object events this.event_handlers = { 'audio-open-document':[], 'audio-play':[], 'audio-pause':[], 'audio-play-next':[], 'audio-ended':[], 'stop-shuffle':[] }; this.init(); }; AudioPlayer.prototype = { init(){ if(!_is_expo){ this.$container_parent = $('header[role="banner"] .region-header'); }else{ this.$container_parent = $('main[role="main"]'); } // append ui to document this.$container.appendTo(this.$container_parent); // record timeline width this.timeline_w = parseInt(this.$timeline.width()); // init seeking this.$loader.on('click', this.seek.bind(this)); // init audio events var fn = ''; for (var i = 0; i < this.audio_events.length; i++) { fn = this.audio_events[i]; // capitalize first letter of event (only cosmetic :p ) fn = 'on'+fn.charAt(0).toUpperCase()+fn.slice(1); this.audio.addEventListener( this.audio_events[i], this[fn].bind(this), true); } // init btns events this.$previous.on('click', this.playPrevious.bind(this)); this.$playpause.on('click', this.togglePlayPause.bind(this)); this.$next.on('click', this.playNext.bind(this)); }, openDocument(node, caller, historic_index){ console.log('AudioPlayer openDocument', node, caller, historic_index); if(typeof node == 'undefined' || typeof node.nid == 'undefined' || typeof node.audio_url == 'undefined'){ console.warn('AudioPlayer openDocument() node is malformed', node); return false; } // if we don't come from history popstate if(typeof caller == 'undefined' || caller != 'popstate'){ console.log(''); this.historic.push(node); this.currentHistoricIndex = this.historic.length-1; // this.shuffle_mode = shuffle_mode || false; // add the document opening to history to be able to share and play audio from any where if(caller != "history_first_load"){ if(typeof node.document_url == 'undefined'){ console.warn("AudioPlayer openDocument missing document_url, can't push state to history", caller, node); }else{ var state = { audio:true, node:{ nid:node.nid, audio_url:node.audio_url, document_url:node.document_url, title:node.title || null, }, historic_index : this.currentHistoricIndex, }; // console.log('AudioPlayer pushstate', state); var url = node.document_url + (caller == 'random' ? '#random' : ''); history.pushState(state, null, url); } } }else{ // if the call commes from popstate, we update the current position of index this.currentHistoricIndex = historic_index; } if(_$body.is('.path-frontpage') && caller !== 'lastdocs' && !_is_mobile){ closeAllModals(); } // TODO: update language switcher for document url // TODO: stop random player if playing from studio this.emmit('audio-open-document', {caller:caller}); // piwik // debugger; if(typeof _paq !== 'undefined'){ // page tracking // https://matomo.org/blog/2017/02/how-to-track-single-page-websites-using-piwik-analytics/ // _paq.push(['setCustomUrl', state.url]); // _paq.push(['setDocumentTitle', data.title]); // _paq.push(['trackPageView']); // js event // trackEvent(category, action, [name], [value]) if(typeof node.title != 'undefined'){ _paq.push(['trackEvent', 'Audio', 'play', node.title]); } } this.launch(); }, launch(){ this.clearTimeOutToHide(); this.clearIntervalAutoCartelSwitch(); console.log('this.historic', this.historic); console.log('this.currentHistoricIndex', this.currentHistoricIndex); this.setSRC(this.historic[this.currentHistoricIndex].audio_url); if(!_is_mobile){ this.loadNode(this.historic[this.currentHistoricIndex].nid); } // emmit new playing doc (e.g.: corpus map nowing that audio played from RandomPlayer) try { _$corpus_canvas.trigger({ 'type':'audio-node-opened', 'nid':this.historic[this.currentHistoricIndex].nid }); } catch (e) { console.info('AudioPlayer : _$corpus_canvas does not exists, testing promise'); var that = this; _corpus_promise.done(function(){ _$corpus_canvas.trigger({ 'type':'audio-node-opened', 'nid':that.historic[that.currentHistoricIndex].nid }); }); } this.showHidePreviousBtn(); this.showHideNextBtn(); this.show(); }, openSound(url, title){ this.hide(); this.clearTimeOutToHide(); this.$cartel.html(""); this.setSRC(url); this.show(); if(typeof _paq !== 'undefined'){ _paq.push(['trackEvent', 'Audio', 'play', url]); } }, // audio functions setSRC(url){ console.log('AudioPlayer setSRC : url', url); this.audio.src = url; // need to trigger play right now to prevent safari blocking auto-play this.play(); }, // audio is ready to play onLoadedmetadata(){ var rem = parseInt(this.audio.duration, 10), mins = Math.floor(rem/60,10), secs = rem - mins*60; this.$duration.html(''+(mins<10 ? '0':'')+mins+':'+(secs<10 ? '0':'')+secs+''); this.updateLoadingBar(); }, updateLoadingBar(){ console.log("updateLoadingBar"); // var that = this; // if (this.audio.readyState === 4){ if(this.audio.buffered.length>0){ // debugger; this.$loader.css({ 'width':parseInt((100 * this.audio.buffered.end(0) / this.audio.duration), 10)+'%' }); if( this.audio.buffered.end(0) < this.audio.duration ){ // loop through this function until file is fully loaded window.requestAnimationFrame(this.updateLoadingBar.bind(this)); }else{ console.log('Audio fully loaded'); } }else{ // as audio buffer is not ready, recall updateLoadingBar in next frame window.requestAnimationFrame(this.updateLoadingBar.bind(this)); } }, // onCanplay(){ // // this.play(); // }, onError(){ console.warn("Audio Error " + this.audio.error.code + "; details: " + this.audio.error.message); }, play(){ this.clearTimeOutToHide(); // this.audio.play(); // making sound shorter for debuging purpose // if(_is_expo){ // setTimeout(this.seekToEnd.bind(this), 20000); // } // Not really needed has we trigger play right after setting the source https://stackoverflow.com/questions/47431439/mp4-video-safari-showing-unhandled-promise-rejection-object-domerror-in-c var promise = this.audio.play(); // console.log('promise', promise); if (promise !== undefined) { promise.catch(function(error){ // Auto-play was prevented // Show a UI element to let the user manually start playback console.warn('autoplay failed, ask for playing', error); }).then(function(){ // Auto-play started console.log('autoplay succeed'); }); } }, playPrevious(){ if(this.currentHistoricIndex > 0){ this.currentHistoricIndex -= 1; this.launch(); // TODO: update history state } }, playNext(){ if(this.currentHistoricIndex < this.historic.length-1){ this.currentHistoricIndex += 1; this.launch(); // TODO: update history state }else{ this.emmit('audio-play-next'); } }, togglePlayPause(e){ if(this.audio.paused){ // this.audio.play(); this.play(); }else{ // this.audio.pause(); this.stop(); } }, stop(){ // console.log('AudioPlayer stop()'); // debugger; this.audio.pause(); // don't close player if article or transcript is open if(!(_$body.is('.path-node-'+this.historic[this.currentHistoricIndex].nid) && (_$body.is('.view-mode-article') || _$body.is('.view-mode-transcript')))){ this.timeOutToHide(); } }, seek(e){ var seek = e.originalEvent.layerX / this.timeline_w * this.audio.duration console.log("Audio seeking : seek", seek); this.audio.currentTime = seek; }, seekToEnd(){ if (this.audio.duration > 40) { console.log("seekToEnd", this.audio.duration); this.audio.currentTime = this.audio.duration - 20; } }, // audio events onPlaying(){ this.$btns.addClass('is-playing'); this.emmit('audio-play'); }, onPause(){ this.$btns.removeClass('is-playing'); this.emmit('audio-pause'); }, onTimeupdate(){ // move cursor this.$cursor.css({ 'left':(this.audio.currentTime/this.audio.duration * this.timeline_w)+"px" }); // update time text display var rem = parseInt(this.audio.currentTime, 10), mins = Math.floor(rem/60,10), secs = rem - mins*60; this.$currentTime.html(''+(mins<10 ? '0':'')+mins+':'+(secs<10 ? '0':'')+secs+''); }, onEnded(){ console.log('AudioPlayer onEnded()'); this.stop(); this.emmit('audio-ended'); }, // cartel functions reloadNode(){ if(this.visible){ if(!_is_mobile){ console.log('reloadNode (cartel)'); this.loadNode(this.historic[this.currentHistoricIndex].nid); } } }, loadNode(nid){ this.$cartel.addClass('loading'); var vm = 'player_cartel'; var ajax_path = _ajax_settings.entityjson_path+'/node/'+nid+'/'+vm; var path = _origin + Drupal.url(ajax_path); $.getJSON(path, {}) .done(this.onNodeLoaded.bind(this)) .fail(this.onNodeLoadFail.bind(this)); }, onNodeLoaded(data){ console.log('AudioPlayer node loaded');//, data); this.$cartel.html(data.rendered).removeClass('loading'); _$body.trigger({'type':'new-audio-cartel-loaded'}); initAjaxLinks(); // cartel autoswitch this.scndCartel_visible = 0; this.$cartel.removeClass('second-visible'); if(!_is_expo){ // if second cartel has special info ? if (this.$cartel.find('.second-cartel .col-left').children().length > 1 || this.$cartel.find('.second-cartel').children('.col-right').length){ // init cartel auto switch this.cartelSwitchInterval = setInterval(this.switchCartel.bind(this), this.cartelSwitchIntervalMS); } // call drupal behaviours (for addtoany) console.log('AudioPlayer onNodeLoaded', this.$cartel); Drupal.attachBehaviors(this.$cartel.get(0)); } // open automaticly tha article if needed this.setAutoOpenArticle(); if(this.auto_open_article){ this.$cartel.find('a.link-article').trigger('click'); this.auto_open_article = false; } }, onNodeLoadFail(jqxhr, textStatus, error){ console.warn('AudioPlayer node load failed', jqxhr.responseText); this.$cartel.removeClass('loading').html(''); }, setAutoOpenArticle(art){ this.auto_open_article = $('a.articles-link').is('.is-active'); return this; }, // global show(){ this.visible = true; this.$container_parent.addClass('audio-player-visible'); this.$container.addClass('visible'); }, showHidePreviousBtn(){ if(this.historic.length > 1 && this.currentHistoricIndex > 0){ this.$previous.addClass('is-active'); }else{ this.$previous.removeClass('is-active'); } }, showHideNextBtn(){ if(this.currentHistoricIndex < this.historic.length-1 || this.shuffle_is_active){ this.$next.addClass('is-active'); }else{ this.$next.removeClass('is-active'); } }, timeOutToHide(){ // console.log('AudioPlayer timeOutToHide()'); this.clearTimeOutToHide(); this.hideTimer = setTimeout(this.hide.bind(this), this.hideTimeMS); }, clearTimeOutToHide(){ // console.log('AudioPlayer clearTimeOutToHide()',this.hideTimer); if(this.hideTimer){ clearTimeout(this.hideTimer); this.hideTimer = false; } }, // cartel switchCartel(){ // console.log("switchCartel", this.scndCartel_visible); if (this.scndCartel_visible) { // return to first cartel this.$cartel.removeClass('second-visible'); this.scndCartel_visible = 0; // kill the auto switch after one rotation this.clearIntervalAutoCartelSwitch(); }else{ // switch to 2nd cartel this.$cartel.addClass('second-visible'); this.scndCartel_visible = 1; } }, clearIntervalAutoCartelSwitch(){ if(this.cartelSwitchInterval){ clearInterval(this.cartelSwitchInterval); this.cartelSwitchInterval = false; } }, hide(){ // console.log('AudioPlayer hide()'); this.visible = false; this.$container_parent.removeClass('audio-player-visible'); this.$container.removeClass('visible'); // trigger highlighted node remove on corpus map try { _$corpus_canvas.trigger('audio-node-closed'); } catch (e) { console.info('AudioPlayer hide() : _$corpus_canvas does not exists'); } }, deActivateRandom(){ this.shuffle_is_active = false; this.showHideNextBtn(); }, // object events on(event_name, handler){ if(typeof this.event_handlers[event_name] == 'undefined'){ console.warn('AudioPlayer : event '+event_name+' does not exists'); } this.event_handlers[event_name].push(handler); return this; }, emmit(event_name, args){ console.log('AudioPlayer emmit()', event_name, args, this.event_handlers[event_name]); // console.log('AudioPlayer emmit() handlers', this.event_handlers[event_name]); var handler; var args = args || {}; for (var i = this.event_handlers[event_name].length-1; i >= 0 ; i--) { handler = this.event_handlers[event_name][i]; // console.log('AudioPlayer emmit() loop handler', handler); (function(handler, args){ setTimeout(function(){ // console.log('AudioPlayer emmit() timeout handler', handler); handler(args); }, 0); }(handler, args)); } return this; }, } // ___ _ ___ _ // | _ \__ _ _ _ __| |___ _ __ | _ \ |__ _ _ _ ___ _ _ // | / _` | ' \/ _` / _ \ ' \| _/ / _` | || / -_) '_| // |_|_\__,_|_||_\__,_\___/_|_|_|_| |_\__,_|\_, \___|_| // |__/ function RandomPlayer(playlist){ this.active = false; this.playlist = playlist; this.path = _base_url+drupalSettings.path.pathPrefix+'#random' this.$btn = $('') .html('Shuffle') .attr('href',this.path) .attr('alt', drupalSettings.edlp_corpus.random_link_title) .addClass('random-player-btn'); this.init(); }; RandomPlayer.prototype = { init(){ // this.shuffle(); $('
') .addClass('block random-player') .append(this.$btn) // .insertAfter('#block-userlogin, #block-studiolinkblock'); .prependTo('.region-footer-right'); // events this.$btn.on('click', this.toggleActive.bind(this)); // attach an event on AudioPlayer _audioPlayer .on('audio-play-next', this.onAudioPlayNext.bind(this)) .on('audio-ended', this.onAudioPlayerEnded.bind(this)) .on('stop-shuffle', this.stop.bind(this)); _$corpus_canvas .on('update-random-playlist', this.updatePlaylist.bind(this)); // provide a link to auto start random player if(window.location.hash == '#random'){ this.start(); } }, updatePlaylist(e){ if (!_is_expo) { this.playlist = e.playlist; this.shuffle(); } }, shuffle(){ var tempPLaylist = []; for (var i = this.playlist.length-1; i >= 0 ; i--) { tempPLaylist.push(this.playlist[i]); } this.shuffledPlaylist = []; while(tempPLaylist.length > 0){ var r = Math.floor(Math.random() * tempPLaylist.length); this.shuffledPlaylist.push(tempPLaylist.splice(r,1)[0]); } //console.log('RandomPlayer, this.shuffledPlaylist', this.shuffledPlaylist); }, toggleActive(e){ e.preventDefault(); if (this.active) { this.stop(); }else{ this.start(); } return false; }, start(){ this.active = _audioPlayer.shuffle_is_active = true; this.$btn.addClass('is-active'); this.shuffle(); this.next(); // piwik if(typeof _paq !== 'undefined'){ // trackEvent(category, action, [name], [value]) _paq.push(['trackEvent', 'RandomPlayer', 'start']); } }, stop(){ this.active = false; this.$btn.removeClass('is-active'); // stop audio player // _audioPlayer.stop(); // remove hash history.replaceState(history.state, null, window.location.pathname); // tell to AudioPlayer to deactivate netx btn _audioPlayer.deActivateRandom(); if(typeof _paq !== 'undefined'){ // trackEvent(category, action, [name], [value]) _paq.push(['trackEvent', 'RandomPlayer', 'stop']); } }, next(){ console.log('RandomPlayer next', this.active, this.shuffledPlaylist.length); if(this.active){ if (this.shuffledPlaylist.length == 0) { this.shuffle(); } _audioPlayer.openDocument(this.shuffledPlaylist.splice(0,1)[0], 'random'); } }, onAudioPlayNext(){ console.log('RandomPlayer : onAudioPlayNext()'); if(this.active){ this.next(); } }, onAudioPlayerEnded(){ console.log('RandomPlayer : onAudioPlayerEnded()'); if(this.active){ this.next(); if(_is_expo){ _$corpus_canvas.trigger({'type':'scramble-collection'}); //shuffle-collection scramble-collection } } } }; // ___ ___ _ // / __|___ _ __ _ __ ___| _ \ |__ _ _ _ ___ _ _ // | (__/ _ \ ' \| '_ \/ _ \ _/ / _` | || / -_) '_| // \___\___/_|_|_| .__/\___/_| |_\__,_|\_, \___|_| // |_| |__/ function CompoPlayer(){ this.active = false; this.playing = false; this.paused = false; this.playlist = []; this.current_index = 0; this.$composer = null; this.$compo = null; this.$controls = null; this.init(); }; CompoPlayer.prototype = { init(){ // console.log('CompoPlayer init()'); // attach an event on AudioPlayer _audioPlayer .on('audio-open-document', this.onAudioOpenDocument.bind(this)) .on('audio-play', this.onAudioPlayerPlay.bind(this)) .on('audio-pause', this.onAudioPlayerPause.bind(this)) .on('audio-ended', this.onAudioPlayerEnded.bind(this)); // .on('audio-play-next', this.onAudioPlayNext.bind(this)); // this.newCompo(); }, newCompo(){ console.log('CompoPlayer newCompo()'); // this.$compo = $('.composition_ui .composer .composition'); this.initControls(); }, initControls(){ //console.log('CompoPlayer initControls()'); this.$composer = $('.composition_ui .composer'); this.$compo = $('.composition_ui .composer .composition'); this.$controls = $('.composition_ui .composer .compo-player-controls'); if(!this.$controls.is('.ready') && this.$compo){ this.$previous = $('
').addClass('previous') .on('click', this.prev.bind(this)) .appendTo(this.$controls); this.$playpause = $('
').addClass('play-pause') .on('click', this.togglePlayPause.bind(this)) .appendTo(this.$controls); this.$next = $('
').addClass('next') .on('click', this.next.bind(this)) .appendTo(this.$controls); this.$controls.addClass('ready'); this.active = true; // this.newCompo(); } this.refresh(); }, refresh(){ // console.log('CompoPlayer refresh(), this', this); this.stop(); // load new playlist this.playlist = []; var that = this; $('.field--name-documents .field__item',this.$compo).each(function(i,el){ var $link = $('a.audio-link',this); that.playlist.push({ item:$(this), audio_url:$link.attr("audio_url"), nid:$link.attr("nid"), }); }); this.showHideControls(); }, togglePlayPause(){ // console.log('CompoPlayer togglePlayPause'); if (this.playing && !this.paused) { this.pause(); }else{ if(this.playing && this.paused){ this.play(); }else{ this.start(); } } }, start(i){ //console.log('start'); // console.log('CompoPlayer start()'); this.current_index = i || 0; this.playing = true; this.play(); }, play(){ console.log('CompoPlayer play()', this.playlist[this.current_index]); if(this.paused){ this.paused = false; _audioPlayer.play(); }else{ console.log('CompoPlayer opendoc with audio player'); // _audioPlayer; _audioPlayer.emmit('stop-shuffle').openDocument(this.playlist[this.current_index], this); } this.setActiveItem().showHideControls(); }, pause(){ //console.log('pause'); this.paused = true; this.showHideControls(); _audioPlayer.stop(); }, next(){ console.log('CompoPlayer next()',this.playing); if(this.playing){ this.current_index += 1; if(this.current_index < this.playlist.length){ this.play(); }else{ this.stop(); } } }, prev(){ // console.log('CompoPlayer prev()'); if(this.playing){ this.current_index -= 1; if(this.current_index >= 0){ this.play(); }else{ this.stop(); } } }, stop(){ if(this.playing){ _audioPlayer.stop(); } this.reset(); }, reset(){ this.playing = false; this.paused = false; this.resetIndex(); }, resetIndex(){ this.current_index = 0; this.showHideControls().resetActiveItems(); }, setActiveItem(){ this.resetActiveItems(); if(this.playing && this.current_index >= 0){ this.playlist[this.current_index].item.addClass('is-active'); } // this call shoud not be here this.showHideControls(); return this; }, resetActiveItems(){ for (var n = 0; n < this.playlist.length; n++) { // console.log('node',node); this.playlist[n].item.removeClass('is-active'); } return this; }, showHideControls(){ // console.log('CompoPlayer showHideNextBtn(), playing:'+this.playing+', paused:'+this.paused); // global playing if(this.$controls){ if(this.playing && !this.paused){ this.$controls.addClass('is-playing'); }else{ this.$controls.removeClass('is-playing'); } } // playpause if(this.$playpause){ if(this.playlist.length > 0){ this.$playpause.addClass('is-active'); }else{ this.$playpause.removeClass('is-active'); } } // next if(this.$next){ if(this.playing && this.playlist.length > 1 && this.current_index < this.playlist.length -1){ this.$next.addClass('is-active'); }else{ this.$next.removeClass('is-active'); } } // previous if(this.$previous){ if(this.playing && this.playlist.length > 1 && this.current_index > 0){ this.$previous.addClass('is-active'); }else{ this.$previous.removeClass('is-active'); } } return this; }, deactivate(){ this.stop(); this.active = false; }, // _audioPlayer events onAudioOpenDocument(args){ console.log('Compo player onAudioOpenDocument', args); if(args.caller !== this){ // console.log('CompoPlayer onAudioOpenDocument() called by other'); this.reset(); } // else{ // // console.log('CompoPlayer onAudioOpenDocument() self calling'); // } }, onAudioPlayerPlay(){ if(this.playing && this.paused){ this.paused = false; this.showHideControls(); } }, onAudioPlayerPause(){ if(this.playing && !this.paused){ this.paused = true; this.showHideControls(); } }, onAudioPlayerEnded(){ console.log('onAudioPlayerEnded'); if(this.playing){ // this paused shoudn't be true but i'm lazzy to find why it is ... this.paused = false; this.next(); } }, // onAudioPlayNext(){ // this.next(); // } }; // ___ // | __|_ ___ __ ___ // | _|\ \ / '_ \/ _ \ // |___/_\_\ .__/\___/ // |_| function initExpo(){ console.log('initExpo', window.location.hash); document.title = edlp.site_name; if(window.location.hash == '#black'){ $('body').addClass('expo-black'); } _$body.on('map-node-opened', checkExpoPlayerPositionning); _randomPlayer.start(); initKeyboard(); } function checkExpoPlayerPositionning(e){ console.log('checkExpoPlayerPositionning', e.node); // optimized for 1280px width screen switch(true){ case e.node.x > window.innerWidth-610 && e.node.y < 200: _audioPlayer.$container.attr('pos', 'bottom-left'); break; case e.node.x > window.innerWidth-610: _audioPlayer.$container.attr('pos', 'top-left'); break; case e.node.y < 200: _audioPlayer.$container.attr('pos', 'bottom-right'); break; default: _audioPlayer.$container.attr('pos', 'top-right'); } _audioPlayer.$container.css({ 'display':"block", 'left':e.node.x+"px", 'top':e.node.y+"px", }); } function initKeyboard(){ $(document).bind('keyup', 'alt+n', function(){ _randomPlayer.next(); }); } // ___ _ _ // / __|_ _(_)__| | // | (_ | '_| / _` | // \___|_| |_\__,_| function initGrid(){ console.log('theme : initGrid'); if(!_is_mobile){ checkGridBlockHeight(); _$row.find('.col').addClass('offfield'); } if(false){ var $grid = $('.grid',_$row).masonry({ itemSelector:'.col', columnWidth:'.col-2', containerStyle: null, resizeContainer:false, // horizontalOrder: true, transitionDuration:0,//'0.2s', // stagger:30, // disable initial layout // initLayout: false, }); // layout Masonry after each image loads $grid.imagesLoaded().progress( function() { $grid.masonry('layout'); }); $grid.imagesLoaded(function(){ $grid.masonry('layout'); // checkProductionBlockVisible(); }); // bind event // $grid.masonry( 'on', 'layoutComplete', function() { // console.log('layout is complete'); // }); $grid.on('layoutComplete', checkGridBlockVisible); }else{ // setTimeout(checkGridBlockVisible, 100); if(!_is_mobile){ checkGridBlockVisible(); } } }; function checkGridBlockHeight(){ // console.log('checkGridBlockHeight'); // if(_is_mobile) return; var $r_h = _$row.height(); var $this; // console.log($r_h); $('.grid .col', _$row).each(function(i,e){ $this = $(this); if(!$this.is('[init-height]')){ $this.attr('init-height', $this.outerHeight()) } // console.log($(this).height(), $(this).innerHeight(), $(this).outerHeight()); // if($this.height() > $r_h){ // $this.height($r_h); // }else{ // $this.height('auto'); // } $this.height(Math.min($this.attr('init-height'), _$row.height())); }); }; function checkGridBlockVisible(){ // console.log('checkGridBlockVisible'); // if(_is_mobile) return; var $r_h = _$row.height(); var $this,pos; $('.grid .col', _$row).each(function(i,e){ // $(this).on('load',function(event){ $this = $(this); pos = $this.position(); // console.log(pos.top, $this.height(), pos.top+$this.height(), $r_h, $this); if(pos.top+$this.height() <= $r_h){ $this.removeClass('offfield'); }else{ $this.addClass('offfield'); } // }); }); // for (var i in items) { // if(!items[i].isTransitioning){ // console.log('y+outerHeight', items[i].position.y+items[i].size.outerHeight); // console.log('_$row.height()', _$row.height()); // if(items[i].position.y+items[i].size.outerHeight < _$row.height()){ // $(items[i].element).removeClass('offfield'); // }else{ // // $(items[i].element).addClass('offfield'); // } // } // } } // ___ _ _ _ // | _ \_ _ ___ __| |_ _ __| |_(_)___ _ _ ___ // | _/ '_/ _ \/ _` | || / _| _| / _ \ ' \(_-< // |_| |_| \___/\__,_|\_,_\__|\__|_\___/_||_/__/ // function initProductions(){ // console.log('theme : initProductions'); // // // _$row.find('.col').addClass('offfield'); // var $grid = $('.grid',_$row).masonry({ // itemSelector:'.col', // columnWidth:'.col-2', // containerStyle: null, // resizeContainer:false, // // horizontalOrder: true, // transitionDuration:0,//'0.2s', // // stagger:30, // // disable initial layout // // initLayout: false, // }); // // // layout Masonry after each image loads // $grid.imagesLoaded().progress( function() { // $grid.masonry('layout'); // }); // // $grid.imagesLoaded(function(){ // $grid.masonry('layout'); // // checkProductionBlockVisible(); // }); // // // bind event // // $grid.masonry( 'on', 'layoutComplete', function() { // // console.log('layout is complete'); // // }); // // $grid.on('layoutComplete', checkProductionBlockVisible); // }; // ___ _ _ _ _ // / __|___| | |___ __| |_(_)___ _ _ // | (__/ _ \ | / -_) _| _| / _ \ ' \ // \___\___/_|_\___\__|\__|_\___/_||_| // mobile version of collection function initCollectionNav(){ console.log('initCollectionNav'); // taxonomy-term.vocabulary-entrees.home_mobile $('.field--name-field-notice, .index', '.taxonomy-term.vocabulary-entrees.home_mobile') .addClass('closed'); $('.field--name-field-notice>.field__label', '.taxonomy-term.vocabulary-entrees.home_mobile') .on('click', onClickCollectionNotice); $('.index>.field__label', '.taxonomy-term.vocabulary-entrees.home_mobile') .on('click', onClickCollectionIndex); }; function onClickCollectionNotice(e){ // console.log('onClickCollectionNotice'); // var $part = $(this).parent();//parents('.taxonomy-term'); toggleEntreeOpening($(this).parent(), 'notice'); }; function onClickCollectionIndex(e){ // console.log('onClickCollectionIndex'); // var $part = $(this).parent();//parents('.taxonomy-term'); toggleEntreeOpening($(this).parent(), 'index'); }; function toggleEntreeOpening($e, part){ $e.toggleClass('closed') .parents('.taxonomy-term.vocabulary-entrees.home_mobile').toggleClass(part+'-opened'); } // ___ _ // / __| ___ __ _ _ _ __| |_ // \__ \/ -_) _` | '_/ _| ' \ // |___/\___\__,_|_| \__|_||_| function initSearch(){ // if($('#edit-entries input:checked', '#edlp-search-form').length){ // $('#edit-entries--wrapper', '#edlp-search-form').toggleClass('opened'); // } $('#edit-entries--wrapper legend', '#edlp-search-form').on('click', function(){ $(this).parent().toggleClass('opened'); }); }; // ___ _ _ _ // | __|_ _ _ _ ___ __ _(_)__| |_ _ _ ___ _ __ ___ _ _| |_ // | _|| ' \| '_/ -_) _` | (_-< _| '_/ -_) ' \/ -_) ' \ _| // |___|_||_|_| \___\__, |_/__/\__|_| \___|_|_|_\___|_||_\__| // |___/ function initEnregistrementTranscript(){ console.log('initEnregistrementTranscript'); var $node = _$row.find('article.node--type-enregistrement.node--view-mode-transcript'); var $nav = $('