<commit_before>(function () {
  "use strict";

  var app = angular.module('viewCustom', ['angularLoad']);

  app.run(['$rootScope', '$location', '$window', function ($rootScope, $location, $window) {
    //record GA page view event to new primo tracker GA ID
    $rootScope.$on('$locationChangeSuccess', function (event) {
      //temporarily create a tracker specifically to new Primo
      if ($window.ga) {
        $window.ga(function () {
          $window.ga('create', 'UA-4365437-14', 'search.library.uq.edu.au', 'NewPrimoTracker');
        });
        $window.ga('NewPrimoTracker.send', 'pageview', { location: $location.url() });
      }
    });

  }]);

  app.component('prmTopBarBefore', {
    template: '
<uqlibrary-alerts></uqlibrary-alerts>
' +
      '
<uq-minimal-header show-login-button="false"></uq-minimal-header>
'
  });

  /****************************************************************************************************/

  /*In case of CENTRAL_PACKAGE - comment out the below line to replace the other module definition*/

  /*var app = angular.module('centralCustom', ['angularLoad']);*/

  /****************************************************************************************************/

  /*
    * this is on hold until May, when the newspaper-articles exclusion will apparently move out of the url
    * Problems with this 'lock facets' code
    * it cant remove multiple facets on a subsequent load
    * eg
    * 1. search 'library' on homepage, it loads & locks facets newspaper_articles and reviews
    * 2. return to homepage and search 'books' - only one of 'reviews' and 'newspaper_articles' will be removed
    *
    * Incomplete:
    * - I havent quite got the physical items search working properly yet (&facet=tlevel,include,physical_items)
    * ** the immediate prior version handle tlevel, but is too slow - consider how it is handling tlevel & library, though
    * - and this still needs cleaning up
    *
    * sample searches:
    * https://uq-edu-primo-sb.hosted.exlibrisgroup.com/primo-explore/search?query=any,contains,frogs&tab=61uq_all&search_scope=61UQ_All&sortby=rank&vid=61UQ_DEV&facet=rtype,include,books&facets=locked
    * https://uq-edu-primo-sb.hosted.exlibrisgroup.com/primo-explore/search?query=any,contains,frogs&tab=61uq_all&search_scope=61UQ_All&sortby=rank&vid=61UQ_DEV&facet=rtype,include,media&facets=locked
    * https://uq-edu-primo-sb.hosted.exlibrisgroup.com/primo-explore/search?query=any,contains,frogs&tab=61uq_all&search_scope=61UQ_All&sortby=rank&vid=61UQ_DEV&facet=rtype,exclude,newspaper_articles&facet=rtype,exclude,reviews&offset=0&facets=locked
    *
   */

  // lock facets
  // Based on code supplied by Univerisity of Otago eg. https://otago.hosted.exlibrisgroup.com/primo-explore/search?query=any,contains,frogs&tab=default_tab&search_scope=All&vid=DUNEDIN&facet=rtype,exclude,reviews&offset=0&ref=http:%2F%2Fmarvin.otago.ac.nz
  // add '&facets=locked' tag to any referer to a search results page you want this to happen on
  // app.controller('prmExploreMainAfterController', function($scope) {
  //    setTimeout(function(){
  //      var tag = "facets=locked";
  //      if (!(window.location.search.indexOf(tag) > 0 && window.location.search.indexOf("facet=") > 0)) {
  //        return;
  //      }
  //
  //      waitForElementToDisplay('prm-breadcrumbs div div div button prm-icon > md-icon', 1000);
  //
  //      function waitForElementToDisplay(selector, time) {
  //        if (document.querySelector(selector) !== null) {
  //          // in the case where this is a second search via the homepage, we need to unlock previous locked ones
  //          // this means we need to hard code a list to check, because this page doesnt know what other search options are provided on the home page
  //          // if any future queries add different facets, this list will have to be updated
  //          // key = value in url eg books in facet=rtype,exclude,books
  //          // value = value on aria-label element of button to be clicked
  //          var validFacets = {
  //            'reviews': 'Reviews',
  //            'books': 'Books',
  //            'newspaper_articles': 'Newspaper Articles',
  //            'articles': 'Articles',
  //            'media': 'Video & Audio',
  //            'physical_items': 'Physical items'
  //          };
  //
  //          var queries = window.location.search.split('&');
  //          if (queries.length > 1) {
  //            var facetsInUrl = [];
  //            queries.map(function (e) {
  //              // get the facet in the from all the different types
  //              if (0 === e.indexOf("facet=rtype,exclude,")) {
  //                facetsInUrl.push(e.replace("facet=rtype,exclude,", ''));
  //              } else if (0 === e.indexOf("facet=rtype,include,")) {
  //                facetsInUrl.push(e.replace("facet=rtype,include,", ''));
  //              } else if (0 === e.indexOf("facet=tlevel,exclude,")) {
  //                facetsInUrl.push(e.replace("facet=tlevel,exclude,", ''));
  //              } else if (0 === e.indexOf("facet=tlevel,include,")) {
  //                facetsInUrl.push(e.replace("facet=tlevel,include,", ''));
  //              }
  //            });
  //
  //            // do all the settings first because the later facet removal refreshes the page, losing our tag
  //            var facet, ariaLabel, facetSelector;
  //            for (facet in validFacets) {
  //              if (facetsInUrl.indexOf(facet) !== -1) {
  //                // found in the url - lock it
  //                ariaLabel = 'Make this filter persistent throughout the session ' + validFacets[facet];
  //                facetSelector = document.querySelector('[aria-label="' + ariaLabel + '"]');
  //                if (facetSelector !== null) {
  //                  angular.element(facetSelector).triggerHandler('click');
  //                }
  //              }
  //            }
  //
  //            var thisFacet, ariaLabelLock, facetSelectorLock;
  //            for (facet in validFacets) {
  //              if (facetsInUrl.indexOf(facet) !== -1) {
  //                // skip any that are for this page
  //              } else {
  //                // remove a facet if it was locked from an earlier search
  //                thisFacet = validFacets[facet];
  //                ariaLabel = 'Remove Content type ' + thisFacet;
  //                facetSelector = document.querySelector('[aria-label="' + ariaLabel + '"]'); // the x (remove) button exists to click
  //                ariaLabelLock = 'Cancel persistence ' + thisFacet;
  //                facetSelectorLock = document.querySelector('[aria-label="' + ariaLabelLock + '"]'); // the 'locked' button exists - this is one we should remove
  //                if (facetSelector !== null && facetSelectorLock !== null) {
  //                  angular.element(facetSelector).triggerHandler('click');
  //                  //once this is clicked the page will refresh and wont have our tag on the end :(
  //                  // so only one is ever done :(
  //                }
  //              }
  //            }
  //
  //            return;
  //          }
  //          else {
  //            setTimeout(function () {
  //              waitForElementToDisplay(selector, time);
  //            }, time);
  //          }
  //        }
  //      }
  //    }, 2500);
  //  });
  //
  //  app.component('prmExploreMainAfter', {
  //    bindings: {
  //      parentCtrl: '<'
  //    },
  //    controller: 'prmExploreMainAfterController'
  //  });
  // End lock facets

  app.controller('prmOpenJournalInFullController', [
    function () {
      var vm = this;
      vm.$onInit = function () {
        var resourceType = vm.parentCtrl.result.pnx.display.type[0] || '';
        if (resourceType === 'journal') {
          vm.parentCtrl.isDirectLink = function () { return false; };
        }
      };
    }
  ]);

  app.component('prmOpenJournalInFull', {
    bindings: { parentCtrl: '<' },
    controller: 'prmOpenJournalInFullController'
  });

  app.component('prmSearchResultAvailabilityLineAfter', {
    bindings: { parentCtrl: '<' },
    template: '<prm-open-journal-in-full parent-ctrl="$ctrl.parentCtrl"></prm-open-journal-in-full>'
  });

  function insertScript(url) {
    var script = document.querySelector("script[src*='" + url + "']");
    if (!script) {
      var heads = document.getElementsByTagName("head");
      if (heads && heads.length) {
        var head = heads[0];
        if (head) {
          script = document.createElement('script');
          script.setAttribute('src', url);
          script.setAttribute('type', 'text/javascript');
          head.appendChild(script);
        }
      }
    }
  }

  function insertLink(link) {
    var linkTag = document.querySelector("link[href*='" + link.href + "']");
    if (!linkTag) {
      var heads = document.getElementsByTagName("head");
      if (heads && heads.length) {
        var head = heads[0];
        if (head) {
          linkTag = document.createElement('link');
          linkTag.setAttribute('href', link.href);
          linkTag.setAttribute('rel', link.rel);
          head.appendChild(linkTag);
        }
      }
    }
  }

  // start and end with slash unless prod, which is just a single slash
  var branchName = '/primo-sand-box-dev/';

  var scripts = [
    '//assets.library.uq.edu.au' + branchName + 'reusable-components/webcomponentsjs/webcomponents-lite.min.js',
    '//assets.library.uq.edu.au' + branchName + 'reusable-components/resources/preloader.js',
    '//assets.library.uq.edu.au' + branchName + 'reusable-components/primo2/load.js'
  ];

  var links = [
    { rel: 'import', href: '//assets.library.uq.edu.au' + branchName + 'reusable-components/elements.vulcanized.html' },
    { rel: 'stylesheet', href: '//assets.library.uq.edu.au' + branchName + 'reusable-components/primo2/custom-styles.css' }
  ];

  insertLink(links[0]);
  insertLink(links[1]);

  insertScript(scripts[0]);
  insertScript(scripts[1]);
  insertScript(scripts[2]);

})();

