| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038 | (function($, Drupal, drupalSettings) {  EdlpTheme = function(){    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;    //  ___      _ _    // |_ _|_ _ (_) |_    //  | || ' \| |  _|    // |___|_||_|_|\__|    function init(){      console.log("EdlpTheme init()");      // if(!drupalSettings.path.isFront)      //   return;      if(_is_mobile){        initMobile();      }      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');      }      // if(!drupalSettings.path.isFront)      //   return;      //      // initEvents();    };    //  __  __     _    _ _    // |  \/  |___| |__(_) |___    // | |\/| / _ \ '_ \ | / -_)    // |_|  |_\___/_.__/_|_\___|    function initMobile(){      // $('[data-drupal-link-system-path="<front>"]','#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');    // }    //  ___             _    // | __|_ _____ _ _| |_ ___    // | _|\ 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 = window.location.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{        _$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');      // url is null means that we are loading content on popState event      // so we don't record the state again      if(state.url){        // var state = {        //   ajax_path:ajax_path,        //   sys_path:sys_path,        // };        // console.log('url:'+url+' ; state',state);        // console.log(window.location);        // /!\ 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')        .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($('<span>')          .addClass('close-col-btn')          .on('click', onCloseModal)        );      });    };    function onCloseModal(e){      // 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 = window.location.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);        // 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'){            // 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;            // we don't laod ajax content so we boot the home            _$body.attr('booted', 'booted');          }else{            // 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('onPopState',e.state);      if(e.state.home){        backToFrontPage(true);      }      else if (e.state.audio) {          _audioPlayer.openDocument(e.state.node, 'popstate', e.state.historic_index);      }      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-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;        // open audio player        _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 == '<front>'){        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;      }      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 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);      // 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   = $('<div id="audio-player">');      // btns      this.$btns        = $('<div>').addClass('btns').appendTo(this.$container);      this.$previous    = $('<div>').addClass('previous').appendTo(this.$btns);      this.$playpause   = $('<div>').addClass('play-pause').appendTo(this.$btns);      this.$next        = $('<div>').addClass('next').appendTo(this.$btns);      // timeline      this.$timelinecont= $('<div>').addClass('time-line-container').appendTo(this.$container);      this.$timeline    = $('<div>').addClass('time-line').appendTo(this.$timelinecont);      this.$loader      = $('<div>').addClass('loader').appendTo(this.$timeline);      this.$cursor      = $('<div>').addClass('cursor').appendTo(this.$timeline);      // time      this.$time        = $('<div>').addClass('time').appendTo(this.$container);      this.$currentTime = $('<div>').addClass('current-time').html('00:00').appendTo(this.$time);      this.$duration    = $('<div>').addClass('duration').html('00:00').appendTo(this.$time);      // favoris      this.$fav       = $('<div>').addClass('favoris').appendTo(this.$container);      // cartel      this.$cartel       = $('<div>').addClass('cartel').appendTo(this.$container);      this.scndCartel_visible = 0;      this.cartelSwitchIntervalMS = 7000;      this.cartelSwitchInterval = false;      // hiding      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(){        this.$container_parent = $('header[role="banner"] .region-header');        // 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);        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'){          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();        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('<span>'+(mins<10 ? '0':'')+mins+':'+(secs<10 ? '0':'')+secs+'</span>');        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();        // 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;      },      // 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('<span>'+(mins<10 ? '0':'')+mins+':'+(secs<10 ? '0':'')+secs+'</span>');      },      onEnded(){        console.log('AudioPlayer onEnded()');        this.stop();        this.emmit('audio-ended');      },      // cartel functions      loadNode(nid){        this.$cartel.addClass('loading');        var vm = 'player_cartel';        var ajax_path = _ajax_settings.entityjson_path+'/node/'+nid+'/'+vm;        var path = window.location.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 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)        Drupal.attachBehaviors(this.$cartel);        // 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.$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.$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 =  drupalSettings.path.baseUrl+drupalSettings.path.pathPrefix+'#random'      this.$btn = $('<a>')        .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();        $('<div>')          .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('audio-ended', function(e){          //   console.log('RandomPlayer, audio-ended', e);          // })          .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();          // window.location.hash = '';        }      },      updatePlaylist(e){        // debugger;        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 && this.shuffledPlaylist.length > 0)          _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();        }      }    };    //   ___                     ___ _    //  / __|___ _ __  _ __  ___| _ \ |__ _ _  _ ___ _ _    // | (__/ _ \ '  \| '_ \/ _ \  _/ / _` | || / -_) '_|    //  \___\___/_|_|_| .__/\___/_| |_\__,_|\_, \___|_|    //                |_|                   |__/    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 = $('<div>').addClass('previous')            .on('click', this.prev.bind(this))            .appendTo(this.$controls);          this.$playpause = $('<div>').addClass('play-pause')            .on('click', this.togglePlayPause.bind(this))            .appendTo(this.$controls);          this.$next = $('<div>').addClass('next')            .on('click', this.next.bind(this))            .appendTo(this.$controls);          this.$controls.addClass('ready');          this.refresh();          this.active = true;          // this.newCompo();        }      },      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(){        //console.log('start');        // console.log('CompoPlayer start()');        this.playing = true;        this.play();      },      play(){        // console.log('play');        if(this.paused){          this.paused = false;          _audioPlayer.play();        }else{          // _audioPlayer;          _audioPlayer.emmit('stop-shuffle').openDocument(this.playlist[this.current_index], this);          // TODO: stop random player        }        this.setActiveItem().showHideControls();      },      pause(){        //console.log('pause');        this.paused = true;        this.showHideControls();        _audioPlayer.stop();      },      next(){        // console.log('CompoPlayer next()');        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){        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(){        if(this.playing){          this.next();        }      },      // onAudioPlayNext(){      //   this.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 = $('<nav>').prependTo($node);      $node.find('.field--name-field-transcript-vo').addClass('visible').find('.field__label')        .clone().appendTo($nav).addClass('is-active')        .attr('field_target', '.field--name-field-transcript-vo');      $node.find('.field--name-field-transcript-trad').find('.field__label')        .clone().appendTo($nav)        .attr('field_target', '.field--name-field-transcript-trad');      $nav.find('.field__label').on('click', function(){        var $this = $(this).addClass('is-active');        $this.siblings('.is-active').removeClass('is-active');        $this.parents('article.node').find('.field.visible').removeClass('visible');        $this.parents('article.node').find($this.attr('field_target')).addClass('visible');      });    };    //  ___            _   ___    // | __| _ ___ _ _| |_| _ \__ _ __ _ ___    // | _| '_/ _ \ ' \  _|  _/ _` / _` / -_)    // |_||_| \___/_||_\__|_| \__,_\__, \___|    //                             |___/    function backToFrontPage(pop_state){      console.log('backToFrontPage', pop_state);      closeAllModals();      // assume we are going back to front page      $('body').removeClass().addClass('path-frontpage');      $('a[data-drupal-link-system-path="<front>"]').addClass('is-active');      // close entrees      if(_corpus_ready){        _$corpus_canvas.trigger({'type':'close-all-entree'});        _$corpus_canvas.trigger({'type':'scramble-collection'});      }      if(typeof pop_state == "undefined" || !pop_state){        console.log('backToFrontPage push state');        history.pushState({home:true}, null, drupalSettings.path.baseUrl+drupalSettings.path.currentLanguage);      }    }    // function initHome(){    //   addCloseModalBtnToCols();      // return;      // console.log('theme : initHome');      // var $grid = $('.grid',_$row).masonry({      //   itemSelector:'.col',      //   columnWidth:'.col-2',      //   horizontalOrder: true,      //   containerStyle: null,      //   // disable initial layout      //   // initLayout: false,      // });      // // bind event      // // $grid.masonry( 'on', 'layoutComplete', function() {      // //   console.log('layout is complete');      // // });      //      // // layout Masonry after each image loads      // $grid.imagesLoaded().progress( function() {      //   $grid.masonry('layout');      // });      //      // $grid.imagesLoaded(function(){      //   $grid.masonry('layout');      // });    // }    //  __  __         _      _    // |  \/  |___  __| |__ _| |___    // | |\/| / _ \/ _` / _` | (_-<    // |_|  |_\___/\__,_\__,_|_/__/    function closeAllModals(){      //console.log('theme : closeAllModals');      // TODO: animate the remove      _$row.html('');      _$ajaxLinks.removeClass('is-active');      _$body.trigger({'type':'all-modal-closed'});      // checkRowEmpty();    };    function checkRowEmpty(){      console.log('checkRowEmpty');      // if row is empty and we are not in productions or entree notice|index call closeAllModals()      if(!$('.col', _$row).length){        if(!_$body.is('.entity-type-taxonomy_term.bundle-entrees')){          if(!_$body.is('.entity-type-node.bundle-page')){            // we weren't on production or entree, so go back to front page            // debugger;            if(_$body.is('.bundle-enregistrement.view-mode-article')              && $('a.articles-link').is('.is-active')){                console.log('Closing article while article index is active');                // if node article and articles is active, reload index                $('a.articles-link').removeClass('is-active').trigger('click');            }else{              backToFrontPage();            }            // if(!$('a.articles-link').is('.is-active')){            //   // don't go back to front page if articles filter is on              // backToFrontPage();            // }else{            // }          }else{            // if we were on production page just scramble collection in case of map was filtered            if(_corpus_ready){              _$corpus_canvas.trigger({'type':'scramble-collection'});            }            // reload production home            $('a[data-drupal-link-system-path="productions"]', '#block-mainnavigation')              .removeClass('is-active').trigger('click');          }        }else{          // remove is-active class from index or notice entree links          $('.entree-content a.is-active').removeClass('is-active');          // TODO: remove the hash index or notice        }      }    };    init();  } // end EdlpTheme()  $(document).ready(function($) {    if(drupalSettings.path.isFront){      var edlptheme = new EdlpTheme();    }else{      $('body').attr('booted', 'booted');    }  });})(jQuery, Drupal, drupalSettings);
 |