/* StackMap: Start */
(function(){

  var a = document.querySelector("head");
  var css1 = document.createElement("link");
  css1.type = "text/css";
  css1.rel = "Stylesheet";
  css1.href = "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css";
  css1.crossorigin = "anonymous";
  a.appendChild(css1);

  var css2 = document.createElement("link");
  css2.type = "text/css";
  css2.rel = "Stylesheet";
  css2.href = "https://www.stackmap.com/integration/uq-primo2/StackMap.css";
  a.appendChild(css2);

  var w = document.createElement("script");
  w.type = "text/javascript"; w.async = true;
  w.src = "https://www.stackmap.com/integration/uq-primo2/StackMap.js";
  var b = document.body;
  b.appendChild(w);

})();
/* StackMap: END */
<commit_msg>set up the branch names so they are 'pick one' rather than 'figure out what to use' [PT #167749020]<commit_after>(function () {
  "use strict";

  var app = angular.module('viewCustom', ['angularLoad']);

  app.run(['$rootScope', '$location', '$window', function ($rootScope, $location, $window) {
    //record GA page view event to new primo tracker GA ID
    $rootScope.$on('$locationChangeSuccess', function (event) {
      //temporarily create a tracker specifically to new Primo
      if ($window.ga) {
        $window.ga(function () {
          $window.ga('create', 'UA-4365437-14', 'search.library.uq.edu.au', 'NewPrimoTracker');
        });
        $window.ga('NewPrimoTracker.send', 'pageview', { location: $location.url() });
      }
    });

  }]);

  app.component('prmTopBarBefore', {
    template: '
<uqlibrary-alerts></uqlibrary-alerts>
' +
      '
<uq-minimal-header show-login-button="false"></uq-minimal-header>
'
  });

  /****************************************************************************************************/

  /*In case of CENTRAL_PACKAGE - comment out the below line to replace the other module definition*/

  /*var app = angular.module('centralCustom', ['angularLoad']);*/

  /****************************************************************************************************/

  /*
    * this is on hold until May, when the newspaper-articles exclusion will apparently move out of the url
    * Problems with this 'lock facets' code
    * it cant remove multiple facets on a subsequent load
    * eg
    * 1. search 'library' on homepage, it loads & locks facets newspaper_articles and reviews
    * 2. return to homepage and search 'books' - only one of 'reviews' and 'newspaper_articles' will be removed
    *
    * Incomplete:
    * - I havent quite got the physical items search working properly yet (&facet=tlevel,include,physical_items)
    * ** the immediate prior version handle tlevel, but is too slow - consider how it is handling tlevel & library, though
    * - and this still needs cleaning up
    *
    * sample searches:
    * https://uq-edu-primo-sb.hosted.exlibrisgroup.com/primo-explore/search?query=any,contains,frogs&tab=61uq_all&search_scope=61UQ_All&sortby=rank&vid=61UQ_DEV&facet=rtype,include,books&facets=locked
    * https://uq-edu-primo-sb.hosted.exlibrisgroup.com/primo-explore/search?query=any,contains,frogs&tab=61uq_all&search_scope=61UQ_All&sortby=rank&vid=61UQ_DEV&facet=rtype,include,media&facets=locked
    * https://uq-edu-primo-sb.hosted.exlibrisgroup.com/primo-explore/search?query=any,contains,frogs&tab=61uq_all&search_scope=61UQ_All&sortby=rank&vid=61UQ_DEV&facet=rtype,exclude,newspaper_articles&facet=rtype,exclude,reviews&offset=0&facets=locked
    *
   */

  // lock facets
  // Based on code supplied by Univerisity of Otago eg. https://otago.hosted.exlibrisgroup.com/primo-explore/search?query=any,contains,frogs&tab=default_tab&search_scope=All&vid=DUNEDIN&facet=rtype,exclude,reviews&offset=0&ref=http:%2F%2Fmarvin.otago.ac.nz
  // add '&facets=locked' tag to any referer to a search results page you want this to happen on
  // app.controller('prmExploreMainAfterController', function($scope) {
  //    setTimeout(function(){
  //      var tag = "facets=locked";
  //      if (!(window.location.search.indexOf(tag) > 0 && window.location.search.indexOf("facet=") > 0)) {
  //        return;
  //      }
  //
  //      waitForElementToDisplay('prm-breadcrumbs div div div button prm-icon > md-icon', 1000);
  //
  //      function waitForElementToDisplay(selector, time) {
  //        if (document.querySelector(selector) !== null) {
  //          // in the case where this is a second search via the homepage, we need to unlock previous locked ones
  //          // this means we need to hard code a list to check, because this page doesnt know what other search options are provided on the home page
  //          // if any future queries add different facets, this list will have to be updated
  //          // key = value in url eg books in facet=rtype,exclude,books
  //          // value = value on aria-label element of button to be clicked
  //          var validFacets = {
  //            'reviews': 'Reviews',
  //            'books': 'Books',
  //            'newspaper_articles': 'Newspaper Articles',
  //            'articles': 'Articles',
  //            'media': 'Video & Audio',
  //            'physical_items': 'Physical items'
  //          };
  //
  //          var queries = window.location.search.split('&');
  //          if (queries.length > 1) {
  //            var facetsInUrl = [];
  //            queries.map(function (e) {
  //              // get the facet in the from all the different types
  //              if (0 === e.indexOf("facet=rtype,exclude,")) {
  //                facetsInUrl.push(e.replace("facet=rtype,exclude,", ''));
  //              } else if (0 === e.indexOf("facet=rtype,include,")) {
  //                facetsInUrl.push(e.replace("facet=rtype,include,", ''));
  //              } else if (0 === e.indexOf("facet=tlevel,exclude,")) {
  //                facetsInUrl.push(e.replace("facet=tlevel,exclude,", ''));
  //              } else if (0 === e.indexOf("facet=tlevel,include,")) {
  //                facetsInUrl.push(e.replace("facet=tlevel,include,", ''));
  //              }
  //            });
  //
  //            // do all the settings first because the later facet removal refreshes the page, losing our tag
  //            var facet, ariaLabel, facetSelector;
  //            for (facet in validFacets) {
  //              if (facetsInUrl.indexOf(facet) !== -1) {
  //                // found in the url - lock it
  //                ariaLabel = 'Make this filter persistent throughout the session ' + validFacets[facet];
  //                facetSelector = document.querySelector('[aria-label="' + ariaLabel + '"]');
  //                if (facetSelector !== null) {
  //                  angular.element(facetSelector).triggerHandler('click');
  //                }
  //              }
  //            }
  //
  //            var thisFacet, ariaLabelLock, facetSelectorLock;
  //            for (facet in validFacets) {
  //              if (facetsInUrl.indexOf(facet) !== -1) {
  //                // skip any that are for this page
  //              } else {
  //                // remove a facet if it was locked from an earlier search
  //                thisFacet = validFacets[facet];
  //                ariaLabel = 'Remove Content type ' + thisFacet;
  //                facetSelector = document.querySelector('[aria-label="' + ariaLabel + '"]'); // the x (remove) button exists to click
  //                ariaLabelLock = 'Cancel persistence ' + thisFacet;
  //                facetSelectorLock = document.querySelector('[aria-label="' + ariaLabelLock + '"]'); // the 'locked' button exists - this is one we should remove
  //                if (facetSelector !== null && facetSelectorLock !== null) {
  //                  angular.element(facetSelector).triggerHandler('click');
  //                  //once this is clicked the page will refresh and wont have our tag on the end :(
  //                  // so only one is ever done :(
  //                }
  //              }
  //            }
  //
  //            return;
  //          }
  //          else {
  //            setTimeout(function () {
  //              waitForElementToDisplay(selector, time);
  //            }, time);
  //          }
  //        }
  //      }
  //    }, 2500);
  //  });
  //
  //  app.component('prmExploreMainAfter', {
  //    bindings: {
  //      parentCtrl: '<'
  //    },
  //    controller: 'prmExploreMainAfterController'
  //  });
  // End lock facets

  app.controller('prmOpenJournalInFullController', [
    function () {
      var vm = this;
      vm.$onInit = function () {
        var resourceType = vm.parentCtrl.result.pnx.display.type[0] || '';
        if (resourceType === 'journal') {
          vm.parentCtrl.isDirectLink = function () { return false; };
        }
      };
    }
  ]);

  app.component('prmOpenJournalInFull', {
    bindings: { parentCtrl: '<' },
    controller: 'prmOpenJournalInFullController'
  });

  app.component('prmSearchResultAvailabilityLineAfter', {
    bindings: { parentCtrl: '<' },
    template: '<prm-open-journal-in-full parent-ctrl="$ctrl.parentCtrl"></prm-open-journal-in-full>'
  });

  function insertScript(url) {
    var script = document.querySelector("script[src*='" + url + "']");
    if (!script) {
      var heads = document.getElementsByTagName("head");
      if (heads && heads.length) {
        var head = heads[0];
        if (head) {
          script = document.createElement('script');
          script.setAttribute('src', url);
          script.setAttribute('type', 'text/javascript');
          head.appendChild(script);
        }
      }
    }
  }

  function insertLink(link) {
    var linkTag = document.querySelector("link[href*='" + link.href + "']");
    if (!linkTag) {
      var heads = document.getElementsByTagName("head");
      if (heads && heads.length) {
        var head = heads[0];
        if (head) {
          linkTag = document.createElement('link');
          linkTag.setAttribute('href', link.href);
          linkTag.setAttribute('rel', link.rel);
          head.appendChild(linkTag);
        }
      }
    }
  }

  // choose the branchname that matches this branch
  // var branchName = '/';                                 // <--- use / for master and prod
  // var branchName = '/primo-prod-dev/';
  // var branchName = '/primo-sand-box/';
  var branchName = '/primo-sand-box-dev/';

  var scripts = [
    '//assets.library.uq.edu.au' + branchName + 'reusable-components/webcomponentsjs/webcomponents-lite.min.js',
    '//assets.library.uq.edu.au' + branchName + 'reusable-components/resources/preloader.js',
    '//assets.library.uq.edu.au' + branchName + 'reusable-components/primo2/load.js'
  ];

  var links = [
    { rel: 'import', href: '//assets.library.uq.edu.au' + branchName + 'reusable-components/elements.vulcanized.html' },
    { rel: 'stylesheet', href: '//assets.library.uq.edu.au' + branchName + 'reusable-components/primo2/custom-styles.css' }
  ];

  insertLink(links[0]);
  insertLink(links[1]);

  insertScript(scripts[0]);
  insertScript(scripts[1]);
  insertScript(scripts[2]);

})();

/* StackMap: Start */
(function(){

  var a = document.querySelector("head");
  var css1 = document.createElement("link");
  css1.type = "text/css";
  css1.rel = "Stylesheet";
  css1.href = "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css";
  css1.crossorigin = "anonymous";
  a.appendChild(css1);

  var css2 = document.createElement("link");
  css2.type = "text/css";
  css2.rel = "Stylesheet";
  css2.href = "https://www.stackmap.com/integration/uq-primo2/StackMap.css";
  a.appendChild(css2);

  var w = document.createElement("script");
  w.type = "text/javascript"; w.async = true;
  w.src = "https://www.stackmap.com/integration/uq-primo2/StackMap.js";
  var b = document.body;
  b.appendChild(w);

})();
/* StackMap: END */
<|endoftext|>


<commit_before>(function () {
  "use strict";

  var app = angular.module('viewCustom', ['angularLoad']);

  app.run(['$rootScope', '$location', '$window', function ($rootScope, $location, $window) {
    //record GA page view event to new primo tracker GA ID
    $rootScope.$on('$locationChangeSuccess', function (event) {
      //temporarily create a tracker specifically to new Primo
      if ($window.ga) {
        $window.ga(function () {
          $window.ga('create', 'UA-4365437-14', 'search.library.uq.edu.au', 'NewPrimoTracker');
        });
        $window.ga('NewPrimoTracker.send', 'pageview', { location: $location.url() });
      }
    });

  }]);

  app.component('prmTopBarBefore', {
    template: '
<uqlibrary-alerts></uqlibrary-alerts>
' +
      '
<uq-minimal-header show-login-button="false"></uq-minimal-header>
'
  });

  /****************************************************************************************************/

  /*In case of CENTRAL_PACKAGE - comment out the below line to replace the other module definition*/

  /*var app = angular.module('centralCustom', ['angularLoad']);*/

  /****************************************************************************************************/

  /*
    * this is on hold until May, when the newspaper-articles exclusion will apparently move out of the url
    * Problems with this 'lock facets' code
    * it cant remove multiple facets on a subsequent load
    * eg
    * 1. search 'library' on homepage, it loads & locks facets newspaper_articles and reviews
    * 2. return to homepage and search 'books' - only one of 'reviews' and 'newspaper_articles' will be removed
    *
    * Incomplete:
    * - I havent quite got the physical items search working properly yet (&facet=tlevel,include,physical_items)
    * ** the immediate prior version handle tlevel, but is too slow - consider how it is handling tlevel & library, though
    * - and this still needs cleaning up
    *
    * sample searches:
    * https://uq-edu-primo-sb.hosted.exlibrisgroup.com/primo-explore/search?query=any,contains,frogs&tab=61uq_all&search_scope=61UQ_All&sortby=rank&vid=61UQ_DEV&facet=rtype,include,books&facets=locked
    * https://uq-edu-primo-sb.hosted.exlibrisgroup.com/primo-explore/search?query=any,contains,frogs&tab=61uq_all&search_scope=61UQ_All&sortby=rank&vid=61UQ_DEV&facet=rtype,include,media&facets=locked
    * https://uq-edu-primo-sb.hosted.exlibrisgroup.com/primo-explore/search?query=any,contains,frogs&tab=61uq_all&search_scope=61UQ_All&sortby=rank&vid=61UQ_DEV&facet=rtype,exclude,newspaper_articles&facet=rtype,exclude,reviews&offset=0&facets=locked
    *
   */

  // lock facets
  // Based on code supplied by Univerisity of Otago eg. https://otago.hosted.exlibrisgroup.com/primo-explore/search?query=any,contains,frogs&tab=default_tab&search_scope=All&vid=DUNEDIN&facet=rtype,exclude,reviews&offset=0&ref=http:%2F%2Fmarvin.otago.ac.nz
  // add '&facets=locked' tag to any referer to a search results page you want this to happen on
  // app.controller('prmExploreMainAfterController', function($scope) {
  //    setTimeout(function(){
  //      var tag = "facets=locked";
  //      if (!(window.location.search.indexOf(tag) > 0 && window.location.search.indexOf("facet=") > 0)) {
  //        return;
  //      }
  //
  //      waitForElementToDisplay('prm-breadcrumbs div div div button prm-icon > md-icon', 1000);
  //
  //      function waitForElementToDisplay(selector, time) {
  //        if (document.querySelector(selector) !== null) {
  //          // in the case where this is a second search via the homepage, we need to unlock previous locked ones
  //          // this means we need to hard code a list to check, because this page doesnt know what other search options are provided on the home page
  //          // if any future queries add different facets, this list will have to be updated
  //          // key = value in url eg books in facet=rtype,exclude,books
  //          // value = value on aria-label element of button to be clicked
  //          var validFacets = {
  //            'reviews': 'Reviews',
  //            'books': 'Books',
  //            'newspaper_articles': 'Newspaper Articles',
  //            'articles': 'Articles',
  //            'media': 'Video & Audio',
  //            'physical_items': 'Physical items'
  //          };
  //
  //          var queries = window.location.search.split('&');
  //          if (queries.length > 1) {
  //            var facetsInUrl = [];
  //            queries.map(function (e) {
  //              // get the facet in the from all the different types
  //              if (0 === e.indexOf("facet=rtype,exclude,")) {
  //                facetsInUrl.push(e.replace("facet=rtype,exclude,", ''));
  //              } else if (0 === e.indexOf("facet=rtype,include,")) {
  //                facetsInUrl.push(e.replace("facet=rtype,include,", ''));
  //              } else if (0 === e.indexOf("facet=tlevel,exclude,")) {
  //                facetsInUrl.push(e.replace("facet=tlevel,exclude,", ''));
  //              } else if (0 === e.indexOf("facet=tlevel,include,")) {
  //                facetsInUrl.push(e.replace("facet=tlevel,include,", ''));
  //              }
  //            });
  //
  //            // do all the settings first because the later facet removal refreshes the page, losing our tag
  //            var facet, ariaLabel, facetSelector;
  //            for (facet in validFacets) {
  //              if (facetsInUrl.indexOf(facet) !== -1) {
  //                // found in the url - lock it
  //                ariaLabel = 'Make this filter persistent throughout the session ' + validFacets[facet];
  //                facetSelector = document.querySelector('[aria-label="' + ariaLabel + '"]');
  //                if (facetSelector !== null) {
  //                  angular.element(facetSelector).triggerHandler('click');
  //                }
  //              }
  //            }
  //
  //            var thisFacet, ariaLabelLock, facetSelectorLock;
  //            for (facet in validFacets) {
  //              if (facetsInUrl.indexOf(facet) !== -1) {
  //                // skip any that are for this page
  //              } else {
  //                // remove a facet if it was locked from an earlier search
  //                thisFacet = validFacets[facet];
  //                ariaLabel = 'Remove Content type ' + thisFacet;
  //                facetSelector = document.querySelector('[aria-label="' + ariaLabel + '"]'); // the x (remove) button exists to click
  //                ariaLabelLock = 'Cancel persistence ' + thisFacet;
  //                facetSelectorLock = document.querySelector('[aria-label="' + ariaLabelLock + '"]'); // the 'locked' button exists - this is one we should remove
  //                if (facetSelector !== null && facetSelectorLock !== null) {
  //                  angular.element(facetSelector).triggerHandler('click');
  //                  //once this is clicked the page will refresh and wont have our tag on the end :(
  //                  // so only one is ever done :(
  //                }
  //              }
  //            }
  //
  //            return;
  //          }
  //          else {
  //            setTimeout(function () {
  //              waitForElementToDisplay(selector, time);
  //            }, time);
  //          }
  //        }
  //      }
  //    }, 2500);
  //  });
  //
  //  app.component('prmExploreMainAfter', {
  //    bindings: {
  //      parentCtrl: '<'
  //    },
  //    controller: 'prmExploreMainAfterController'
  //  });
  // End lock facets

  app.controller('prmOpenJournalInFullController', [
    function () {
      var vm = this;
      vm.$onInit = function () {
        var resourceType = vm.parentCtrl.result.pnx.display.type[0] || '';
        if (resourceType === 'journal') {
          vm.parentCtrl.isDirectLink = function () { return false; };
        }
      };
    }
  ]);

  app.component('prmOpenJournalInFull', {
    bindings: { parentCtrl: '<' },
    controller: 'prmOpenJournalInFullController'
  });

  app.component('prmSearchResultAvailabilityLineAfter', {
    bindings: { parentCtrl: '<' },
    template: '<prm-open-journal-in-full parent-ctrl="$ctrl.parentCtrl"></prm-open-journal-in-full>'
  });

  function insertScript(url) {
    var script = document.querySelector("script[src*='" + url + "']");
    if (!script) {
      var heads = document.getElementsByTagName("head");
      if (heads && heads.length) {
        var head = heads[0];
        if (head) {
          script = document.createElement('script');
          script.setAttribute('src', url);
          script.setAttribute('type', 'text/javascript');
          head.appendChild(script);
        }
      }
    }
  }

  function insertLink(link) {
    var linkTag = document.querySelector("link[href*='" + link.href + "']");
    if (!linkTag) {
      var heads = document.getElementsByTagName("head");
      if (heads && heads.length) {
        var head = heads[0];
        if (head) {
          linkTag = document.createElement('link');
          linkTag.setAttribute('href', link.href);
          linkTag.setAttribute('rel', link.rel);
          head.appendChild(linkTag);
        }
      }
    }
  }

  // this script should only be called on views that have UQ header showing
  var branchName = '/'; // default. Use for master and prod
  if (window.location.hostname === 'search.library.uq.edu.au') {
    if (/vid=61UQ_DEV/.test(window.location.href)) {
      branchName = '/primo-prod-dev/';
    }
  } else {
    if (/vid=61UQ_DEV/.test(window.location.href)) {
      branchName = '/primo-sand-box-dev/';
    } else if (/vid=61UQ/.test(window.location.href)) {
      branchName = '/primo-sand-box/';
    }
  }

  var scripts = [
    '//assets.library.uq.edu.au' + branchName + 'reusable-components/webcomponentsjs/webcomponents-lite.min.js',
    '//assets.library.uq.edu.au' + branchName + 'reusable-components/resources/preloader.js',
    '//assets.library.uq.edu.au' + branchName + 'reusable-components/primo2/load.js'
  ];

  var links = [
    { rel: 'import', href: '//assets.library.uq.edu.au' + branchName + 'reusable-components/elements.vulcanized.html' },
    { rel: 'stylesheet', href: '//assets.library.uq.edu.au' + branchName + 'reusable-components/primo2/custom-styles.css' }
  ];

  insertLink(links[0]);
  insertLink(links[1]);

  insertScript(scripts[0]);
  insertScript(scripts[1]);
  insertScript(scripts[2]);

})();
<commit_msg>first cut of report a bug button added to primo [PT #168829407]<commit_after>(function () {
  "use strict";

  var app = angular.module('viewCustom', ['customActions', 'angularLoad']);

  app.run(['$rootScope', '$location', '$window', function ($rootScope, $location, $window) {
    //record GA page view event to new primo tracker GA ID
    $rootScope.$on('$locationChangeSuccess', function (event) {
      //temporarily create a tracker specifically to new Primo
      if ($window.ga) {
        $window.ga(function () {
          $window.ga('create', 'UA-4365437-14', 'search.library.uq.edu.au', 'NewPrimoTracker');
        });
        $window.ga('NewPrimoTracker.send', 'pageview', { location: $location.url() });
      }
    });

  }]);

  // Add custom actions to the Actions Menu (stolen from onesearch.library.wwu.edu)
  app.constant('customActions', [{
    name: "Report A Problem",
    type: "template",
    icon: {
      set: "action",
      name: "ic_bug_report_24px"
    },
    action: "{CRMdomain}/app/library/contact/report_problem/true/incidents.subject/{recordTitle}/incidents.c$external_id/{recordId}"
  }]);

  angular.module('customActions', []).component('prmActionListAfter', {
    require: { prmActionCtrl: '^prmActionList' },
    controller: ['customActionsService', 'customActions', function (customActionsService, customActions) {
      this.$onInit = function () {
        customActionsService.setController(this.prmActionCtrl);
        customActions.map(function (action) {
          return customActionsService.addAction(action);
        });
      };
    }]
  }).factory('customActionsService', function () {
    return {
      setController: function setController(controller) {
        this.prmActionCtrl = controller;
      },
      processAction: function processAction(action) {
        action.iconname = action.name.replace(/\s+/g, ''), action.slug = action.name.replace(/\s+/g, '').toLowerCase(), action.index = Object.keys(this.prmActionCtrl.actionListService.actionsToIndex).length - 1;
        this.prmActionCtrl.actionLabelNamesMap[action.slug] = action.name;
        this.prmActionCtrl.actionIconNamesMap[action.slug] = action.iconname;
        this.prmActionCtrl.actionIcons[action.iconname] = {
          icon: action.icon.name,
          iconSet: action.icon.set,
          type: "svg"
        };
        return action;
      },
      addAction: function addAction(action) {
        var _this = this;

        action = this.processAction(action);
        var whitelistpages = [
          '/primo-explore/citationTrails',
          '/primo-explore/chapters',
          '/primo-explore/dbfulldisplay',
          '/primo-explore/dbsearch',
          '/primo-explore/fulldisplay',
          '/primo-explore/search',
        ];
        if (!this.prmActionCtrl.actionListService.actionsToIndex[action.slug]
          && -1 !== whitelistpages.indexOf(window.location.pathname)
        ) {
          this.prmActionCtrl.actionListService.requiredActionsList[action.index] = action.slug;
          this.prmActionCtrl.actionListService.actionsToDisplay.unshift(action.slug);
          this.prmActionCtrl.actionListService.actionsToIndex[action.slug] = action.index;
        }
        if (action.type === 'template') {
          // process { } in templateVars
          if (action.hasOwnProperty('templateVar')) {
            action.action = action.action.replace(/{\d}/g, function (r) {
              return action.templateVar[r.replace(/[^\d]/g, '')];
            });
          }
          // add the document id to the data passed to the crm report a problem page (in the url)
          action.action = action.action.replace(/{recordId}/g, function (r) {
            return encodeURIComponent(_this.prmActionCtrl.item.pnx.search.recordid[0]);
          });
          // add the record title to the data passed to the crm report a problem page (in the url)
          action.action = action.action.replace(/{recordTitle}/g, function (r) {
            return encodeURIComponent(_this.prmActionCtrl.item.pnx.search.title[0]);
          });
          // replace the domain for the crm report a problem page with the correct CRM domain
          action.action = action.action.replace(/{CRMdomain}/g, function (r) {
            if (window.location.hostname === 'search.library.uq.edu.au') {
              return 'https://support.my.uq.edu.au';
            }
            return 'https://uqcurrent--tst1.custhelp.com'; // we can probably return the live url for all when this is in prod
          });
          // replace a pnx.xxx.xxx[0] pattern ex. pnx.search.recordid[0]
          var pnxProperties = action.action.match(/\{(pnx\..*?)\}/g) || [];
          pnxProperties.forEach(function (p) {
            var valueForP = p.replace(/[{}]/g, '').split('.').reduce(function (o, i) {
              try {
                var h = /(.*)(\[\d\])/.exec(i);
                if (h instanceof Array) {
                  return o[h[1]][h[2].replace(/[^\d]/g, '')];
                }
                return o[i];
              } catch (e) {
                return '';
              }
            }, _this.prmActionCtrl.item);
            action.action = action.action.replace(p, valueForP);
          });
        }
        this.prmActionCtrl.actionListService.onToggle[action.slug] = function () {
          return window.open(action.action, '_blank');
        };
      }
    };
  });

  app.component('prmTopBarBefore', {
    template: '
<uqlibrary-alerts></uqlibrary-alerts>
' +
      '
<uq-minimal-header show-login-button="false"></uq-minimal-header>
'
  });

  /****************************************************************************************************/

  /*In case of CENTRAL_PACKAGE - comment out the below line to replace the other module definition*/

  /*var app = angular.module('centralCustom', ['angularLoad']);*/

  /****************************************************************************************************/

  /*
    * this is on hold until May, when the newspaper-articles exclusion will apparently move out of the url
    * Problems with this 'lock facets' code
    * it cant remove multiple facets on a subsequent load
    * eg
    * 1. search 'library' on homepage, it loads & locks facets newspaper_articles and reviews
    * 2. return to homepage and search 'books' - only one of 'reviews' and 'newspaper_articles' will be removed
    *
    * Incomplete:
    * - I havent quite got the physical items search working properly yet (&facet=tlevel,include,physical_items)
    * ** the immediate prior version handle tlevel, but is too slow - consider how it is handling tlevel & library, though
    * - and this still needs cleaning up
    *
    * sample searches:
    * https://uq-edu-primo-sb.hosted.exlibrisgroup.com/primo-explore/search?query=any,contains,frogs&tab=61uq_all&search_scope=61UQ_All&sortby=rank&vid=61UQ_DEV&facet=rtype,include,books&facets=locked
    * https://uq-edu-primo-sb.hosted.exlibrisgroup.com/primo-explore/search?query=any,contains,frogs&tab=61uq_all&search_scope=61UQ_All&sortby=rank&vid=61UQ_DEV&facet=rtype,include,media&facets=locked
    * https://uq-edu-primo-sb.hosted.exlibrisgroup.com/primo-explore/search?query=any,contains,frogs&tab=61uq_all&search_scope=61UQ_All&sortby=rank&vid=61UQ_DEV&facet=rtype,exclude,newspaper_articles&facet=rtype,exclude,reviews&offset=0&facets=locked
    *
   */

  // lock facets
  // Based on code supplied by Univerisity of Otago eg. https://otago.hosted.exlibrisgroup.com/primo-explore/search?query=any,contains,frogs&tab=default_tab&search_scope=All&vid=DUNEDIN&facet=rtype,exclude,reviews&offset=0&ref=http:%2F%2Fmarvin.otago.ac.nz
  // add '&facets=locked' tag to any referer to a search results page you want this to happen on
  // app.controller('prmExploreMainAfterController', function($scope) {
  //    setTimeout(function(){
  //      var tag = "facets=locked";
  //      if (!(window.location.search.indexOf(tag) > 0 && window.location.search.indexOf("facet=") > 0)) {
  //        return;
  //      }
  //
  //      waitForElementToDisplay('prm-breadcrumbs div div div button prm-icon > md-icon', 1000);
  //
  //      function waitForElementToDisplay(selector, time) {
  //        if (document.querySelector(selector) !== null) {
  //          // in the case where this is a second search via the homepage, we need to unlock previous locked ones
  //          // this means we need to hard code a list to check, because this page doesnt know what other search options are provided on the home page
  //          // if any future queries add different facets, this list will have to be updated
  //          // key = value in url eg books in facet=rtype,exclude,books
  //          // value = value on aria-label element of button to be clicked
  //          var validFacets = {
  //            'reviews': 'Reviews',
  //            'books': 'Books',
  //            'newspaper_articles': 'Newspaper Articles',
  //            'articles': 'Articles',
  //            'media': 'Video & Audio',
  //            'physical_items': 'Physical items'
  //          };
  //
  //          var queries = window.location.search.split('&');
  //          if (queries.length > 1) {
  //            var facetsInUrl = [];
  //            queries.map(function (e) {
  //              // get the facet in the from all the different types
  //              if (0 === e.indexOf("facet=rtype,exclude,")) {
  //                facetsInUrl.push(e.replace("facet=rtype,exclude,", ''));
  //              } else if (0 === e.indexOf("facet=rtype,include,")) {
  //                facetsInUrl.push(e.replace("facet=rtype,include,", ''));
  //              } else if (0 === e.indexOf("facet=tlevel,exclude,")) {
  //                facetsInUrl.push(e.replace("facet=tlevel,exclude,", ''));
  //              } else if (0 === e.indexOf("facet=tlevel,include,")) {
  //                facetsInUrl.push(e.replace("facet=tlevel,include,", ''));
  //              }
  //            });
  //
  //            // do all the settings first because the later facet removal refreshes the page, losing our tag
  //            var facet, ariaLabel, facetSelector;
  //            for (facet in validFacets) {
  //              if (facetsInUrl.indexOf(facet) !== -1) {
  //                // found in the url - lock it
  //                ariaLabel = 'Make this filter persistent throughout the session ' + validFacets[facet];
  //                facetSelector = document.querySelector('[aria-label="' + ariaLabel + '"]');
  //                if (facetSelector !== null) {
  //                  angular.element(facetSelector).triggerHandler('click');
  //                }
  //              }
  //            }
  //
  //            var thisFacet, ariaLabelLock, facetSelectorLock;
  //            for (facet in validFacets) {
  //              if (facetsInUrl.indexOf(facet) !== -1) {
  //                // skip any that are for this page
  //              } else {
  //                // remove a facet if it was locked from an earlier search
  //                thisFacet = validFacets[facet];
  //                ariaLabel = 'Remove Content type ' + thisFacet;
  //                facetSelector = document.querySelector('[aria-label="' + ariaLabel + '"]'); // the x (remove) button exists to click
  //                ariaLabelLock = 'Cancel persistence ' + thisFacet;
  //                facetSelectorLock = document.querySelector('[aria-label="' + ariaLabelLock + '"]'); // the 'locked' button exists - this is one we should remove
  //                if (facetSelector !== null && facetSelectorLock !== null) {
  //                  angular.element(facetSelector).triggerHandler('click');
  //                  //once this is clicked the page will refresh and wont have our tag on the end :(
  //                  // so only one is ever done :(
  //                }
  //              }
  //            }
  //
  //            return;
  //          }
  //          else {
  //            setTimeout(function () {
  //              waitForElementToDisplay(selector, time);
  //            }, time);
  //          }
  //        }
  //      }
  //    }, 2500);
  //  });
  //
  //  app.component('prmExploreMainAfter', {
  //    bindings: {
  //      parentCtrl: '<'
  //    },
  //    controller: 'prmExploreMainAfterController'
  //  });
  // End lock facets

  app.controller('prmOpenJournalInFullController', [
    function () {
      var vm = this;
      vm.$onInit = function () {
        var resourceType = vm.parentCtrl.result.pnx.display.type[0] || '';
        if (resourceType === 'journal') {
          vm.parentCtrl.isDirectLink = function () { return false; };
        }
      };
    }
  ]);

  app.component('prmOpenJournalInFull', {
    bindings: { parentCtrl: '<' },
    controller: 'prmOpenJournalInFullController'
  });

  app.component('prmSearchResultAvailabilityLineAfter', {
    bindings: { parentCtrl: '<' },
    template: '<prm-open-journal-in-full parent-ctrl="$ctrl.parentCtrl"></prm-open-journal-in-full>'
  });

  function insertScript(url) {
    var script = document.querySelector("script[src*='" + url + "']");
    if (!script) {
      var heads = document.getElementsByTagName("head");
      if (heads && heads.length) {
        var head = heads[0];
        if (head) {
          script = document.createElement('script');
          script.setAttribute('src', url);
          script.setAttribute('type', 'text/javascript');
          head.appendChild(script);
        }
      }
    }
  }

  function insertLink(link) {
    var linkTag = document.querySelector("link[href*='" + link.href + "']");
    if (!linkTag) {
      var heads = document.getElementsByTagName("head");
      if (heads && heads.length) {
        var head = heads[0];
        if (head) {
          linkTag = document.createElement('link');
          linkTag.setAttribute('href', link.href);
          linkTag.setAttribute('rel', link.rel);
          head.appendChild(linkTag);
        }
      }
    }
  }

  // this script should only be called on views that have UQ header showing
  var branchName = '/'; // default. Use for prod
  if (window.location.hostname === 'search.library.uq.edu.au') {
    if (/vid=61UQ_DEV/.test(window.location.href)) {
      branchName = '/primo-prod-dev/';
    }
  } else {
    if (/vid=61UQ_DEV/.test(window.location.href)) {
      branchName = '/primo-sand-box-dev/';
    } else if (/vid=61UQ/.test(window.location.href)) {
      branchName = '/primo-sand-box/';
    }
  }

  var links = [
    { rel: 'import', href: '//assets.library.uq.edu.au' + branchName + 'reusable-components/elements.vulcanized.html' },
    { rel: 'stylesheet', href: '//assets.library.uq.edu.au' + branchName + 'reusable-components/primo2/custom-styles.css' }
  ];
  insertLink(links[0]);
  insertLink(links[1]);

  var scripts = [
    '//assets.library.uq.edu.au' + branchName + 'reusable-components/webcomponentsjs/webcomponents-lite.min.js',
    '//assets.library.uq.edu.au' + branchName + 'reusable-components/resources/preloader.js',
    '//assets.library.uq.edu.au' + branchName + 'reusable-components/primo2/load.js',
  ];
  insertScript(scripts[0]);
  insertScript(scripts[1]);
  insertScript(scripts[2]);
})();
<|endoftext|>


<commit_before>/* Libre.fm -- a free network service for sharing your music listening habits

   Copyright (C) 2009 Libre.fm Project

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU Affero General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Affero General Public License for more details.

   You should have received a copy of the GNU Affero General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

function unrecognised ( msg )
{
	$('#location_uri')[0].value = '';
	$('#location_uri_label').removeClass('ok');
	$('#location_uri_label').addClass('no');
	$('#location_uri_label').text( msg );
	return 0;
}

function LocationCheck ()
{
	if ( !$('#location').val() )
	{
		return unrecognised("You must enter a location.");
	}

	if ($('#loading')[0])
	{
		$('#loading').show();
	}
	else
	{
		var loading = document.createElement('IMG');
		loading.id = 'loading';
		document.body.appendChild(loading);
		loading.src = '/i/loading.gif';
		loading.style.height = '32px';
		loading.style.width = '32px';
		loading.style.position = 'absolute';
		loading.style.top = '50%';
		loading.style.left = '50%';
		loading.style.marginTop = '-16px';
		loading.style.marginLeft = '-16px';
	}

	$.getJSON("/location-ws.php",
		{ 'q' : $('#location').val() },
		function (data, status)
		{
			$('#loading').hide();

			if (! data.geonames[0])
			{
				return unrecognised("This location was unrecognisable.");
			}

			var list;

			if ($('#chooser_list')[0])
			{
				$('#chooser_list').empty();
				$('#chooser_list').show();
				list = $('#chooser_list')[0];
			}
			else
			{
				list = document.createElement('UL');
				list.id = 'chooser_list';
				$('#chooser')[0].appendChild(list);
			}

			for (var g in data.geonames)
			{
				var G = data.geonames[g];

				var fullName = G.name;
				if (G.adminName3) fullName += ", " + G.adminName3;
				if (G.adminName2) fullName += ", " + G.adminName2;
				if (G.adminName1) fullName += ", " + G.adminName1;
				if (G.countryName) fullName += ", " + G.countryName;

				var coords = G.lat.toFixed(2) + ';' + G.lng.toFixed(2);

				var shortName = G.name;
				if (G.countryCode == 'US')
					shortName += ", " + G.adminCode1 + ", USA";
				else
					shortName += ", " + G.countryCode;

				var item = document.createElement('LI');
				var label1 = document.createElement('B');
				label1.appendChild(document.createTextNode(fullName));
				item.appendChild(label1);
				item.appendChild(document.createTextNode(' '));
				var label2 = document.createElement('SMALL');
				label2.appendChild(document.createTextNode('['+coords+']'));
				item.appendChild(label2);

				item.setAttribute('data-geoname', 'http://sws.geonames.org/' + G.geonameId + '/');
				item.setAttribute('data-geoname-name', shortName);
				item.setAttribute('data-geoname-coords', coords);

				item.onclick = function (e) {
					if (!e) var e = window.event;
					var tg = (window.event) ? e.srcElement : e.target;
					var geoname = $(tg).closest('li').attr('data-geoname');
					$('#location_uri')[0].value = geoname;
					$('#chooser_list').empty();
					$('#chooser_list').hide();
					$('#location_uri_label').text(
						$(tg).closest('li').attr('data-geoname-name')
						+ ' ['	+ $(tg).closest('li').attr('data-geoname-coords') + ']'  );
					$('#location_uri_label').addClass('ok');
					$('#location_uri_label').removeClass('no');
				}
				$(item).hover(function ()
					{
						$(this).addClass('hover');
					},
					function ()
					{
						$(this).removeClass('hover');
					}
					);
				list.appendChild(item);
			}
		});
}
<commit_msg>Add timeouts.<commit_after>/* Libre.fm -- a free network service for sharing your music listening habits

   Copyright (C) 2009 Libre.fm Project

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU Affero General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Affero General Public License for more details.

   You should have received a copy of the GNU Affero General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

function unrecognised ( msg )
{
	$('#location_uri')[0].value = '';
	$('#location_uri_label').removeClass('ok');
	$('#location_uri_label').addClass('no');
	$('#location_uri_label').text( msg );
	return 0;
}

function LocationCheck ()
{
	if ( !$('#location').val() )
	{
		return unrecognised("You must enter a location.");
	}

	ajaxLoading(1);

	var ajaxSuccess = function (data, status)
		{
			ajaxLoading(0);

			if (! data.geonames[0])
			{
				return unrecognised("This location was unrecognisable.");
			}

			var list;

			if ($('#chooser_list')[0])
			{
				$('#chooser_list').empty();
				$('#chooser_list').show();
				list = $('#chooser_list')[0];
			}
			else
			{
				list = document.createElement('UL');
				list.id = 'chooser_list';
				$('#chooser')[0].appendChild(list);
			}

			for (var g in data.geonames)
			{
				var G = data.geonames[g];

				var fullName = G.name;
				if (G.adminName3) fullName += ", " + G.adminName3;
				if (G.adminName2) fullName += ", " + G.adminName2;
				if (G.adminName1) fullName += ", " + G.adminName1;
				if (G.countryName) fullName += ", " + G.countryName;

				var coords = G.lat.toFixed(2) + ';' + G.lng.toFixed(2);

				var shortName = G.name;
				if (G.countryCode == 'US')
					shortName += ", " + G.adminCode1 + ", USA";
				else
					shortName += ", " + G.countryCode;

				var item = document.createElement('LI');
				var label1 = document.createElement('B');
				label1.appendChild(document.createTextNode(fullName));
				item.appendChild(label1);
				item.appendChild(document.createTextNode(' '));
				var label2 = document.createElement('SMALL');
				label2.appendChild(document.createTextNode('['+coords+']'));
				item.appendChild(label2);

				item.setAttribute('data-geoname', 'http://sws.geonames.org/' + G.geonameId + '/');
				item.setAttribute('data-geoname-name', shortName);
				item.setAttribute('data-geoname-coords', coords);

				item.onclick = function (e) {
					if (!e) var e = window.event;
					var tg = (window.event) ? e.srcElement : e.target;
					var geoname = $(tg).closest('li').attr('data-geoname');
					$('#location_uri')[0].value = geoname;
					$('#chooser_list').empty();
					$('#chooser_list').hide();
					$('#location_uri_label').text(
						$(tg).closest('li').attr('data-geoname-name')
						+ ' ['	+ $(tg).closest('li').attr('data-geoname-coords') + ']'  );
					$('#location_uri_label').addClass('ok');
					$('#location_uri_label').removeClass('no');
				}
				$(item).hover(function ()
					{
						$(this).addClass('hover');
					},
					function ()
					{
						$(this).removeClass('hover');
					}
					);
				list.appendChild(item);
			}
		};

	var ajaxError = function (XMLHttpRequest, textStatus, errorThrown)
		{
			ajaxLoading(0);
			return unrecognised("Request error: " + textStatus);
		};

	$.ajax({
			'type' : 'GET' ,
			'url' : "/location-ws.php" ,
			'data' : { 'q' : $('#location').val() },
			'dataType' : 'json' ,
			'timeout' : 30000 ,
			'success' : ajaxSuccess ,
			'error' : ajaxError
		});
}

function ajaxLoading (l)
{
	if (l==1)
	{
		if ($('#loading')[0])
		{
			$('#loading').show();
		}
		else
		{
			var loading = document.createElement('IMG');
			loading.id = 'loading';
			document.body.appendChild(loading);
			loading.src = '/i/loading.gif';
			loading.style.height = '32px';
			loading.style.width = '32px';
			loading.style.position = 'absolute';
			loading.style.top = '50%';
			loading.style.left = '50%';
			loading.style.marginTop = '-16px';
			loading.style.marginLeft = '-16px';
		}
	}
	else
	{
		$('#loading').hide();
	}
}
<|endoftext|>


<commit_before>/*global angular, console, _, moment, $ */

var eurosportApp = angular.module('eurosportApp',[]);

eurosportApp.controller('reportController', ['$scope', function($scope) {

    'use strict';

    String.prototype.reverse=function(){return this.split("").reverse().join("");};

    var reader = new FileReader();

    var eus1EventColor = '#428bca';
    var eus2EventColor = '#d9534f';
    var eus2NEEventColor = '#5bc0de';
    var eus1Name = 'INTER';
    var eus2Name = 'EUROSPORT 2';
    var eus2NEName = 'EUROSPORT 2 NORTH-EAST';

    $scope.supported = angular.isDefined(window.FileReader);
    $scope.selectedFile;
    $scope.textResult;
    $scope.jsonData;
    $scope.calendarEvents = [];
    $scope.parseComplete = false;
    $scope.logData = [];
    $scope.printView = false;

    $scope.progressStyle = {
        width : $scope.progressPercentage +'%'
    };

    $scope.togglePrintView = function () {
        $scope.printView = !$scope.printView;
    }

    $scope.displayDate = function (date) {
       return moment(date).format("YYYY/MM/DD HH:mm");
    };

    function csvToJSON (csvText) {
        $scope.logData = [];

        var resultObject = [];

        var lines = csvText.split(/[\r\n]+/g);      // tolerate both Windows and Unix linebreaks

        var max = lines.length;

        if( max <= 1 ) {
            logMessage("A fájl valószínűleg hibás, mert túl kevés sorból áll.", 2);
            return;
        }

        var current = 0;
        var fatalError = false;
        lines.forEach(function(line) {
            if (fatalError) return;
            current++;
            var lineDatas = line.split("\t");
            if (lineDatas.length > 10){
                var tempProgramme = {
                    commentatorName : lineDatas[0],
                    date : lineDatas[1],
                    originalStartTime : lineDatas[2].trim().substring(0,5),
                    originalEndTime : lineDatas[3].trim().substring(0,5),
                    programme : lineDatas[4],
                    type : lineDatas[5],
                    channel : lineDatas[6],
                    id : lineDatas[7],
                    commentatorIds : lineDatas[8],
                    realStartTime : lineDatas[9],
                    realEndTime : lineDatas[10]
                };

                computeCancelled(tempProgramme);
                computeRealTime(tempProgramme);
                computeBaseDate(tempProgramme);
                computeCalendarDates(tempProgramme);

                // look for identical object before pushing
                var possibleIdentical = _.find(resultObject, function(prog){
                    return prog.id == tempProgramme.id &&
                           prog.computedStartTime == tempProgramme.computedStartTime &&
                           prog.computedEndTime == tempProgramme.computedEndTime;
                });

                if (!possibleIdentical) {
                    resultObject.push(tempProgramme);
                } else {
                    logMessage("A " + tempProgramme.id + " számú műsor kétszer szerepelt azonos időpontban.", 1);
                }
            } else {
                if (line !== "") {
                    logMessage("A fájl nem tartalmaz elég adatot.", 2);
                    fatalError = true;
                }
            }
            setPercentage(current, max);
        });

        $scope.parseComplete = true;
        makeFullCalendarEvents(resultObject);
        $scope.$broadcast('initCalendar');
        return resultObject;
    }

    $scope.returnEventColor = function (programme) {
        if (programme.channel == eus1Name) {
            return eus1EventColor;
        }
        if (programme.channel == eus2Name) {
            return eus2EventColor;
        }
        if (programme.channel == eus2NEName) {
            return eus2NEEventColor;
        }
    };

    $scope.returnResourceId = function (programme) {
        if (programme.channel == eus1Name) {
            return 1;
        }
        if (programme.channel == eus2Name) {
            return 2;
        }
        if (programme.channel == eus2NEName) {
            return 3;
        }
    };

    function makeFullCalendarEvents(array) {
        var fullCalendarEvents = [];
        array.forEach(function (programme) {
            if(!programme.cancelled)
                fullCalendarEvents.push( {
                    title  : programme.id,
                    start  : moment(programme.calendarStartDate).format("YYYY-MM-DD HH:mm"),
                    end    : moment(programme.calendarEndDate).format("YYYY-MM-DD HH:mm"),
                    allDay : false,
                    color  : $scope.returnEventColor(programme),
                    resourceId: $scope.returnResourceId(programme)
                });
        });

        $scope.calendarEvents = fullCalendarEvents;
    }

    function computeCalendarDates (programmeObject) {
        var startTimeDatas = programmeObject.computedStartTime.split(":");
        var m = moment(programmeObject.date);

        if(startTimeDatas[0] >= 0 && startTimeDatas[0] < 3) {
            logMessage("A " + programmeObject.id + " számú műsor másnap kezdődik (?)", 2);
            m.add('days', 1);
        } else if(startTimeDatas[0] >= 24) {
            logMessage("A " + programmeObject.id + " számú műsor másnap kezdődik.", 1);
            startTimeDatas[0] = startTimeDatas[0] - 24; // start date will be the next date
            m.add('days', 1);
        }

        m.set('hour', startTimeDatas[0]);
        m.set('minute', startTimeDatas[1]);

        programmeObject.calendarStartDate = m.toDate();

        var endTimeDatas = programmeObject.computedEndTime.split(":");
        m = moment(programmeObject.date);

        if(endTimeDatas[0] >= 0 && endTimeDatas[0] < 3) {
            logMessage("A " + programmeObject.id + " számú műsor másnap végződik (?)", 2);
            m.add('days', 1);
        } else if (endTimeDatas[0] >= 24) {
            logMessage("A " + programmeObject.id + " számú műsor másnap végződik.", 1);
            endTimeDatas[0] = endTimeDatas[0] - 24; // end date will be the next date
            m.add('days', 1);
        }

        m.set('hour', endTimeDatas[0]);
        m.set('minute', endTimeDatas[1]);

        programmeObject.calendarEndDate = m.toDate();
    }

    function setPercentage (current, max) {
        $scope.progressStyle.width = (current/max * 100) + '%';
    }

    function computeBaseDate (programmeObject) {
        // a date looks like this: Sun 16/03/2014
        var extractedDate = programmeObject.date.reverse().substring(0,10).reverse();
        var day = extractedDate.substring(0,2);
        var month = extractedDate.substring(3,5);
        var year = extractedDate.substring(6,10);

        programmeObject.date = new Date(year, month - 1, day);

    }

    function computeRealTime (programmeObject) {
        // start time
        programmeObject.computedStartTime = programmeObject.realStartTime.length > 1 ? programmeObject.realStartTime : programmeObject.originalStartTime;

        // end time
        programmeObject.computedEndTime = programmeObject.realEndTime.length > 1 ? programmeObject.realEndTime : programmeObject.originalEndTime;
    }

    function computeCancelled (programmeObject) {
        programmeObject.cancelled = programmeObject.id.length < 1 ? true : false;
        if (programmeObject.cancelled)
            logMessage("A " + programmeObject.programme + " elmaradt.", 1);
    }

    function logMessage (message, level) {
        $scope.logData.push({ message : message, level : level});
    }

    $scope.fileSelected = function (file) {

        if(file.length == 1)
        {

            // check extension
            if(file[0].name.indexOf(".txt") > 0){
                reader.readAsText(file[0]);

                reader.onload = function() {
                    $scope.calendarEvents = [];
                    $scope.parseComplete = false;
                    $scope.logData = [];
                    $scope.textResult = reader.result;
                    $scope.jsonData = csvToJSON(reader.result);
                    $scope.$digest();
                };
            } else {
                $scope.logData = [];
                logMessage("Nem megfelelő formátum.", 2);
                $scope.calendarEvents = [];
                $scope.parseComplete = false;
                $scope.jsonData = [];
                $scope.$digest();
            }

        }

    };
}]);

eurosportApp.directive('fullCalendar', function(){

    'use strict';

    return {
        scope: {
            events : "="
        },
        restrict: 'EA',
        link: function($scope, iElm) {

            $('#calendar-prev-button').click(function() {
                $('#calendar').fullCalendar('prev');
                updateDate();
            });
            $('#calendar-next-button').click(function() {
                $('#calendar').fullCalendar('next');
                updateDate();
            });

            function updateDate () {
                $('#calendar-date').text(moment($('#calendar').fullCalendar('getDate')).format("YYYY/MM/DD"));
            }

            $scope.$watch('events', function (newVal) {
                if(newVal.length !== 0){
                    $(iElm).fullCalendar({
                        allDaySlot : false,
                        header: false,
                        theme: true,
                        defaultView : "resourceDay",
                        events: $scope.events,
                        slotEventOverlap : false,resources: [
                            { name: 'Eurosport Inter', id: 1 },
                            { name: 'Eurosport 2', id: 2 },
                            { name: 'Eurosport 2 NE', id: 3 },
                        ],
                        timeFormat: 'HH:mm',
                        axisFormat: 'HH:mm',
                        buttonText: {
                            prev: 'előző nap',
                            next: 'következő nap',
                            today: 'mai nap',
                        }
                    });

                    $(iElm).fullCalendar('gotoDate', newVal[0].start);
                    updateDate();
                }
            });

        }
    };
});

eurosportApp.directive('uploadButton', function(){

    'use strict';

    return {
        restrict: 'A',
        link: function($scope, $element) {
            var fileElem = document.getElementById("fileElem");

            $element.bind('click', function (e) {
                if (fileElem) {
                    fileElem.click();
                }
                e.preventDefault();
            });

        }
    };
});<commit_msg>cancelled upgrade<commit_after>/*global angular, console, _, moment, $ */

var eurosportApp = angular.module('eurosportApp',[]);

eurosportApp.controller('reportController', ['$scope', function($scope) {

    'use strict';

    String.prototype.reverse=function(){return this.split("").reverse().join("");};

    var reader = new FileReader();

    var eus1EventColor = '#428bca';
    var eus2EventColor = '#d9534f';
    var eus2NEEventColor = '#5bc0de';
    var eus1Name = 'INTER';
    var eus2Name = 'EUROSPORT 2';
    var eus2NEName = 'EUROSPORT 2 NORTH-EAST';

    $scope.supported = angular.isDefined(window.FileReader);
    $scope.selectedFile;
    $scope.textResult;
    $scope.jsonData;
    $scope.calendarEvents = [];
    $scope.parseComplete = false;
    $scope.logData = [];
    $scope.printView = false;

    $scope.progressStyle = {
        width : $scope.progressPercentage +'%'
    };

    $scope.togglePrintView = function () {
        $scope.printView = !$scope.printView;
    }

    $scope.displayDate = function (date) {
       return moment(date).format("YYYY/MM/DD HH:mm");
    };

    function csvToJSON (csvText) {
        $scope.logData = [];

        var resultObject = [];

        var lines = csvText.split(/[\r\n]+/g);      // tolerate both Windows and Unix linebreaks

        var max = lines.length;

        if( max <= 1 ) {
            logMessage("A fájl valószínűleg hibás, mert túl kevés sorból áll.", 2);
            return;
        }

        var current = 0;
        var fatalError = false;
        lines.forEach(function(line) {
            if (fatalError) return;
            current++;
            var lineDatas = line.split("\t");
            if (lineDatas.length > 10){
                var tempProgramme = {
                    commentatorName : lineDatas[0],
                    date : lineDatas[1],
                    originalStartTime : lineDatas[2].trim().substring(0,5),
                    originalEndTime : lineDatas[3].trim().substring(0,5),
                    programme : lineDatas[4],
                    type : lineDatas[5],
                    channel : lineDatas[6],
                    id : lineDatas[7],
                    commentatorIds : lineDatas[8],
                    realStartTime : lineDatas[9],
                    realEndTime : lineDatas[10]
                };

                computeCancelled(tempProgramme);
                computeRealTime(tempProgramme);
                computeBaseDate(tempProgramme);
                computeCalendarDates(tempProgramme);

                // look for identical object before pushing
                var possibleIdentical = _.find(resultObject, function(prog){
                    return prog.id == tempProgramme.id &&
                           prog.computedStartTime == tempProgramme.computedStartTime &&
                           prog.computedEndTime == tempProgramme.computedEndTime;
                });

                if (!possibleIdentical) {
                    resultObject.push(tempProgramme);
                } else {
                    logMessage("A " + tempProgramme.id + " számú műsor kétszer szerepelt azonos időpontban.", 1);
                }
            } else {
                if (line !== "") {
                    logMessage("A fájl nem tartalmaz elég adatot.", 2);
                    fatalError = true;
                }
            }
            setPercentage(current, max);
        });

        $scope.parseComplete = true;
        makeFullCalendarEvents(resultObject);
        $scope.$broadcast('initCalendar');
        return resultObject;
    }

    $scope.returnEventColor = function (programme) {
        if (programme.channel == eus1Name) {
            return eus1EventColor;
        }
        if (programme.channel == eus2Name) {
            return eus2EventColor;
        }
        if (programme.channel == eus2NEName) {
            return eus2NEEventColor;
        }
    };

    $scope.returnResourceId = function (programme) {
        if (programme.channel == eus1Name) {
            return 1;
        }
        if (programme.channel == eus2Name) {
            return 2;
        }
        if (programme.channel == eus2NEName) {
            return 3;
        }
    };

    function makeFullCalendarEvents(array) {
        var fullCalendarEvents = [];
        array.forEach(function (programme) {
            if(!programme.cancelled)
                fullCalendarEvents.push( {
                    title  : programme.id,
                    start  : moment(programme.calendarStartDate).format("YYYY-MM-DD HH:mm"),
                    end    : moment(programme.calendarEndDate).format("YYYY-MM-DD HH:mm"),
                    allDay : false,
                    color  : $scope.returnEventColor(programme),
                    resourceId: $scope.returnResourceId(programme)
                });
        });

        $scope.calendarEvents = fullCalendarEvents;
    }

    function computeCalendarDates (programmeObject) {
        var startTimeDatas = programmeObject.computedStartTime.split(":");
        var m = moment(programmeObject.date);

        if(startTimeDatas[0] >= 0 && startTimeDatas[0] < 3) {
            logMessage("A " + programmeObject.id + " számú műsor másnap kezdődik (?)", 2);
            m.add('days', 1);
        } else if(startTimeDatas[0] >= 24) {
            logMessage("A " + programmeObject.id + " számú műsor másnap kezdődik.", 1);
            startTimeDatas[0] = startTimeDatas[0] - 24; // start date will be the next date
            m.add('days', 1);
        }

        m.set('hour', startTimeDatas[0]);
        m.set('minute', startTimeDatas[1]);

        programmeObject.calendarStartDate = m.toDate();

        var endTimeDatas = programmeObject.computedEndTime.split(":");
        m = moment(programmeObject.date);

        if(endTimeDatas[0] >= 0 && endTimeDatas[0] < 3) {
            logMessage("A " + programmeObject.id + " számú műsor másnap végződik (?)", 2);
            m.add('days', 1);
        } else if (endTimeDatas[0] >= 24) {
            logMessage("A " + programmeObject.id + " számú műsor másnap végződik.", 1);
            endTimeDatas[0] = endTimeDatas[0] - 24; // end date will be the next date
            m.add('days', 1);
        }

        m.set('hour', endTimeDatas[0]);
        m.set('minute', endTimeDatas[1]);

        programmeObject.calendarEndDate = m.toDate();
    }

    function setPercentage (current, max) {
        $scope.progressStyle.width = (current/max * 100) + '%';
    }

    function computeBaseDate (programmeObject) {
        // a date looks like this: Sun 16/03/2014
        var extractedDate = programmeObject.date.reverse().substring(0,10).reverse();
        var day = extractedDate.substring(0,2);
        var month = extractedDate.substring(3,5);
        var year = extractedDate.substring(6,10);

        programmeObject.date = new Date(year, month - 1, day);

    }

    function computeRealTime (programmeObject) {
        // start time
        programmeObject.computedStartTime = programmeObject.realStartTime.length > 1 ? programmeObject.realStartTime : programmeObject.originalStartTime;

        // end time
        programmeObject.computedEndTime = programmeObject.realEndTime.length > 1 ? programmeObject.realEndTime : programmeObject.originalEndTime;
    }

    function computeCancelled (programmeObject) {
        programmeObject.cancelled = programmeObject.id.length < 1 ? true : false;
        programmeObject.cancelled = _.isNumber(programmeObject.id) ? false : true;
        if (programmeObject.cancelled)
            logMessage("A " + programmeObject.programme + " elmaradt.", 1);
    }

    function logMessage (message, level) {
        $scope.logData.push({ message : message, level : level});
    }

    $scope.fileSelected = function (file) {

        if(file.length == 1)
        {

            // check extension
            if(file[0].name.indexOf(".txt") > 0){
                reader.readAsText(file[0]);

                reader.onload = function() {
                    $scope.calendarEvents = [];
                    $scope.parseComplete = false;
                    $scope.logData = [];
                    $scope.textResult = reader.result;
                    $scope.jsonData = csvToJSON(reader.result);
                    $scope.$digest();
                };
            } else {
                $scope.logData = [];
                logMessage("Nem megfelelő formátum.", 2);
                $scope.calendarEvents = [];
                $scope.parseComplete = false;
                $scope.jsonData = [];
                $scope.$digest();
            }

        }

    };
}]);

eurosportApp.directive('fullCalendar', function(){

    'use strict';

    return {
        scope: {
            events : "="
        },
        restrict: 'EA',
        link: function($scope, iElm) {

            $('#calendar-prev-button').click(function() {
                $('#calendar').fullCalendar('prev');
                updateDate();
            });
            $('#calendar-next-button').click(function() {
                $('#calendar').fullCalendar('next');
                updateDate();
            });

            function updateDate () {
                $('#calendar-date').text(moment($('#calendar').fullCalendar('getDate')).format("YYYY/MM/DD"));
            }

            $scope.$watch('events', function (newVal) {
                if(newVal.length !== 0){
                    $(iElm).fullCalendar({
                        allDaySlot : false,
                        header: false,
                        theme: true,
                        defaultView : "resourceDay",
                        events: $scope.events,
                        slotEventOverlap : false,resources: [
                            { name: 'Eurosport Inter', id: 1 },
                            { name: 'Eurosport 2', id: 2 },
                            { name: 'Eurosport 2 NE', id: 3 },
                        ],
                        timeFormat: 'HH:mm',
                        axisFormat: 'HH:mm',
                        buttonText: {
                            prev: 'előző nap',
                            next: 'következő nap',
                            today: 'mai nap',
                        }
                    });

                    $(iElm).fullCalendar('gotoDate', newVal[0].start);
                    updateDate();
                }
            });

        }
    };
});

eurosportApp.directive('uploadButton', function(){

    'use strict';

    return {
        restrict: 'A',
        link: function($scope, $element) {
            var fileElem = document.getElementById("fileElem");

            $element.bind('click', function (e) {
                if (fileElem) {
                    fileElem.click();
                }
                e.preventDefault();
            });

        }
    };
});<|endoftext|>


<commit_before>// ==========================================================================
//                              DG.Drag
//
//  Author:   William Finzer
//
//  Copyright (c) 2014 by The Concord Consortium, Inc. All rights reserved.
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
// ==========================================================================

/*
 * We override SC.Drag for the single purpose of dealing with overlapping drop targets
 * in the graph. Different browsers seem to produce different results with the SC.Drag
 * implementation. Namely, for one browser, the AxisMultiTarget will allow a drop while
 * for another browser it won't.
 */

/** @class  Override the private method _findDropTarget

*/
DG.Drag = SC.Drag.extend({

  _findDropTarget: function( iEvent) {
    var tTargets = this._dropTargets(),
        tLoc = { x: iEvent.pageX, y: iEvent.pageY },
        tResult = null;
    tTargets.forEach( function( iTarget) {
      if( (iTarget.constructor === DG.AxisMultiTarget) || (iTarget.get('orientation') === 'vertical2')) {
        var tFrame = iTarget.parentView.convertFrameToView( iTarget.get('frame'), null);
        if( SC.pointInRect( tLoc, tFrame)) {
          tResult = iTarget;
        }
      }
    });
    if( !SC.none( tResult))
      return tResult;
    else
      return sc_super();
  },

  /** @private Called instead of _destroyGhostView if slideBack is YES.
   *  Overridden to get a better destination for the slideBack than SC provides
   * */
  _slideGhostViewBack: function () {
    if( !this.origin)
        sc_super();
    else if (this.ghostView) {
      var slidebackLayout = { top: this.origin.y, left: this.origin.x };

      // Animate the ghost view back to its original position; destroy after.
      this.ghostView.animate(slidebackLayout, 0.5, this, function () {
        this.invokeNext(function() {
          // notify the source that slideback has completed
          var source = this.get('source');
          if (this.get('slideBack') && source && source.dragSlideBackDidEnd)
            source.dragSlideBackDidEnd(this);
          this._endDrag();
        });
      });

    }
    else {
      this._endDrag();
    }
  }
});
<commit_msg>[Fixes #115786297] In SproutCore 1.9 Drag::StartDrag would pass 'drag Started' to _all_ drop targets. This was changed in 1.11 so that drop targets not visible are skipped. We reinstate by overriding StartDrag to provide previous behavior.<commit_after>// ==========================================================================
//                              DG.Drag
//
//  Author:   William Finzer
//
//  Copyright (c) 2014 by The Concord Consortium, Inc. All rights reserved.
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
// ==========================================================================

/*
 * We override SC.Drag for the single purpose of dealing with overlapping drop targets
 * in the graph. Different browsers seem to produce different results with the SC.Drag
 * implementation. Namely, for one browser, the AxisMultiTarget will allow a drop while
 * for another browser it won't.
 */

/** @class  Override the private method _findDropTarget

*/
DG.Drag = SC.Drag.extend({

  /** @private
   This will actually start the drag process. Called by SC.Drag.start().
   [Finzer - Concord Consortium] We override to get a previous behavior with regard dragStarted for views
        that are not visible.
   */
  startDrag: function () {
    if (this.get('sourceIsDraggable')) {
      // create the ghost view
      this._createGhostView();
    }

    var evt = this.event;

    // compute the ghost offset from the original start location

    var loc = { x: evt.pageX, y: evt.pageY };
    this.set('location', loc);

    if (this.get('sourceIsDraggable')) {
      var dv = this._getDragView();
      var pv = dv.get('parentView');

      // convert to global coordinates
      var origin = pv ? pv.convertFrameToView(dv.get('frame'), null) : dv.get('frame');

      if (this.get('ghost')) {
        // Hide the dragView
        this._dragViewWasVisible = dv.get('isVisible');
        dv.set('isVisible', NO);
      }

      if (this.ghostActsLikeCursor) this.ghostOffset = { x: 14, y: 14 };
      else this.ghostOffset = { x: (loc.x - origin.x), y: (loc.y - origin.y) };

      // position the ghost view
      if (!this._ghostViewHidden) this._positionGhostView(evt);

      if (evt.makeTouchResponder) {
        // Should use invokeLater if I can figure it out
        var self = this;
        SC.Timer.schedule({
          target: evt,
          action: function () {
            if (!evt.hasEnded) evt.makeTouchResponder(self, YES);
          },
          interval: 1
        });
      }
      else {
        // notify root responder that a drag is in process
        this.ghostView.rootResponder.dragDidStart(this, evt);
      }
    }

    var source = this.source;
    if (source && source.dragDidBegin) source.dragDidBegin(this, loc);

    // let all drop targets know that a drag has started
    var ary = this._dropTargets();

    for (var idx = 0, len = ary.length; idx < len; idx++) {
      var target = ary[idx];
      // This change to ignore views that are not visible was introduced post SC 1.9.
      // We rely on get dragStarted in the various axis views and there is no easy alternative.
      // If the target is not visible, it is not valid.
      //if (!target.get('isVisibleInWindow')) continue;

      target.tryToPerform('dragStarted', this, evt);
    }
  },

  _findDropTarget: function( iEvent) {
    var tTargets = this._dropTargets(),
        tLoc = { x: iEvent.pageX, y: iEvent.pageY },
        tResult = null;
    tTargets.forEach( function( iTarget) {
      if( (iTarget.constructor === DG.AxisMultiTarget) || (iTarget.get('orientation') === 'vertical2')) {
        var tFrame = iTarget.parentView.convertFrameToView( iTarget.get('frame'), null);
        if( SC.pointInRect( tLoc, tFrame)) {
          tResult = iTarget;
        }
      }
    });
    if( !SC.none( tResult))
      return tResult;
    else
      return sc_super();
  },

  /** @private Called instead of _destroyGhostView if slideBack is YES.
   *  Overridden to get a better destination for the slideBack than SC provides
   * */
  _slideGhostViewBack: function () {
    if( !this.origin)
        sc_super();
    else if (this.ghostView) {
      var slidebackLayout = { top: this.origin.y, left: this.origin.x };

      // Animate the ghost view back to its original position; destroy after.
      this.ghostView.animate(slidebackLayout, 0.5, this, function () {
        this.invokeNext(function() {
          // notify the source that slideback has completed
          var source = this.get('source');
          if (this.get('slideBack') && source && source.dragSlideBackDidEnd)
            source.dragSlideBackDidEnd(this);
          this._endDrag();
        });
      });

    }
    else {
      this._endDrag();
    }
  }
});
<|endoftext|>


<commit_before>frappe.ui.FilterGroup = class {
	constructor(opts) {
		$.extend(this, opts);
		this.wrapper = this.parent;
		this.filters = [];
		this.make();
		window.fltr = this;
	}

	make() {
		this.wrapper.append(this.get_container_template());
		this.set_events();
	}

	toggle_clear_filter() {
		let clear_filter_button = this.wrapper.find('.clear-filters');

		if (this.filters.length == 0) {
			clear_filter_button.hide();
		} else {
			clear_filter_button.show();
		}
	}
	set_events() {
		this.wrapper.find('.add-filter').on('click', () => {
			this.add_filter(this.doctype, 'name')
				.then(this.toggle_clear_filter());

		});
		this.wrapper.find('.clear-filters').on('click', () => {
			this.clear_filters();
		});
	}

	add_filters(filters) {
		let promises = [];

		for (const filter of filters) {
			promises.push(() => this.add_filter(...filter));
		}

		promises.push(() => this.toggle_clear_filter());

		return frappe.run_serially(promises);
	}

	add_filter(doctype, fieldname, condition, value, hidden) {
		if (!fieldname) return Promise.resolve();
		// adds a new filter, returns true if filter has been added

		// {}: Add in page filter by fieldname if exists ('=' => 'like')

		if(!this.validate_args(doctype, fieldname)) return false;
		const is_new_filter = arguments.length < 2;
		if (is_new_filter && this.wrapper.find(".new-filter:visible").length) {
			// only allow 1 new filter at a time!
			return Promise.resolve();
		} else {
			let args = [doctype, fieldname, condition, value, hidden];
			const promise = this.push_new_filter(args, is_new_filter);
			return (promise && promise.then) ? promise : Promise.resolve();
		}
	}

	validate_args(doctype, fieldname) {
		if (doctype && fieldname
			&& !frappe.meta.has_field(doctype, fieldname)
			&& !frappe.model.std_fields_list.includes(fieldname)) {

			frappe.throw(__("Invalid filter: {0}", [fieldname.bold()]));
			return false;
		}
		return true;
	}

	push_new_filter(args, is_new_filter=false) {
		// args: [doctype, fieldname, condition, value]
		if(this.filter_exists(args)) return;

		// {}: Clear page filter fieldname field

		let filter = this._push_new_filter(...args);

		if (filter && filter.value) {
			filter.setup_state(is_new_filter);
			return filter._filter_value_set; // internal promise
		}
	}

	_push_new_filter(doctype, fieldname, condition, value, hidden = false) {
		let args = {
			parent: this.wrapper,
			parent_doctype: this.doctype,
			doctype: doctype,
			fieldname: fieldname,
			condition: condition,
			value: value,
			hidden: hidden,
			on_change: (update) => {
				if(update) this.update_filters();
				this.on_change();
			},
			filter_items: (doctype, fieldname) => {
				return !this.filter_exists([doctype, fieldname]);
			},
			filter_list: this.base_list || this,
		};
		let filter = new frappe.ui.Filter(args);
		this.filters.push(filter);
		return filter;
	}

	get_filter_value(fieldname) {
		let filter_obj = this.filters.find(f => f.fieldname == fieldname) || {};
		return filter_obj.value;
	}

	filter_exists(filter_value) {
		// filter_value of form: [doctype, fieldname, condition, value]
		let exists = false;
		this.filters.filter(f => f.field).map(f => {
			let f_value = f.get_value();
			if (filter_value.length === 2) {
				exists = filter_value[0] === f_value[0] && filter_value[1] === f_value[1];
				return;
			}

			let value = filter_value[3];
			let equal = frappe.utils.arrays_equal;

			if(equal(f_value.slice(0, 4), filter_value.slice(0, 4)) || (Array.isArray(value) && equal(value, f_value[3]))) {
				exists = true;
			}
		});
		return exists;
	}

	get_filters() {
		return this.filters.filter(f => f.field).map(f => {
			return f.get_value();
		});
		// {}: this.list.update_standard_filters(values);
	}

	update_filters() {
		this.filters = this.filters.filter(f => f.field); // remove hidden filters
		this.toggle_clear_filter();
	}

	clear_filters() {
		this.filters.map(f => f.remove(true));
		// {}: Clear page filters, .date-range-picker (called list run())
		this.filters = [];
	}

	get_filter(fieldname) {
		return this.filters.filter(f => {
			return (f.field && f.field.df.fieldname==fieldname);
		})[0];
	}

	get_container_template() {
		return $(`

				<button class="btn btn-default btn-xs filter-button text-muted add-filter">
					${__("Add Filter")}
				</button><button class="btn btn-default btn-xs filter-button text-muted clear-filters" style="display: none;">
					${__("Clear Filters")}
				</button>

`);
	}

	get_filters_as_object() {
		let filters = this.get_filters().reduce((acc, filter) => {
			return Object.assign(acc, {
				[filter[1]]: [filter[2], filter[3]]
			});
		}, {});
		return filters;
	}

	add_filters_to_filter_group(filters) {

		filters.forEach(filter => {
			this.add_filter(filter[0], filter[1], filter[2], filter[3]);
		});
	}
};
<commit_msg>fix: don't throw if filter is invalid<commit_after>frappe.ui.FilterGroup = class {
	constructor(opts) {
		$.extend(this, opts);
		this.wrapper = this.parent;
		this.filters = [];
		this.make();
		window.fltr = this;
	}

	make() {
		this.wrapper.append(this.get_container_template());
		this.set_events();
	}

	toggle_clear_filter() {
		let clear_filter_button = this.wrapper.find('.clear-filters');

		if (this.filters.length == 0) {
			clear_filter_button.hide();
		} else {
			clear_filter_button.show();
		}
	}
	set_events() {
		this.wrapper.find('.add-filter').on('click', () => {
			this.add_filter(this.doctype, 'name')
				.then(this.toggle_clear_filter());

		});
		this.wrapper.find('.clear-filters').on('click', () => {
			this.clear_filters();
		});
	}

	add_filters(filters) {
		let promises = [];

		for (const filter of filters) {
			promises.push(() => this.add_filter(...filter));
		}

		promises.push(() => this.toggle_clear_filter());

		return frappe.run_serially(promises);
	}

	add_filter(doctype, fieldname, condition, value, hidden) {
		if (!fieldname) return Promise.resolve();
		// adds a new filter, returns true if filter has been added

		// {}: Add in page filter by fieldname if exists ('=' => 'like')

		if(!this.validate_args(doctype, fieldname)) return false;
		const is_new_filter = arguments.length < 2;
		if (is_new_filter && this.wrapper.find(".new-filter:visible").length) {
			// only allow 1 new filter at a time!
			return Promise.resolve();
		} else {
			let args = [doctype, fieldname, condition, value, hidden];
			const promise = this.push_new_filter(args, is_new_filter);
			return (promise && promise.then) ? promise : Promise.resolve();
		}
	}

	validate_args(doctype, fieldname) {
		if (doctype && fieldname
			&& !frappe.meta.has_field(doctype, fieldname)
			&& !frappe.model.std_fields_list.includes(fieldname)) {

			frappe.msgprint({
				message: __('Invalid filter: {0}', [fieldname.bold()]),
				indicator: 'red',
			});

			return false;
		}
		return true;
	}

	push_new_filter(args, is_new_filter=false) {
		// args: [doctype, fieldname, condition, value]
		if(this.filter_exists(args)) return;

		// {}: Clear page filter fieldname field

		let filter = this._push_new_filter(...args);

		if (filter && filter.value) {
			filter.setup_state(is_new_filter);
			return filter._filter_value_set; // internal promise
		}
	}

	_push_new_filter(doctype, fieldname, condition, value, hidden = false) {
		let args = {
			parent: this.wrapper,
			parent_doctype: this.doctype,
			doctype: doctype,
			fieldname: fieldname,
			condition: condition,
			value: value,
			hidden: hidden,
			on_change: (update) => {
				if(update) this.update_filters();
				this.on_change();
			},
			filter_items: (doctype, fieldname) => {
				return !this.filter_exists([doctype, fieldname]);
			},
			filter_list: this.base_list || this,
		};
		let filter = new frappe.ui.Filter(args);
		this.filters.push(filter);
		return filter;
	}

	get_filter_value(fieldname) {
		let filter_obj = this.filters.find(f => f.fieldname == fieldname) || {};
		return filter_obj.value;
	}

	filter_exists(filter_value) {
		// filter_value of form: [doctype, fieldname, condition, value]
		let exists = false;
		this.filters.filter(f => f.field).map(f => {
			let f_value = f.get_value();
			if (filter_value.length === 2) {
				exists = filter_value[0] === f_value[0] && filter_value[1] === f_value[1];
				return;
			}

			let value = filter_value[3];
			let equal = frappe.utils.arrays_equal;

			if(equal(f_value.slice(0, 4), filter_value.slice(0, 4)) || (Array.isArray(value) && equal(value, f_value[3]))) {
				exists = true;
			}
		});
		return exists;
	}

	get_filters() {
		return this.filters.filter(f => f.field).map(f => {
			return f.get_value();
		});
		// {}: this.list.update_standard_filters(values);
	}

	update_filters() {
		this.filters = this.filters.filter(f => f.field); // remove hidden filters
		this.toggle_clear_filter();
	}

	clear_filters() {
		this.filters.map(f => f.remove(true));
		// {}: Clear page filters, .date-range-picker (called list run())
		this.filters = [];
	}

	get_filter(fieldname) {
		return this.filters.filter(f => {
			return (f.field && f.field.df.fieldname==fieldname);
		})[0];
	}

	get_container_template() {
		return $(`

				<button class="btn btn-default btn-xs filter-button text-muted add-filter">
					${__("Add Filter")}
				</button><button class="btn btn-default btn-xs filter-button text-muted clear-filters" style="display: none;">
					${__("Clear Filters")}
				</button>

`);
	}

	get_filters_as_object() {
		let filters = this.get_filters().reduce((acc, filter) => {
			return Object.assign(acc, {
				[filter[1]]: [filter[2], filter[3]]
			});
		}, {});
		return filters;
	}

	add_filters_to_filter_group(filters) {

		filters.forEach(filter => {
			this.add_filter(filter[0], filter[1], filter[2], filter[3]);
		});
	}
};
<|endoftext|>