<commit_before>(function() {
  var siteBaseUrl = 'https://github.com/';
  var repoBaseUrl = 'https://api.github.com/repos/';
  var userBaseUrl = 'https://api.github.com/users/';

  var renderer = new marked.Renderer();
  renderer.listitem = function(text) {
    if (/^\s*\[[x ]\]\s*/.test(text)) {
      text = text
        .replace(/^\s*\[ \]\s*/, ' ')
        .replace(/^\s*\[x\]\s*/, ' ');
      return '
' + text + '
';
    } else {
      return '
' + text + '
';
    }
  };

  /** Filters **/
  Vue.filter('marked', function(v, k) {
    return marked(v, {renderer: renderer});
  });
  Vue.filter('stripComments', function(v) {
    return v.replace(/<![\s\S]*?--[ \t\n\r]*>/g,'');
  });
  Vue.filter('truncate', function (v) {
    var newline = v.indexOf('\n');
    return newline > -1 ? v.slice(0, newline) : v;
  });
  Vue.filter('formatDate', function (v) {
    if (v) {
      return (new Date(v)).toDateString();
    }
  });

  var Fetchable = Vue.extend({
    methods: {
      fetchData: function () {
        if (!this.apiUrl) return false;
        var xhr = new XMLHttpRequest(),
            self = this;
        xhr.open('GET', self.apiUrl);
        xhr.onload = function () {
          self.items = JSON.parse(xhr.responseText);
        };
        xhr.send();
      }
    }
  });

  /** Resource Components **/
  var GitHubRepoList = Fetchable.extend({
    computed: {
      apiUrl: function() {
        if (this.user) {
          var url = userBaseUrl + this.user + '/repos';
          return url;
        }
      }
    },
    created: function() {
      this.$watch('user', function() {
        this.fetchData();
      });
    }
  });

  var GitHubBranchList = Fetchable.extend({
    computed: {
      apiUrl: function() {
        if (this.user && this.project) {
          var url = repoBaseUrl + this.user + '/' + this.project + '/branches';
          return url;
        }
      }
    },
    created: function () {
      this.$watch('user', function () {
        if (this.project) {
          this.fetchData();
        }
      });
      this.$watch('project', function () {
        this.fetchData();
      });
    }
  });

  var GitHubCommitList = Fetchable.extend({
    computed: {
      apiUrl: function() {
        if (this.user && this.project) {
          var url = repoBaseUrl + this.user + '/' + this.project + '/commits?per_page=3&sha=' + (this.branch == 'master' ? '' : this.branch);
          return url;
        }
      }
    },
    created: function () {
      this.$watch('user', function () {
        this.branch = 'master';
        this.fetchData();
      });
      this.$watch('project', function () {
        this.branch = 'master';
        this.fetchData();
      });
      this.$watch('branch', function () {
        this.fetchData();
      });
    }
  });

  var GitHubMilestoneList = Fetchable.extend({
    paramAttributes: ['data-sort', 'data-state',
      'data-milestone'],
    computed: {
      apiUrl: function() {
        if (this.user && this.project) {
          var sort = this.$data['data-sort'] || 'due_date';
          var state = this.$data['data-state'] || 'open';
          var url = repoBaseUrl + this.user + '/'
            + this.project + '/milestones'
            + '?sort=' + sort
            + '&state=' + state;
          return url;
        }
      },
      htmlUrl: function() {
        if (this.user && this.project) {
          var url = siteBaseUrl + this.user + '/' + this.project + '/issues/milestones';
          return url;
        }
      }
    },
    created: function () {
      this.$watch('user', function () {
        this.fetchData();
      });
      this.$watch('project', function () {
        this.fetchData();
      });
    }
  });

  var GitHubIssueList = Fetchable.extend({
    computed: {
      apiUrl: function() {
        if (this.user && this.project) {
          var url = repoBaseUrl + this.user + '/' + this.project + '/issues';
          if (this.milestone && this.milestone.number) {
            url += '?milestone=' + this.milestone.number;
            if (this.milestone.state == 'closed') {
              url += '&state=all';
            }
          }
          return url;
        }
      },
      htmlUrl: function() {
        if (this.user && this.project) {
          var url = siteBaseUrl + this.user + '/' + this.project + '/issues';
          return url;
        }
      }
    },
    created: function () {
      this.$watch('user', function () {
        this.fetchData();
      });
      this.$watch('project', function () {
        this.fetchData();
      });
      this.$watch('milestone', function () {
        this.fetchData();
      });
    }
  });

  /** Rendering Components **/
  Vue.component('github-repo-list', GitHubRepoList.extend({
  }));

  Vue.component('github-branch-list', GitHubBranchList.extend({
  }));

  Vue.component('github-commit-list', GitHubCommitList.extend({
  }));

  Vue.component('github-commit', {
    template: '#template-github-commit'
  });

  var toggleMilestone = function(e) {
    if (this.$parent.milestone == e.targetVM.$data) {
      this.$parent.milestone = {};
    } else {
      this.$parent.milestone = e.targetVM.$data;
    }
  };

  Vue.component('github-milestone-list', GitHubMilestoneList.extend({
    template: '#template-github-milestone-list',
    methods: {
      toggleMilestone: toggleMilestone
    }
  }));

  Vue.component('github-milestone-accordion', GitHubMilestoneList.extend({
    template: '#template-github-milestone-accordion',
    methods: {
      toggleMilestone: toggleMilestone
    }
  }));

  Vue.component('github-milestone-flattened', GitHubMilestoneList.extend({
    template: '#template-github-milestone-flattened',
    methods: {
      toggleMilestone: toggleMilestone
    }
  }));

  var toggleActive = function(e) {
    if (e.targetVM.accordionOpen) {
      e.targetVM.accordionOpen = false;
    } else {
      e.targetVM.accordionOpen = true;
    }
  };

  Vue.component('github-issue-list', GitHubIssueList.extend({
    template: '#template-github-issue-list',
    methods: {
      toggleActive: toggleActive
    }
  }));
  Vue.component('github-issue-accordion', GitHubIssueList.extend({
    template: '#template-github-issue-accordion',
    methods: {
      toggleActive: toggleActive
    }
  }));
  Vue.component('github-issue-flattened', GitHubIssueList.extend({
    template: '#template-github-issue-flattened',
    methods: {
      toggleActive: toggleActive
    }
  }));
})();
<commit_msg>caching responses in localStorage<commit_after>(function() {
  var siteBaseUrl = 'https://github.com/';
  var repoBaseUrl = 'https://api.github.com/repos/';
  var userBaseUrl = 'https://api.github.com/users/';

  var renderer = new marked.Renderer();
  renderer.listitem = function(text) {
    if (/^\s*\[[x ]\]\s*/.test(text)) {
      text = text
        .replace(/^\s*\[ \]\s*/, ' ')
        .replace(/^\s*\[x\]\s*/, ' ');
      return '
' + text + '
';
    } else {
      return '
' + text + '
';
    }
  };

  /** Filters **/
  Vue.filter('marked', function(v, k) {
    return marked(v, {renderer: renderer});
  });
  Vue.filter('stripComments', function(v) {
    return v.replace(/<![\s\S]*?--[ \t\n\r]*>/g,'');
  });
  Vue.filter('truncate', function (v) {
    var newline = v.indexOf('\n');
    return newline > -1 ? v.slice(0, newline) : v;
  });
  Vue.filter('formatDate', function (v) {
    if (v) {
      return (new Date(v)).toDateString();
    }
  });

  var Fetchable = Vue.extend({
    methods: {
      fetchData: function () {
        if (!this.apiUrl) return false;

        var apiUrlHash = btoa(this.apiUrl),
            xhr = new XMLHttpRequest(),
            self = this;
        if (window.localStorage[apiUrlHash]) {
          self.items = JSON.parse(window.localStorage[apiUrlHash]);
        } else {
          xhr.open('GET', self.apiUrl);
          xhr.onload = function () {
            window.localStorage[apiUrlHash] = xhr.responseText;
            self.items = JSON.parse(xhr.responseText);
          };
          xhr.send();
        }
      }
    }
  });

  /** Resource Components **/
  var GitHubRepoList = Fetchable.extend({
    computed: {
      apiUrl: function() {
        if (this.user) {
          var url = userBaseUrl + this.user + '/repos';
          return url;
        }
      }
    },
    created: function() {
      this.$watch('user', function() {
        this.fetchData();
      });
    }
  });

  var GitHubBranchList = Fetchable.extend({
    computed: {
      apiUrl: function() {
        if (this.user && this.project) {
          var url = repoBaseUrl + this.user + '/' + this.project + '/branches';
          return url;
        }
      }
    },
    created: function () {
      this.$watch('user', function () {
        if (this.project) {
          this.fetchData();
        }
      });
      this.$watch('project', function () {
        this.fetchData();
      });
    }
  });

  var GitHubCommitList = Fetchable.extend({
    computed: {
      apiUrl: function() {
        if (this.user && this.project) {
          var url = repoBaseUrl + this.user + '/' + this.project + '/commits?per_page=3&sha=' + (this.branch == 'master' ? '' : this.branch);
          return url;
        }
      }
    },
    created: function () {
      this.$watch('user', function () {
        this.branch = 'master';
        this.fetchData();
      });
      this.$watch('project', function () {
        this.branch = 'master';
        this.fetchData();
      });
      this.$watch('branch', function () {
        this.fetchData();
      });
    }
  });

  var GitHubMilestoneList = Fetchable.extend({
    paramAttributes: ['data-sort', 'data-state',
      'data-milestone'],
    computed: {
      apiUrl: function() {
        if (this.user && this.project) {
          var sort = this.$data['data-sort'] || 'due_date';
          var state = this.$data['data-state'] || 'open';
          var url = repoBaseUrl + this.user + '/'
            + this.project + '/milestones'
            + '?sort=' + sort
            + '&state=' + state;
          return url;
        }
      },
      htmlUrl: function() {
        if (this.user && this.project) {
          var url = siteBaseUrl + this.user + '/' + this.project + '/issues/milestones';
          return url;
        }
      }
    },
    created: function () {
      this.$watch('user', function () {
        this.fetchData();
      });
      this.$watch('project', function () {
        this.fetchData();
      });
    }
  });

  var GitHubIssueList = Fetchable.extend({
    computed: {
      apiUrl: function() {
        if (this.user && this.project) {
          var url = repoBaseUrl + this.user + '/' + this.project + '/issues';
          if (this.milestone && this.milestone.number) {
            url += '?milestone=' + this.milestone.number;
            if (this.milestone.state == 'closed') {
              url += '&state=all';
            }
          }
          return url;
        }
      },
      htmlUrl: function() {
        if (this.user && this.project) {
          var url = siteBaseUrl + this.user + '/' + this.project + '/issues';
          return url;
        }
      }
    },
    created: function () {
      this.$watch('user', function () {
        this.fetchData();
      });
      this.$watch('project', function () {
        this.fetchData();
      });
      this.$watch('milestone', function () {
        this.fetchData();
      });
    }
  });

  /** Rendering Components **/
  Vue.component('github-repo-list', GitHubRepoList.extend({
  }));

  Vue.component('github-branch-list', GitHubBranchList.extend({
  }));

  Vue.component('github-commit-list', GitHubCommitList.extend({
  }));

  Vue.component('github-commit', {
    template: '#template-github-commit'
  });

  var toggleMilestone = function(e) {
    if (this.$parent.milestone == e.targetVM.$data) {
      this.$parent.milestone = {};
    } else {
      this.$parent.milestone = e.targetVM.$data;
    }
  };

  Vue.component('github-milestone-list', GitHubMilestoneList.extend({
    template: '#template-github-milestone-list',
    methods: {
      toggleMilestone: toggleMilestone
    }
  }));

  Vue.component('github-milestone-accordion', GitHubMilestoneList.extend({
    template: '#template-github-milestone-accordion',
    methods: {
      toggleMilestone: toggleMilestone
    }
  }));

  Vue.component('github-milestone-flattened', GitHubMilestoneList.extend({
    template: '#template-github-milestone-flattened',
    methods: {
      toggleMilestone: toggleMilestone
    }
  }));

  var toggleActive = function(e) {
    if (e.targetVM.accordionOpen) {
      e.targetVM.accordionOpen = false;
    } else {
      e.targetVM.accordionOpen = true;
    }
  };

  Vue.component('github-issue-list', GitHubIssueList.extend({
    template: '#template-github-issue-list',
    methods: {
      toggleActive: toggleActive
    }
  }));
  Vue.component('github-issue-accordion', GitHubIssueList.extend({
    template: '#template-github-issue-accordion',
    methods: {
      toggleActive: toggleActive
    }
  }));
  Vue.component('github-issue-flattened', GitHubIssueList.extend({
    template: '#template-github-issue-flattened',
    methods: {
      toggleActive: toggleActive
    }
  }));
})();
<|endoftext|>


<commit_before>/*
chipotle order online
*/

module.exports = {
  'open chipotle.com' : function (client) {
    client
      .url('https://chipotle.com/')
      //.maximizeWindow()
      .url(function(result){
        console.log(result);
      })
      .waitForElementPresent('body', 2000)
      .saveScreenshot('./screenshots/screenshot1.png')
      .useXpath()
      .click('/html/body/header/div[1]/div/nav[3]/ul/li[3]/a/span')
      .useCss()
      .waitForElementPresent('body', 2000)
      .saveScreenshot('./screenshots/screenshot2.png')

  },

  'find your chipotle' : function(client) {
    client
      .window_handles(function(result) {
          var handle = result.value[1];
          this.switchWindow(handle);
        })
      .waitForElementPresent('body', 3000)
      .pause(2000)
      .saveScreenshot('./screenshots/screenshot3.png')
      .useXpath()
      .setValue('/html/body/div/div/cmg-order-entree/div/div[1]/div/form/input', ['07110',])
      .useCss()
      .pause(1000)
      .saveScreenshot('./screenshots/screenshot4.png')
      .keys(client.Keys.ENTER)
      .pause(1000)
      .saveScreenshot('./screenshots/screenshot5.png')
  },

  'select Clifton' :function(client) {
    client
      //.click('id="817"')
      .useXpath()
      .click('//*[@id="817"]')
      //.assert.attributeContains("/html/body/div/div/cmg-order-entree/div/div[2]/div/div[1]", 'Clifton')
      //.assert.containsText("#main", "Clifton")
      //.assert.urlEquals('https://order.chipotle.com/?_ga=1.48495968.795510196.1485274896')
      .useCss()

  },

  'order' : function(client) {
    client
      .useXpath()
      //.click('#Burrito bowl')
      //.click('button[name=burrio bowl]')
      .click('/html/body/div/div/cmg-order-entree/div/div[3]/cmg-entrees/div/div[1]/div[2]/div/a/cmg-entree-tile')
      //.waitForElementPresent('body', 3000)
      .pause(2000)
            .url(function(result){
        console.log("Meat?")
      })
      .click('//*[@id="carnitas"]')
      //.pause(2000)
      .url(function(result){
        console.log("Rice?")
      })
      .click('//*[@id="ricebrown"]')
      .url(function(result){
        console.log("Beans?")
      })
      .click('//*[@id="beansblack"]')
      .url(function(result){
        console.log("Want guac?")
      })
      .click('//*[@id="guactopping"]')
      .url(function(result){
        console.log("I know it costs extra!")
        console.log("Extras?")
      })
      .click('//*[@id="salsacorn"]')

      .click('//*[@id="salsagreenchili"]')

      .click('//*[@id="cheese"]')

      .click('//*[@id="lettuce"]')

      .click('//*[@id="chipsandguacamole"]')

      .click('//*[@id="sodalarge"]')
      .url(function(result){
        console.log("add to bag")
      })
      .click('//*[@id="next"]')
  },

  'special instructions': function(client) {
    client
      .click('//*[@id="bag-container"]')
      //.click('//*[@id="bag-container"]/div[4]/div[2]/div[2]/div/div/cmg-meal-summary/div/div[1]/div[1]/a')
      .useCss()
      .setValue('input[type=text]', ['Alex Rose'])

  //.end();
  }
};
<commit_msg>Update chipotleonlineorder.js<commit_after>/*
chipotle order online
*/

module.exports = {
  'open chipotle.com' : function (client) {
    client
      .url('https://chipotle.com/')
      //.maximizeWindow()
      .url(function(result){
        console.log(result);
      })
      .waitForElementPresent('body', 2000)
      .saveScreenshot('./screenshots/screenshot1.png')
      .useXpath()
      .click('/html/body/header/div[1]/div/nav[3]/ul/li[3]/a/span')
      .useCss()
      .waitForElementPresent('body', 2000)
      .saveScreenshot('./screenshots/screenshot2.png')

  },

  'find your chipotle' : function(client) {
    client
      .window_handles(function(result) {
          client.assert.equal(result.value.length, 2, 'There should be two windows open.');
          var handle = result.value[1];
          this.switchWindow(handle);
        })
      .waitForElementPresent('body', 3000)
      .pause(2000)
      .saveScreenshot('./screenshots/screenshot3.png')
      .useXpath()
      .setValue('/html/body/div/div/cmg-order-entree/div/div[1]/div/form/input', ['07110',])
      .useCss()
      .pause(1000)
      .saveScreenshot('./screenshots/screenshot4.png')
      .keys(client.Keys.ENTER)
      .pause(1000)
      .saveScreenshot('./screenshots/screenshot5.png')
  },

  'select Clifton' :function(client) {
    client
      //.click('id="817"')
      .useXpath()
      .click('//*[@id="817"]')
      //.assert.attributeContains("/html/body/div/div/cmg-order-entree/div/div[2]/div/div[1]", 'Clifton')
      //.assert.containsText("#main", "Clifton")
      //.assert.urlEquals('https://order.chipotle.com/?_ga=1.48495968.795510196.1485274896')
      .useCss()

  },

  'order' : function(client) {
    client
      .useXpath()
      //.click('#Burrito bowl')
      //.click('button[name=burrio bowl]')
      .click('/html/body/div/div/cmg-order-entree/div/div[3]/cmg-entrees/div/div[1]/div[2]/div/a/cmg-entree-tile')
      //.waitForElementPresent('body', 3000)
      .pause(2000)
            .url(function(result){
        console.log("Meat?")
      })
      .click('//*[@id="carnitas"]')
      //.pause(2000)
      .url(function(result){
        console.log("Rice?")
      })
      .click('//*[@id="ricebrown"]')
      .url(function(result){
        console.log("Beans?")
      })
      .click('//*[@id="beansblack"]')
      .url(function(result){
        console.log("Want guac?")
      })
      .click('//*[@id="guactopping"]')
      .url(function(result){
        console.log("I know it costs extra!")
        console.log("Extras?")
      })
      .click('//*[@id="salsacorn"]')

      .click('//*[@id="salsagreenchili"]')

      .click('//*[@id="cheese"]')

      .click('//*[@id="lettuce"]')

      .click('//*[@id="chipsandguacamole"]')

      .click('//*[@id="sodalarge"]')
      .url(function(result){
        console.log("add to bag")
      })
      .click('//*[@id="next"]')
  },

  'special instructions': function(client) {
    client
      .click('//*[@id="bag-container"]')
      //.click('//*[@id="bag-container"]/div[4]/div[2]/div[2]/div/div/cmg-meal-summary/div/div[1]/div[1]/a')
      .useCss()
      .setValue('input[type=text]', ['Alex Rose'])

  //.end();
  }
};
<|endoftext|>


<commit_before>// framed glossary support, runs in parent window
Glossary = {
	//timers...
	wait: null,
	dirty: null,

	input: document.getElementById("rc-find"),
	warning: document.getElementById("rc-warning"),
	window: document.getElementById('rc-glossary').contentWindow,
	touch: 'ontouchstart' in window,

	init: function () { // messages from inside iframe...
		addEventListener('message', function (event) {
			var d = event.data
			if (d.indexOf('height ') === 0) {
				document.getElementById('rc-glossary').height = parseInt(d.substr(7)) + 200
				if (location.hash) Glossary.gloss(location.hash.substr(1))
				}
			else if (d.indexOf('top ') === 0) {
				document.documentElement.scrollTop = document.body.scrollTop = window.pageYOffset = parseInt(d.substr(4))
				if (!Glossary.touch) Glossary.input.focus()
				}
			else if (d.indexOf('no ') === 0) {
				document.getElementById('rc-warning').textContent = d.substr(3) + ' cannot be found.'
				if (this.dirty) clearTimeout(this.dirty)
				this.dirty = setTimeout(function () {
					Glossary.warning.textContent = ''
					}, 4000)
				}
			})
		},

	gloss: function (term) { // scroll to term...
		if (this.touch) this.input.blur()
		if (!term) term = this.input.value
		if (!term) return
		this.window.postMessage('gloss ' + term, '*')
		if (this.dirty) clearTimeout(this.dirty)
		this.dirty = setTimeout(function () {
			Glossary.input.value = Glossary.warning.textContent = ''
			}, 4000)
		},

	keypress: function () { // user input...
		if (this.wait) clearTimeout(this.wait)
		this.wait = setTimeout(function () {Glossary.gloss()}, 850)
		if (this.dirty) this.dirty = clearTimeout(this.dirty)
		this.warning.textContent = ''
		return event.keyCode != 13
		}

	}

Glossary.init()
<commit_msg>handle spinner<commit_after>// framed glossary support, runs in parent window
Glossary = {
	//timers...
	wait: null,
	dirty: null,

	input: document.getElementById("rc-find"),
	warning: document.getElementById("rc-warning"),
	window: document.getElementById('rc-glossary').contentWindow,
	touch: 'ontouchstart' in window,

	init: function () { // messages from inside iframe...
		addEventListener('message', function (event) {
			var d = event.data
			if (d.indexOf('height ') === 0) {
				document.getElementById('rc-glossary').height = parseInt(d.substr(7)) + 200
				document.getElementById('rc-spinner').style.display = 'none'
				if (location.hash) Glossary.gloss(location.hash.substr(1))
				}
			else if (d.indexOf('top ') === 0) {
				document.documentElement.scrollTop = document.body.scrollTop = window.pageYOffset = parseInt(d.substr(4))
				if (!Glossary.touch) Glossary.input.focus()
				}
			else if (d.indexOf('no ') === 0) {
				document.getElementById('rc-warning').textContent = d.substr(3) + ' cannot be found.'
				if (this.dirty) clearTimeout(this.dirty)
				this.dirty = setTimeout(function () {
					Glossary.warning.textContent = ''
					}, 4000)
				}
			})
		},

	gloss: function (term) { // scroll to term...
		if (this.touch) this.input.blur()
		if (!term) term = this.input.value
		if (!term) return
		this.window.postMessage('gloss ' + term, '*')
		if (this.dirty) clearTimeout(this.dirty)
		this.dirty = setTimeout(function () {
			Glossary.input.value = Glossary.warning.textContent = ''
			}, 4000)
		},

	keypress: function () { // user input...
		if (this.wait) clearTimeout(this.wait)
		this.wait = setTimeout(function () {Glossary.gloss()}, 850)
		if (this.dirty) this.dirty = clearTimeout(this.dirty)
		this.warning.textContent = ''
		return event.keyCode != 13
		}

	}

Glossary.init()
<|endoftext|>


<commit_before>module.exports = {
	dist : {
		src: ['js/util.js', 'js/dialogs.js'],
		options: {
			destination: 'docs/jsdoc'
		}
	}
};<commit_msg>Path to custom jsdoc template<commit_after>module.exports = {
	dist : {
		src: ['js/util.js', 'js/dialogs.js'],
		options: {
			destination: 'docs/jsdoc',
			template: 'docs/templates/jsdoc'
		}
	}
};<|endoftext|>


<commit_before>// Global configuration
var config = {
      api: { endpoint: 'http://api.spokanelibrary.org/v2/'
           }
}

// Modified http://paulirish.com/2009/markup-based-unobtrusive-comprehensive-dom-ready-execution/
// Only fires on body class (working off strictly WordPress body_class)

var ORG = {
  // All pages
  common: {
    init: function() {
      MBP.hideUrlBarOnLoad();

      // trigger tabs from alternate links
      $('body').on('click', '[data-toggle="tab"]', function(e) {
        $('a[href='+$(this).attr('href')+']').tab('show');
      });

      // Ajax defaults
      $.ajaxSetup({
         type: 'POST'
        ,dataType: 'json'
        ,dataType: 'jsonp'
        ,jsonp: 'callback'
        /*
        ,complete: function(obj) {
          console.log( $.parseJSON(obj.responseText) );
        }
        */
      });

    },
    finalize: function() {
      $('body').tooltip({
        selector: 'a[rel=tooltip]'
      });
    }
  }
, home: {
    init: function() {
      //console.log(config);
    }
  }

, account: {
    init: function() {

      Modernizr.load([
        {
          load: '../js/org/account.js',
          complete: function () {
            org.init();
          }
        }
      ]);

    }
  }
};

var UTIL = {
  fire: function(func, funcname, args) {
    var namespace = ORG;
    funcname = (funcname === undefined) ? 'init' : funcname;
    if (func !== '' && namespace[func] && typeof namespace[func][funcname] === 'function') {
      namespace[func][funcname](args);
    }
  },
  loadEvents: function() {

    UTIL.fire('common');

    $.each(document.body.className.replace(/-/g, '_').split(/\s+/),function(i,classnm) {
      UTIL.fire(classnm);
    });

    UTIL.fire('common', 'finalize');
  }
};

// https://github.com/h5bp/html5-boilerplate/blob/master/js/plugins.js
// Avoid `console` errors in browsers that lack a console.
(function() {
    var method;
    var noop = function () {};
    var methods = [
        'assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error',
        'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log',
        'markTimeline', 'profile', 'profileEnd', 'table', 'time', 'timeEnd',
        'timeStamp', 'trace', 'warn'
    ];
    var length = methods.length;
    var console = (window.console = window.console || {});

    while (length--) {
        method = methods[length];

        // Only stub undefined methods.
        if (!console[method]) {
            console[method] = noop;
        }
    }
}());

$(document).ready(UTIL.loadEvents);
<commit_msg>path to account.js<commit_after>// Global configuration
var config = {
      api: { endpoint: 'http://api.spokanelibrary.org/v2/'
           }
}

// Modified http://paulirish.com/2009/markup-based-unobtrusive-comprehensive-dom-ready-execution/
// Only fires on body class (working off strictly WordPress body_class)

var ORG = {
  // All pages
  common: {
    init: function() {
      MBP.hideUrlBarOnLoad();

      // trigger tabs from alternate links
      $('body').on('click', '[data-toggle="tab"]', function(e) {
        $('a[href='+$(this).attr('href')+']').tab('show');
      });

      // Ajax defaults
      $.ajaxSetup({
         type: 'POST'
        ,dataType: 'json'
        ,dataType: 'jsonp'
        ,jsonp: 'callback'
        /*
        ,complete: function(obj) {
          console.log( $.parseJSON(obj.responseText) );
        }
        */
      });

    },
    finalize: function() {
      $('body').tooltip({
        selector: 'a[rel=tooltip]'
      });
    }
  }
, home: {
    init: function() {
      //console.log(config);
    }
  }

, account: {
    init: function() {

      Modernizr.load([
        {
          load: '../assets/js/org/account.js',
          complete: function () {
            org.init();
          }
        }
      ]);

    }
  }
};

var UTIL = {
  fire: function(func, funcname, args) {
    var namespace = ORG;
    funcname = (funcname === undefined) ? 'init' : funcname;
    if (func !== '' && namespace[func] && typeof namespace[func][funcname] === 'function') {
      namespace[func][funcname](args);
    }
  },
  loadEvents: function() {

    UTIL.fire('common');

    $.each(document.body.className.replace(/-/g, '_').split(/\s+/),function(i,classnm) {
      UTIL.fire(classnm);
    });

    UTIL.fire('common', 'finalize');
  }
};

// https://github.com/h5bp/html5-boilerplate/blob/master/js/plugins.js
// Avoid `console` errors in browsers that lack a console.
(function() {
    var method;
    var noop = function () {};
    var methods = [
        'assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error',
        'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log',
        'markTimeline', 'profile', 'profileEnd', 'table', 'time', 'timeEnd',
        'timeStamp', 'trace', 'warn'
    ];
    var length = methods.length;
    var console = (window.console = window.console || {});

    while (length--) {
        method = methods[length];

        // Only stub undefined methods.
        if (!console[method]) {
            console[method] = noop;
        }
    }
}());

$(document).ready(UTIL.loadEvents);
<|endoftext|>


<commit_before>// Compile SCSS files to CSS

module.exports = function(grunt) {
    grunt.config('sass', {
        dev: {
            options: {
                sourcemap: false,
                style: 'nested',
                precision: 5
            },
            files: [{
                expand: true,
                cwd: 'scss',
                src: ['*.scss'],
                dest: 'styles',
                ext: '.css'
            }],
        },
        deploy: {
            options: {
                sourcemap: false,
                style: 'compressed',
                precision: 5
            },
            files: [{
                expand: true,
                cwd: 'scss',
                src: ['*.scss'],
                dest: 'dist/styles',
                ext: '.css'
            }],
        },
    });

    grunt.loadNpmTasks('grunt-contrib-sass');
};
<commit_msg>Generate Sass source maps<commit_after>// Compile SCSS files to CSS

module.exports = function(grunt) {
    grunt.config('sass', {
        dev: {
            options: {
                sourcemap: true,
                style: 'nested',
                precision: 5
            },
            files: [{
                expand: true,
                cwd: 'scss',
                src: ['*.scss'],
                dest: 'styles',
                ext: '.css'
            }],
        },
        deploy: {
            options: {
                sourcemap: true,
                style: 'compressed',
                precision: 5
            },
            files: [{
                expand: true,
                cwd: 'scss',
                src: ['*.scss'],
                dest: 'dist/styles',
                ext: '.css'
            }],
        },
    });

    grunt.loadNpmTasks('grunt-contrib-sass');
};
<|endoftext|>


<commit_before>/* ========================================================================
 * DOM-based Routing
 * Based on http://goo.gl/EUTi53 by Paul Irish
 *
 * Only fires on body classes that match. If a body class contains a dash,
 * replace the dash with an underscore when adding it to the object below.
 *
 * .noConflict()
 * The routing is enclosed within an anonymous function so that you can
 * always reference jQuery with $, even when in .noConflict() mode.
 *
 * Google CDN, Latest jQuery
 * To use the default WordPress version of jQuery, go to lib/config.php and
 * remove or comment out: add_theme_support('jquery-cdn');
 * ======================================================================== */

(function($) {

// Use this variable to set up the common and page specific functions. If you
// rename this variable, you will also need to rename the namespace below.
var I4web = {
  // All pages
  common: {
    init: function() {
      // JavaScript to be fired on all pages

    }
  },
  // Home page
  home: {
    init: function() {
      // JavaScript to be fired on the home page

	  //Simple solution for smooth scrolling
	   $('a[href*=#]:not([href=#])').click(function() {
      if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {

	    var target = $(this.hash);

	    target = target.length ? target : $('[name=' + this.hash.slice(1) +']');

	  if (target.length) {
        $('html,body').animate({
          scrollTop: target.offset().top
        }, 500);
        return false;
      }
      }
 	   });  //end solution for smooth scrolling

	   //Script to trigger the radial progress bars when they enter the users viewport
	   //Function to check whether the elements are in the viewport
  $.fn.visible = function(partial) {

      var $t            = $(this),
          $w            = $(window),
          viewTop       = $w.scrollTop(),
          viewBottom    = viewTop + $w.height(),
          _top          = $t.offset().top,
          _bottom       = _top + $t.height(),
          compareTop    = partial === true ? _bottom : _top,
          compareBottom = partial === true ? _top : _bottom;

    return ((compareBottom <= viewBottom) && (compareTop >= viewTop));

  };

	//Store the window element
	var win = $(window);

	// Store the target class to look for in the viewport. This triggers the action of the radial progress bar upon moving
	// into the viewport
	var allMods = $(".radial-progress");

	//Function to store the Strengths Pct into Data Progress. Effectively Changes the data-progress value enabling the 0 to *num* effect
	$.fn.sernStrengths = function() {
		$('.radial-a').attr('data-progress', strengths[0]);
		$('.radial-b').attr('data-progress', strengths[1]);
		$('.radial-c').attr('data-progress', strengths[2]);
	}

	//Declare the Strengths Array. Will hold the data-strength attributes input via WordPress Admin area and collected from the HTML data-strength attribute
	var strengths = [];

	// Loop through each of the data-strength attributes. We will store the attributes and
	$("[data-strength]").each(function() {

		 var strength = $(this).attr('data-strength');
		 strengths.push(strength);

	//$('.radial-progress').click(window.sernStrengths);

	});

	allMods.each(function(i, el) {
	  var el = $(el);
	  if (el.visible(true)) {
		el.addClass("already-visible");
	  }
	});

	win.scroll(function(event) {

	  allMods.each(function(i, el) {
		var el = $(el);
		if (el.visible(true)) {
		  el.addClass("radial-progress-complete");
		  setTimeout(el.sernStrengths, 400);
		}
	  });

	});

    }
  },
  // About us page, note the change from about-us to about_us.
  about_us: {
    init: function() {
      // JavaScript to be fired on the about us page
    }
  },

  archive:{
	  init: function(){

	  setActive();

	  //Function to add the "active" class to the menu where the Walker class does not due to rewrites done to the CPT and Taxonomies.
	  function setActive() {
	    var path = window.location.pathname;

		 //split the path name and grab the 2nd element in the array to search for the correct class
	    $('.menu-' + path.split("/")[1] ).addClass('active');

		}

	  }
  }
};

// The routing fires all common scripts, followed by the page specific scripts.
// Add additional events for more control over timing e.g. a finalize event
var UTIL = {
  fire: function(func, funcname, args) {
    var namespace = I4web;
    funcname = (funcname === undefined) ? 'init' : funcname;
    if (func !== '' && namespace[func] && typeof namespace[func][funcname] === 'function') {
      namespace[func][funcname](args);
    }
  },
  loadEvents: function() {
    UTIL.fire('common');

    $.each(document.body.className.replace(/-/g, '_').split(/\s+/),function(i,classnm) {
      UTIL.fire(classnm);
    });
  }
};

$(document).ready(UTIL.loadEvents);

})(jQuery); // Fully reference jQuery after this point.
<commit_msg>Remove empty values from the path array<commit_after>/* ========================================================================
 * DOM-based Routing
 * Based on http://goo.gl/EUTi53 by Paul Irish
 *
 * Only fires on body classes that match. If a body class contains a dash,
 * replace the dash with an underscore when adding it to the object below.
 *
 * .noConflict()
 * The routing is enclosed within an anonymous function so that you can
 * always reference jQuery with $, even when in .noConflict() mode.
 *
 * Google CDN, Latest jQuery
 * To use the default WordPress version of jQuery, go to lib/config.php and
 * remove or comment out: add_theme_support('jquery-cdn');
 * ======================================================================== */

(function($) {

// Use this variable to set up the common and page specific functions. If you
// rename this variable, you will also need to rename the namespace below.
var I4web = {
  // All pages
  common: {
    init: function() {
      // JavaScript to be fired on all pages

    }
  },
  // Home page
  home: {
    init: function() {
      // JavaScript to be fired on the home page

	  //Simple solution for smooth scrolling
	   $('a[href*=#]:not([href=#])').click(function() {
      if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {

	    var target = $(this.hash);

	    target = target.length ? target : $('[name=' + this.hash.slice(1) +']');

	  if (target.length) {
        $('html,body').animate({
          scrollTop: target.offset().top
        }, 500);
        return false;
      }
      }
 	   });  //end solution for smooth scrolling

	   //Script to trigger the radial progress bars when they enter the users viewport
	   //Function to check whether the elements are in the viewport
  $.fn.visible = function(partial) {

      var $t            = $(this),
          $w            = $(window),
          viewTop       = $w.scrollTop(),
          viewBottom    = viewTop + $w.height(),
          _top          = $t.offset().top,
          _bottom       = _top + $t.height(),
          compareTop    = partial === true ? _bottom : _top,
          compareBottom = partial === true ? _top : _bottom;

    return ((compareBottom <= viewBottom) && (compareTop >= viewTop));

  };

	//Store the window element
	var win = $(window);

	// Store the target class to look for in the viewport. This triggers the action of the radial progress bar upon moving
	// into the viewport
	var allMods = $(".radial-progress");

	//Function to store the Strengths Pct into Data Progress. Effectively Changes the data-progress value enabling the 0 to *num* effect
	$.fn.sernStrengths = function() {
		$('.radial-a').attr('data-progress', strengths[0]);
		$('.radial-b').attr('data-progress', strengths[1]);
		$('.radial-c').attr('data-progress', strengths[2]);
	}

	//Declare the Strengths Array. Will hold the data-strength attributes input via WordPress Admin area and collected from the HTML data-strength attribute
	var strengths = [];

	// Loop through each of the data-strength attributes. We will store the attributes and
	$("[data-strength]").each(function() {

		 var strength = $(this).attr('data-strength');
		 strengths.push(strength);

	//$('.radial-progress').click(window.sernStrengths);

	});

	allMods.each(function(i, el) {
	  var el = $(el);
	  if (el.visible(true)) {
		el.addClass("already-visible");
	  }
	});

	win.scroll(function(event) {

	  allMods.each(function(i, el) {
		var el = $(el);
		if (el.visible(true)) {
		  el.addClass("radial-progress-complete");
		  setTimeout(el.sernStrengths, 400);
		}
	  });

	});

    }
  },
  // About us page, note the change from about-us to about_us.
  about_us: {
    init: function() {
      // JavaScript to be fired on the about us page
    }
  },

  archive: {
	  init: function() {

	      setActive();

	      //Function to add the "active" class to the menu where the Walker class does not due to rewrites done to the CPT and Taxonomies.
	      function setActive() {
	          var path = window.location.pathname;
                  // Split the path name, strip out the empty values, and grab the 1st element in the array to search for the correct class
                  var pathArray = path.split("/").filter(Boolean);
                  $('.menu-' + path.split("/")[0] ).addClass('active');

              }
	 }
  }
};

// The routing fires all common scripts, followed by the page specific scripts.
// Add additional events for more control over timing e.g. a finalize event
var UTIL = {
  fire: function(func, funcname, args) {
    var namespace = I4web;
    funcname = (funcname === undefined) ? 'init' : funcname;
    if (func !== '' && namespace[func] && typeof namespace[func][funcname] === 'function') {
      namespace[func][funcname](args);
    }
  },
  loadEvents: function() {
    UTIL.fire('common');

    $.each(document.body.className.replace(/-/g, '_').split(/\s+/),function(i,classnm) {
      UTIL.fire(classnm);
    });
  }
};

$(document).ready(UTIL.loadEvents);

})(jQuery); // Fully reference jQuery after this point.
<|endoftext|>


<commit_before>/**
 * WP Editor Widget object
 */
WPEditorWidget = {

	/**
	 * @var string
	 */
	currentContentId: '',

	/**
	 * Show the editor
	 * @param string contentId
	 */
	showEditor: function(contentId) {
		jQuery('#wp-editor-widget-backdrop').show();
		jQuery('#wp-editor-widget-container').show();

		this.currentContentId = contentId;

		this.setEditorContent(contentId);
	},

	/**
	 * Hide editor
	 */
	hideEditor: function() {
		jQuery('#wp-editor-widget-backdrop').hide();
		jQuery('#wp-editor-widget-container').hide();
	},

	/**
	 * Set editor content
	 */
	setEditorContent: function(contentId) {
		var editor = tinyMCE.EditorManager.get('wp-editor-widget');
		if (typeof editor == "undefined") {
			jQuery('#wp-editor-widget').val(jQuery('#'+ contentId).val());
		}
		else {
			editor.setContent(jQuery('#'+ contentId).val());
		}
	},

	/**
	 * Update widget and close the editor
	 */
	updateWidgetAndCloseEditor: function() {
		var editor = tinyMCE.EditorManager.get('wp-editor-widget');
		if (typeof editor == "undefined") {
			jQuery('#'+ this.currentContentId).val(jQuery('#wp-editor-widget').val());
		}
		else {
			jQuery('#'+ this.currentContentId).val(editor.getContent());
		}
		wpWidgets.save(jQuery('#'+ this.currentContentId).closest('div.widget'), 0, 1, 0);
		this.hideEditor();
	}

};<commit_msg>Functionality for customize.php<commit_after>/**
 * WP Editor Widget object
 */
WPEditorWidget = {

	/**
	 * @var string
	 */
	currentContentId: '',

	/**
	 * @var string
	 */
	 currentEditorPage: '',

	 /**
	  * @var int
	  */
	 wpFullOverlayOriginalZIndex: 0,

	/**
	 * Show the editor
	 * @param string contentId
	 */
	showEditor: function(contentId) {
		jQuery('#wp-editor-widget-backdrop').show();
		jQuery('#wp-editor-widget-container').show();

		this.currentContentId = contentId;
		this.currentEditorPage = ( jQuery('body').hasClass('wp-customizer') ? 'wp-customizer':'wp-widgets');

		if (this.currentEditorPage == "wp-customizer") {
			this.wpFullOverlayOriginalZIndex = parseInt(jQuery('.wp-full-overlay').css('zIndex'));
			jQuery('.wp-full-overlay').css({ zIndex: 49000 });
		}

		this.setEditorContent(contentId);
	},

	/**
	 * Hide editor
	 */
	hideEditor: function() {
		jQuery('#wp-editor-widget-backdrop').hide();
		jQuery('#wp-editor-widget-container').hide();

		if (this.currentEditorPage == "wp-customizer") {
			jQuery('.wp-full-overlay').css({ zIndex: this.wpFullOverlayOriginalZIndex });
		}
	},

	/**
	 * Set editor content
	 */
	setEditorContent: function(contentId) {
		var editor = tinyMCE.EditorManager.get('wp-editor-widget');
		if (typeof editor == "undefined") {
			jQuery('#wp-editor-widget').val(jQuery('#'+ contentId).val());
		}
		else {
			editor.setContent(jQuery('#'+ contentId).val());
		}
	},

	/**
	 * Update widget and close the editor
	 */
	updateWidgetAndCloseEditor: function() {
		var editor = tinyMCE.EditorManager.get('wp-editor-widget');

		if (typeof editor == "undefined") {
			jQuery('#'+ this.currentContentId).val(jQuery('#wp-editor-widget').val());
		}
		else {
			jQuery('#'+ this.currentContentId).val(editor.getContent());
		}

		// customize.php
		if (this.currentEditorPage == "wp-customizer") {
			var widget_id = jQuery('#'+ this.currentContentId).closest('div.form').find('input.widget-id').val();
			var widget_form_control = wp.customize.Widgets.getWidgetFormControlForWidget( widget_id )
			widget_form_control.updateWidget();
		}

		// widgets.php
		else {
			wpWidgets.save(jQuery('#'+ this.currentContentId).closest('div.widget'), 0, 1, 0);
		}

		this.hideEditor();
	}

};<|endoftext|>


<commit_before>"use strict";

/**
 * Main JS file for GhostScroll behaviours
 */

var $post = $('.post');
var $sitehead = $('#site-head');

/* Globals jQuery, document */
(function ($) {
	function smoothScroll (el) {
		$('html, body').animate({
			scrollTop: el.offset().top
		}, 400);
	}

	$(document).ready(function(){

        // FitVids for responsive videos
        $('.post-content').fitVids();

		$('.btn.first, #header-arrow').click( function () {
            var $first = $post.first();
			smoothScroll($first);
		});
		$('.btn.last').click( function () {
            var $last = $post.last();
			smoothScroll($last);
		});

        $('#totop-arrow').click(function () {
            smoothScroll($sitehead);
        });

        $('.fn-item').click(function (evt) {
            evt.preventDefault();
            var slug = $(this).attr("href");
            smoothScroll($(slug))
        });

        function conditionallyShowNav() {
            var navOpacity = shouldDisplayNav() ? 1 : 0;
            $(".fixed-nav").css("opacity", navOpacity);

            function shouldDisplayNav() {
                var isTooNarrow = $(window).width() < 500;
                return (!isTooNarrow && !isElementInViewport($sitehead));
            }
        }

        function highlightActiveSection() {
            $(".post-holder").each(function () {
                var $this = $(this);
                var postId = $this.attr("id");
                var thisNavLink = $(".fn-item[href='#" + postId + "']");
                var previousArrow = $(this).prev('.post-holder').find('.post-after');

                if(isElementInViewport($this)) {
                    thisNavLink.addClass('active');
                    previousArrow.fadeOut('slow');
                } else {
                    thisNavLink.removeClass('active');
                    previousArrow.fadeIn('slow');
                }
            });
        }

        function isElementInViewport($element) {
            var scrollPosition = $(window).scrollTop();
            var topOfElement = $element.offset().top;
            var bottomOfElement = topOfElement + $element.height();

            var isAboveElement = topOfElement > scrollPosition;
            var isBelowElement = scrollPosition >= bottomOfElement;

            return (!isAboveElement && !isBelowElement);
        }

        $(window).resize(function() {
            conditionallyShowNav();
            highlightActiveSection();
        });

        $(window).scroll( function () {
            conditionallyShowNav();
            highlightActiveSection();
        });

        $('ul > li').before('');
		$('blockquote p').prepend('');
		$('blockquote p').append('');
	});

    // Replace post text with font-awesome fonts
	$post.each(function () {
		var postText = $(this).html();
		var fa  = [];
		for(var i=0; i < icons.length; i++) {
			fa[i]       = {};
			fa[i].str   = "@"+ icons[i]+ "@";
			fa[i].icon  = icons[i];
			fa[i].int   = postText.search(fa[i].str);

			if(fa[i].int > -1 ) {
				fa[i].count = postText.match(new RegExp(fa[i].str,"g")).length;
				for(var j=0; j < fa[i].count; j++) {
					$(this).html($(this).html().replace(fa[i].str, ""))
				}
			}
		}
	});

}(jQuery));
<commit_msg>Restructure index.js<commit_after>"use strict";

/**
 * Main JS file for GhostScroll behaviours
 */

var $post = $('.post');
var $sitehead = $('#site-head');

/* Globals jQuery, document */
(function ($) {
	$(document).ready(initialize);
	$(window).resize(onViewportChange);
	$(window).scroll(onViewportChange);

	function initialize() {
		setupJumpHandlers();
		fontAwesomeDecorators();
		fontAwesomeReplacement();

		function setupJumpHandlers() {
                    // FitVids for responsive videos
            $('.post-content').fitVids();
                    // Arrow top in fixed menu
            $('#totop-arrow').click(function () {
            smoothScroll($sitehead);
            });
			$('.btn.first, #header-arrow').click( function () {
				var $first = $post.first();
				smoothScroll($first);
			});
			$('.btn.last').click( function () {
				var $last = $post.last();
				smoothScroll($last);
			});

			$('.fn-item').click(function (evt) {
				evt.preventDefault();
				var slug = $(this).attr("href");
				smoothScroll($(slug))
			});
		}

		function fontAwesomeDecorators() {
			$('ul > li').before('');
			$('blockquote p').prepend('');
			$('blockquote p').append('');
		}

		function fontAwesomeReplacement() {
			$post.each(function () {
				var postText = $(this).html();
				var fa = [];
				for(var i=0; i < icons.length; i++) {
					fa[i] = {};
					fa[i].str = "@"+ icons[i]+ "@";
					fa[i].icon = icons[i];
					fa[i].int = postText.search(fa[i].str);

					if(fa[i].int > -1 ) {
						fa[i].count = postText.match(new RegExp(fa[i].str,"g")).length;
						for(var j=0; j < fa[i].count; j++) {
							$(this).html(
								$(this).html().replace(
									fa[i].str,
									""
								)
							)
						}
					}
				}
			});
		}
	}

	function onViewportChange() {
		conditionallyShowNav();
		highlightActiveSection();

		function conditionallyShowNav() {
			var navOpacity = shouldDisplayNav() ? 1 : 0;
			$(".fixed-nav").css("opacity", navOpacity);

			function shouldDisplayNav() {
				var isTooNarrow = $(window).width() < 500;
				return (!isTooNarrow && !isElementInViewport($sitehead));
			}
		}

		function highlightActiveSection() {
			$(".post-holder").each(function () {
				var $this = $(this);
				var postId = $this.attr("id");
				var thisNavLink = $(".fn-item[href='#" + postId + "']");
				var previousArrow = $(this).prev('.post-holder').find('.post-after');

				if(isElementInViewport($this)) {
					thisNavLink.addClass('active');
					previousArrow.fadeOut('slow');
				} else {
					thisNavLink.removeClass('active');
					previousArrow.fadeIn('slow');
				}
			});
		}

		function isElementInViewport($element) {
			var scrollPosition = $(window).scrollTop();
			var topOfElement = $element.offset().top;
			var bottomOfElement = topOfElement + $element.height();

			var isAboveElement = topOfElement > scrollPosition;
			var isBelowElement = scrollPosition >= bottomOfElement;

			return (!isAboveElement && !isBelowElement);
		}
	}

	function smoothScroll (el) {
		$('html, body').animate({
			scrollTop: el.offset().top
		}, 400);
	}

}(jQuery));
<|endoftext|>


<commit_before>const SCROLL_Y_CONTROL = 50

$(document).ready(function(){
	$('.highlight ol li').click(function(event){
		event.preventDefault()

		var _this = $(this);
		$('html, body').stop(true).animate({
			scrollTop: $('.' + _this.text()).offset().top - SCROLL_Y_CONTROL
		}, 500);

		$('.highlight ol .highlight').removeClass('highlight')
		_this.addClass('highlight')
	})

	$('li.collection').click(function(){
		var _this = $(this);

		if (_this.attr('class').indexOf('highlight') <= -1){
			$('li.collection.highlight').removeClass('highlight')
			_this.addClass('highlight')

			$.ajax({
				url : document.URL + '/get_api_detail/' + _this.find('label a').text(),
				type : 'GET',
				success : function(data){
					json_data_convert_tag(data)
				}
			})
		}
	})

	$('.api-box .urlparameter input[type="text"]').focusout(function(){
		var _this = $(this)
		var input_index = _this.parents('.urlparameter').find('input[type="text"]').index(_this)
		var url_val = _this.parents('.group').siblings('.endpoint')
		var method_name = _this.parents('.api-box').siblings('.method-name').text()

		var split_url = url_val.text().split(method_name + '/')
		split_url[0] += method_name
		split_url[1].split('/').forEach(function(element, index){
			split_url[0] += '/' + (index == input_index ? (_this.val() != '' ? _this.val() : _this.parent().siblings('div').text()) : element)
		})

		url_val.text(split_url[0])
	})

	$('button[type="submit"]').click(function(){
		var api_parent = $(this).parents('section')
		var call_type = api_parent.find('.method').attr('data-method')

		var ajax_config = {
			type : call_type,
			url : function(){
				var url = api_parent.find('.endpoint').text().replace(/\s/g, '')

				if (call_type == 'GET'){
					$.each(api_parent.children('.parameter').children('.row'), function(index, row_val){
						$.each($(row_val).children('div'), function(div_index, div_val){
							var input_dom = $(div_val).children('input[type="text"]')
							var parameter_val = input_dom.val()
							if (parameter_val != undefined){
								url += (index ? '&' : '?') + input_dom.parent().siblings('div').text() + '=' + parameter_val
							}
						})
					})
				}

				return url
			}(),
			success : function(data){
				alert(data)
			},
			complete : function(){
				// alert(123)
			}
		}

		if (call_type != 'GET'){
			ajax_config['data'] = ajax_data_binding(api_parent, 'parameter')
			ajax_config['headers'] = ajax_data_binding(api_parent, 'header')
		}

		$.ajax(ajax_config)
	})
})

function json_data_convert_tag(controller_name, data){
	var api_data = JSON.parse(data)
	var tag_str = ''
	// api_data.item.forEach(function(element, index){
	// 	tag_str += '
' +
	// 		'
' + element.method_name + '
' +
	// 		'
Vestibulum rutrum quam vitae fringilla tincidunt. Suspendisse nec tortor urna. Ut laoreet sodales nisi, quis iaculis nulla iaculis vitae. Donec sagittis faucibus lacus eget blandit. Mauris vitae ultricies metus, at condimentum nulla.
' +
	// 		'
' +
	// 			'

' +
	// 			'
';

	// 	var api_url = ''
	// 	element.url_parameter.forEach(function(urlparameter_item, urlparameter_index){
	// 		api_url += '/{' + urlparameter_item + '}'
	// 	})

	// 	tag_str += api_data.base_url + '/' + controller_name + api_url
	// })
	console.log(tag_str)
}

function ajax_data_binding(api_parent, group_name){
	var data_str = {}
	$.each(api_parent.find('.' + group_name).children('.row'), function(index, row){
		var row_div = $(row).children('div')
		data_str[row_div.eq(0).text()] = row_div.eq(1).children('input[type="text"]').val()
	})
	return data_str
}

function parse_code_block(){
	$("pre.code-wrap").each(function(){
		if ($(this).hasClass("highlighter"))
			return;

		var data = $(this).html();

		data = _.unescape(data).trim();

		// cross-hatch
		var crosshatch = /^(#[\s]{1,}GET|POST|DELETE|UPDATE)([\s]{1,})([\S]+)([\s]{1,})([\S]+\/[\S]+)$/gm;
		data = data.replace(crosshatch, "$1$2$3$4$5");

		// spacial-charactor
		var spacialcharactor = /^(\?)([\s]{1,})([\S]+=)([\S]+)$/gm;
		data = data.replace(spacialcharactor, "$1$2$3$4");

		// header
		var header = /^(\+)([\s]{1,})([\S]+:)[\s]{1,}([\S]+)$/gm;
		data = data.replace(header, "$1$2$3$4");

		// Query Param
		var newlength = 0;
		var queryParam = /(((&){0,1}[\w]+=)([\w]+))/gm;
		while ((m = queryParam.exec(data)) !== null) {
			if (m.index === queryParam.lastIndex)
				queryParam.lastIndex ++;
			newlength += m[1].length;
		}

		if (data.length == newlength) {
			$(".response .description").html("query response");

			data = data.replace(queryParam, "$2$4");

		// JSON
		} else if (data.indexOf("<?xml") === -1 && data.indexOf("<? xml") === -1) {
			$(".response .description").html("json response");

			// brackets
			var brackets = /({|}|\(|\)|\[|\])/gm;
			data = data.replace(brackets, "$1");

			// numbers | strings
			var m;
			var lastindex = 0;
			var newdata = "";
			var numberstrings = /(("[ \t\S]+")|('[ \t\S]+')|([\d]+)){0,1}(:)([\s]{1,})((("[ \t\S]+")|('[ \t\S]+')|([\d]+))){0,1}/gm;
			while ((m = numberstrings.exec(data)) !== null) {
				if (m.index === numberstrings.lastIndex) {
			        numberstrings.lastIndex++;
			    }

			    newdata += data.substr(lastindex, m.index - lastindex);

				if (m[4])
					newdata += "" + m[1] + m[5] + "";
				else
					newdata += "" + m[1] + m[5] + "";

				newdata += m[6];

				if (m[7]) {
					if (m[11])
						newdata += "" + m[8] + "";
					else
						newdata += "" + m[8] + "";

					lastindex = m.index + m[0].length;
				} else {
					lastindex = m.index + m[0].length;
				}
			}
			data = newdata + data.substr(lastindex, data.length - lastindex)
			data = data.replace(/(,)/gm, "$1");

		// XML
		} else {
			$(".response .description").html("xml response");

			var m;
			var lastindex = 0;
			var newdata = "";
			var xml = /(<)([\/|?]{0,})([^>\s]+)(([\s]+[^>\s]+)*)(>)/gm;
			while ((m = xml.exec(data)) !== null) {
				if (m.index === xml.lastIndex) {
					xml.lastIndex++;
				}

				newdata += "" + data.substr(lastindex, m.index - lastindex) + "";

				if (m[2] === '?') {
					newdata += "" + _.escape(m[0]) + "";
				} else {
					newdata += "" + _.escape(m[1] + m[2] + m[3]) + "" + m[4].replace(/([\w]+=)(('[\w]')|("[\w]+"))/g, "$1$2") + "" + _.escape(m[6]) + "";
				}

				lastindex = m.index + m[0].length;
			}
			data = newdata + "" + data.substr(lastindex, data.length - lastindex) + "";
		}

		$(this).addClass("highlighter");
		$(this).html(data);
	});
}

<commit_msg>JSON 뷰리파이어 추가<commit_after>const SCROLL_Y_CONTROL = 50

$(document).ready(function(){
	$('.highlight ol li').click(function(event){
		event.preventDefault()

		var _this = $(this);
		$('html, body').stop(true).animate({
			scrollTop: $('.' + _this.text()).offset().top - SCROLL_Y_CONTROL
		}, 500);

		$('.highlight ol .highlight').removeClass('highlight')
		_this.addClass('highlight')
	})

	$('li.collection').click(function(){
		var _this = $(this);

		if (_this.attr('class').indexOf('highlight') <= -1){
			$('li.collection.highlight').removeClass('highlight')
			_this.addClass('highlight')

			$.ajax({
				url : document.URL + '/get_api_detail/' + _this.find('label a').text(),
				type : 'GET',
				success : function(data){
					json_data_convert_tag(data)
				}
			})
		}
	})

	$('.api-box .urlparameter input[type="text"]').focusout(function(){
		var _this = $(this)
		var input_index = _this.parents('.urlparameter').find('input[type="text"]').index(_this)
		var url_val = _this.parents('.group').siblings('.endpoint')
		var method_name = _this.parents('.api-box').siblings('.method-name').text()

		var split_url = url_val.text().split(method_name + '/')
		split_url[0] += method_name
		split_url[1].split('/').forEach(function(element, index){
			split_url[0] += '/' + (index == input_index ? (_this.val() != '' ? _this.val() : _this.parent().siblings('div').text()) : element)
		})

		url_val.text(split_url[0])
	})

	$('button[type="submit"]').click(function(){
		var api_parent = $(this).parents('section')
		var call_type = api_parent.find('.method').attr('data-method')

		var ajax_config = {
			type : call_type,
			url : function(){
				var url = api_parent.find('.endpoint').text().replace(/\s/g, '')

				if (call_type == 'GET'){
					$.each(api_parent.children('.parameter').children('.row'), function(index, row_val){
						$.each($(row_val).children('div'), function(div_index, div_val){
							var input_dom = $(div_val).children('input[type="text"]')
							var parameter_val = input_dom.val()
							if (parameter_val != undefined){
								url += (index ? '&' : '?') + input_dom.parent().siblings('div').text() + '=' + parameter_val
							}
						})
					})
				}

				return url
			}(),
			success : function(data){
				alert(data)
			},
			complete : function(){
				// alert(123)
			}
		}

		if (call_type != 'GET'){
			ajax_config['data'] = ajax_data_binding(api_parent, 'parameter')
			ajax_config['headers'] = ajax_data_binding(api_parent, 'header')
		}

		$.ajax(ajax_config)
	})
})

function json_data_convert_tag(controller_name, data){
	var api_data = JSON.parse(data)
	var tag_str = ''
	// api_data.item.forEach(function(element, index){
	// 	tag_str += '
' +
	// 		'
' + element.method_name + '
' +
	// 		'
Vestibulum rutrum quam vitae fringilla tincidunt. Suspendisse nec tortor urna. Ut laoreet sodales nisi, quis iaculis nulla iaculis vitae. Donec sagittis faucibus lacus eget blandit. Mauris vitae ultricies metus, at condimentum nulla.
' +
	// 		'
' +
	// 			'

' +
	// 			'
';

	// 	var api_url = ''
	// 	element.url_parameter.forEach(function(urlparameter_item, urlparameter_index){
	// 		api_url += '/{' + urlparameter_item + '}'
	// 	})

	// 	tag_str += api_data.base_url + '/' + controller_name + api_url
	// })
	console.log(tag_str)
}

function ajax_data_binding(api_parent, group_name){
	var data_str = {}
	$.each(api_parent.find('.' + group_name).children('.row'), function(index, row){
		var row_div = $(row).children('div')
		data_str[row_div.eq(0).text()] = row_div.eq(1).children('input[type="text"]').val()
	})
	return data_str
}

function parse_code_block(){
	$("pre.code-wrap").each(function(){
		if ($(this).hasClass("highlighter"))
			return;

		var data = $(this).html();

		data = _.unescape(data).trim();

		// cross-hatch
		var crosshatch = /^(#[\s]{1,}GET|POST|DELETE|UPDATE)([\s]{1,})([\S]+)([\s]{1,})([\S]+\/[\S]+)$/gm;
		data = data.replace(crosshatch, "$1$2$3$4$5");

		// spacial-charactor
		var spacialcharactor = /^(\?)([\s]{1,})([\S]+=)([\S]+)$/gm;
		data = data.replace(spacialcharactor, "$1$2$3$4");

		// header
		var header = /^(\+)([\s]{1,})([\S]+:)[\s]{1,}([\S]+)$/gm;
		data = data.replace(header, "$1$2$3$4");

		// Query Param
		var newlength = 0;
		var queryParam = /(((&){0,1}[\w]+=)([\w]+))/gm;
		while ((m = queryParam.exec(data)) !== null) {
			if (m.index === queryParam.lastIndex)
				queryParam.lastIndex ++;
			newlength += m[1].length;
		}

		if (data.length == newlength) {
			$(".response .description").html("query response");

			data = data.replace(queryParam, "$2$4");

		// JSON
		} else if (data.indexOf("<?xml") === -1 && data.indexOf("<? xml") === -1) {
			try {
				odata = data;
				data = JSON.stringify(JSON.parse(data), null, 4);

				$(".response .description").html("json response");

				// brackets
				var brackets = /({|}|\(|\)|\[|\])/gm;
				data = data.replace(brackets, "$1");

				// numbers | strings
				var m;
				var lastindex = 0;
				var newdata = "";
				var numberstrings = /(("[ \t\S]+")|('[ \t\S]+')|([\d]+)){0,1}(:)([\s]{1,})((("[ \t\S]+")|('[ \t\S]+')|([\d]+))){0,1}/gm;
				while ((m = numberstrings.exec(data)) !== null) {
					if (m.index === numberstrings.lastIndex) {
				        numberstrings.lastIndex++;
				    }

				    newdata += data.substr(lastindex, m.index - lastindex);

					if (m[4])
						newdata += "" + m[1] + m[5] + "";
					else
						newdata += "" + m[1] + m[5] + "";

					newdata += m[6];

					if (m[7]) {
						if (m[11])
							newdata += "" + m[8] + "";
						else
							newdata += "" + m[8] + "";

						lastindex = m.index + m[0].length;
					} else {
						lastindex = m.index + m[0].length;
					}
				}
				data = newdata + data.substr(lastindex, data.length - lastindex)
				data = data.replace(/(,)/gm, "$1");
			} catch(e) {
				data = odata;
				$(".response .description").html("response");
			}

		// XML
		} else {
			$(".response .description").html("xml response");

			var m;
			var lastindex = 0;
			var newdata = "";
			var xml = /(<)([\/|?]{0,})([^>\s]+)(([\s]+[^>\s]+)*)(>)/gm;
			while ((m = xml.exec(data)) !== null) {
				if (m.index === xml.lastIndex) {
					xml.lastIndex++;
				}

				newdata += "" + data.substr(lastindex, m.index - lastindex) + "";

				if (m[2] === '?') {
					newdata += "" + _.escape(m[0]) + "";
				} else {
					newdata += "" + _.escape(m[1] + m[2] + m[3]) + "" + m[4].replace(/([\w]+=)(('[\w]')|("[\w]+"))/g, "$1$2") + "" + _.escape(m[6]) + "";
				}

				lastindex = m.index + m[0].length;
			}
			data = newdata + "" + data.substr(lastindex, data.length - lastindex) + "";
		}

		$(this).addClass("highlighter");
		$(this).html(data);
	});
}

<|endoftext|>


<commit_before>describe('ListView rendering', function() {
  pushOptions({
    defaultView: 'listWeek',
    now: '2016-08-20'
  })

  describe('with all-day events', function() {

    describe('when single-day', function() {
      pushOptions({
        events: [
          {
            title: 'event 1',
            start: '2016-08-15'
          },
          {
            title: 'event 2',
            start: '2016-08-17'
          }
        ]
      })

      it('renders only days with events', function() {
        initCalendar()

        var days = getDayInfo()
        var events = getEventInfo()

        expect(days.length).toBe(2)
        expect(days[0].date.format()).toEqual('2016-08-15')
        expect(days[1].date.format()).toEqual('2016-08-17')

        expect(events.length).toBe(2)
        expect(events[0].title).toBe('event 1')
        expect(events[0].timeText).toBe('all-day')
        expect(events[1].title).toBe('event 2')
        expect(events[1].timeText).toBe('all-day')
      })

      it('filters events through eventRender', function() {
        var options = {}
        options.eventRender = function(event, el) {
          el.find('.fc-event-dot').replaceWith('')
        }

        initCalendar(options)

        expect($('.custom-icon').length).toBe(2)
      })
    })

    describe('when multi-day', function() {
      pushOptions({
        events: [
          {
            title: 'event 1',
            start: '2016-08-15',
            end: '2016-08-18' // 3 days
          }
        ]
      })

      it('renders all-day for every day', function() {
        initCalendar()

        var events = getEventInfo()

        expect(events.length).toBe(3)
        expect(events[0].title).toBe('event 1')
        expect(events[0].timeText).toBe('all-day')
        expect(events[1].title).toBe('event 1')
        expect(events[1].timeText).toBe('all-day')
        expect(events[2].title).toBe('event 1')
        expect(events[2].timeText).toBe('all-day')
      })
    })
  })

  describe('with timed events', function() {

    describe('when single-day', function() {
      pushOptions({
        events: [
          {
            title: 'event 1',
            start: '2016-08-15T07:00'
          },
          {
            title: 'event 2',
            start: '2016-08-17T09:00',
            end: '2016-08-17T11:00'
          }
        ]
      })

      it('renders times', function() {
        initCalendar()

        var events = getEventInfo()

        expect(events.length).toBe(2)
        expect(events[0].title).toBe('event 1')
        expect(events[0].timeText).toBe('7:00am')
        expect(events[1].title).toBe('event 2')
        expect(events[1].timeText).toBe('9:00am - 11:00am')
      })

      it('doesn\'t render times when displayEventTime is false', function() {
        var options = {}
        options.displayEventTime = false
        initCalendar(options)

        var events = getEventInfo()

        expect(events.length).toBe(2)
        expect(events[0].title).toBe('event 1')
        expect(events[0].timeText).toBe('')
        expect(events[1].title).toBe('event 2')
        expect(events[1].timeText).toBe('')
      })

      it('doesn\'t render end times when displayEventEnd is false', function() {
        var options = {}
        options.displayEventEnd = false
        initCalendar(options)

        var events = getEventInfo()

        expect(events.length).toBe(2)
        expect(events[0].title).toBe('event 1')
        expect(events[0].timeText).toBe('7:00am')
        expect(events[1].title).toBe('event 2')
        expect(events[1].timeText).toBe('9:00am')
      })

      // regression test for when localized event dates get unlocalized and leak into view rendering
      it('renders dates and times in locale', function() {
        var options = {}
        options.locale = 'fr'
        initCalendar(options)

        var days = getDayInfo()
        var events = getEventInfo()

        expect(days.length).toBe(2)
        expect(days[0].date.format()).toEqual('2016-08-15')
        expect(days[0].mainText).toEqual('lundi')
        expect(days[0].altText).toEqual('15 août 2016')
        expect(days[1].date.format()).toEqual('2016-08-17')
        expect(days[1].mainText).toEqual('mercredi')
        expect(days[1].altText).toEqual('17 août 2016')

        expect(events.length).toBe(2)
        expect(events[0].title).toBe('event 1')
        expect(events[0].timeText).toBe('07:00')
        expect(events[1].title).toBe('event 2')
        expect(events[1].timeText).toBe('09:00 - 11:00')
      })
    })

    describe('when multi-day', function() {
      pushOptions({
        nextDayThreshold: '00:00'
      })

      it('renders partial and full days', function() {
        var options = {}
        options.events = [
          {
            title: 'event 1',
            start: '2016-08-15T07:00',
            end: '2016-08-17T11:00'
          }
        ]
        initCalendar(options)

        var events = getEventInfo()

        expect(events.length).toBe(3)
        expect(events[0].title).toBe('event 1')
        expect(events[0].timeText).toBe('7:00am - 12:00am')
        expect(events[1].title).toBe('event 1')
        expect(events[1].timeText).toBe('all-day')
        expect(events[2].title).toBe('event 1')
        expect(events[2].timeText).toBe('12:00am - 11:00am')
      })

      it('truncates an out-of-range start', function() {
        var options = {}
        options.events = [
          {
            title: 'event 1',
            start: '2016-08-13T07:00',
            end: '2016-08-16T11:00'
          }
        ]
        initCalendar(options)

        var events = getEventInfo()

        expect(events.length).toBe(3)
        expect(events[0].title).toBe('event 1')
        expect(events[0].timeText).toBe('all-day')
        expect(events[1].title).toBe('event 1')
        expect(events[1].timeText).toBe('all-day')
        expect(events[2].title).toBe('event 1')
        expect(events[2].timeText).toBe('12:00am - 11:00am')
      })

      it('truncates an out-of-range start', function() {
        var options = {}
        options.events = [
          {
            title: 'event 1',
            start: '2016-08-18T07:00',
            end: '2016-08-21T11:00'
          }
        ]
        initCalendar(options)

        var events = getEventInfo()

        expect(events.length).toBe(3)
        expect(events[0].title).toBe('event 1')
        expect(events[0].timeText).toBe('7:00am - 12:00am')
        expect(events[1].title).toBe('event 1')
        expect(events[1].timeText).toBe('all-day')
        expect(events[2].title).toBe('event 1')
        expect(events[2].timeText).toBe('all-day')
      })
    })

    it('renders same days when equal to nextDayThreshold', function() {
      var options = {}
      options.nextDayThreshold = '09:00'
      options.events = [
        {
          title: 'event 1',
          start: '2016-08-15T07:00',
          end: '2016-08-17T09:00'
        }
      ]

      initCalendar(options)

      var events = getEventInfo()

      expect(events.length).toBe(3)
      expect(events[0].title).toBe('event 1')
      expect(events[0].timeText).toBe('7:00am - 12:00am')
      expect(events[1].title).toBe('event 1')
      expect(events[1].timeText).toBe('all-day')
      expect(events[2].title).toBe('event 1')
      expect(events[2].timeText).toBe('12:00am - 9:00am')
    })

    it('renders fewer days when before nextDayThreshold', function() {
      var options = {}
      options.nextDayThreshold = '09:00'
      options.events = [
        {
          title: 'event 1',
          start: '2016-08-15T07:00',
          end: '2016-08-17T08:00'
        }
      ]

      initCalendar(options)

      var events = getEventInfo()

      expect(events.length).toBe(2)
      expect(events[0].title).toBe('event 1')
      expect(events[0].timeText).toBe('7:00am - 12:00am')
      expect(events[1].title).toBe('event 1')
      expect(events[1].timeText).toBe('12:00am - 8:00am')
    })
  })

  describe('when an event has no title', function() {
    it('renders no text for its title', function() {
      var options = {}
      options.events = [
        {
          start: '2016-08-15'
        }
      ]
      initCalendar(options)

      var events = getEventInfo()

      expect(events.length).toBe(1)
      expect(events[0].title).toBe('')
      expect(events[0].timeText).toBe('all-day')
    })
  })

  describe('when no events', function() {
    it('renders an empty message', function() {
      initCalendar()
      expect(getIsEmptyMessage()).toBe(true)
    })
  })

  it('sorts events correctly', function() {
    var options = {}
    options.now = '2016-08-29'
    options.events = [
      {
        title: 'All Day Event',
        start: '2016-08-29'
      },
      {
        title: 'Long Event',
        start: '2016-08-28',
        end: '2016-09-04'
      },
      {
        title: 'Meeting',
        start: '2016-08-29T10:30:00'
      },
      {
        title: 'Lunch',
        start: '2016-08-30T12:00:00'
      },
      {
        title: 'Meeting',
        start: '2016-08-30T14:30:00'
      },
      {
        title: 'Happy Hour',
        start: '2014-11-12T17:30:00'
      },
      {
        title: 'Dinner',
        start: '2014-11-12T20:00:00'
      },
      {
        title: 'Birthday Party',
        start: '2016-08-29T07:00:00'
      },
      {
        title: 'Click for Google',
        url: 'http://google.com/',
        start: '2016-08-31'
      }
    ]

    initCalendar(options)

    var days = getDayInfo()
    var events = getEventInfo()

    expect(days.length).toBe(7)
    expect(days[0].date.format()).toEqual('2016-08-28')
    expect(days[1].date.format()).toEqual('2016-08-29')
    expect(days[2].date.format()).toEqual('2016-08-30')
    expect(days[3].date.format()).toEqual('2016-08-31')
    expect(days[4].date.format()).toEqual('2016-09-01')
    expect(days[5].date.format()).toEqual('2016-09-02')
    expect(days[6].date.format()).toEqual('2016-09-03')

    expect(events.length).toBe(13)
    expect(events[0].title).toBe('Long Event')
    expect(events[0].timeText).toBe('all-day')
    expect(events[1].title).toBe('Long Event')
    expect(events[1].timeText).toBe('all-day')
    expect(events[2].title).toBe('All Day Event')
    expect(events[2].timeText).toBe('all-day')
    expect(events[3].title).toBe('Birthday Party')
    expect(events[3].timeText).toBe('7:00am')
    expect(events[4].title).toBe('Meeting')
    expect(events[4].timeText).toBe('10:30am')
    expect(events[5].title).toBe('Long Event')
    expect(events[5].timeText).toBe('all-day')
    expect(events[6].title).toBe('Lunch')
    expect(events[6].timeText).toBe('12:00pm')
    expect(events[7].title).toBe('Meeting')
    expect(events[7].timeText).toBe('2:30pm')
    expect(events[8].title).toBe('Long Event')
    expect(events[8].timeText).toBe('all-day')
    expect(events[9].title).toBe('Click for Google')
    expect(events[9].timeText).toBe('all-day')
    expect(events[10].title).toBe('Long Event')
    expect(events[10].timeText).toBe('all-day')
    expect(events[11].title).toBe('Long Event')
    expect(events[11].timeText).toBe('all-day')
    expect(events[12].title).toBe('Long Event')
    expect(events[12].timeText).toBe('all-day')
  })

  it('updates rendered events despite fetch range being lazy', function() {
    var options = {}
    options.now = '2016-09-12'
    options.defaultView = 'month'
    options.events = [
      { title: 'event1', start: '2016-09-12' }
    ]

    initCalendar(options)
    currentCalendar.changeView('listWeek')

    expect($('.fc-list-item').length).toBe(1)

    currentCalendar.prev()

    expect($('.fc-list-item').length).toBe(0)
  })

  function getDayInfo() {
    return $('.fc-list-heading').map(function(i, el) {
      el = $(el)
      return {
        mainText: el.find('.fc-list-heading-main').text() || '',
        altText: el.find('.fc-list-heading-alt').text() || '',
        date: $.fullCalendar.moment(el.data('date'))
      }
    }).get()
  }

  function getEventInfo() { // gets all *segments*
    return $('.fc-list-item').map(function(i, el) {
      el = $(el)
      return {
        title: el.find('.fc-list-item-title').text() || '', // text!
        timeText: el.find('.fc-list-item-time').text() || '' // text!
      }
    }).get()
  }

  function getIsEmptyMessage() {
    return Boolean($('.fc-list-empty').length)
  }
})
<commit_msg>tests for list view height<commit_after>describe('ListView rendering', function() {
  pushOptions({
    defaultView: 'listWeek',
    now: '2016-08-20'
  })

  describe('with all-day events', function() {

    describe('when single-day', function() {
      pushOptions({
        events: [
          {
            title: 'event 1',
            start: '2016-08-15'
          },
          {
            title: 'event 2',
            start: '2016-08-17'
          }
        ]
      })

      it('renders only days with events', function() {
        initCalendar()

        var days = getDayInfo()
        var events = getEventInfo()

        expect(days.length).toBe(2)
        expect(days[0].date.format()).toEqual('2016-08-15')
        expect(days[1].date.format()).toEqual('2016-08-17')

        expect(events.length).toBe(2)
        expect(events[0].title).toBe('event 1')
        expect(events[0].timeText).toBe('all-day')
        expect(events[1].title).toBe('event 2')
        expect(events[1].timeText).toBe('all-day')
      })

      it('filters events through eventRender', function() {
        var options = {}
        options.eventRender = function(event, el) {
          el.find('.fc-event-dot').replaceWith('')
        }

        initCalendar(options)

        expect($('.custom-icon').length).toBe(2)
      })
    })

    describe('when multi-day', function() {
      pushOptions({
        events: [
          {
            title: 'event 1',
            start: '2016-08-15',
            end: '2016-08-18' // 3 days
          }
        ]
      })

      it('renders all-day for every day', function() {
        initCalendar()

        var events = getEventInfo()

        expect(events.length).toBe(3)
        expect(events[0].title).toBe('event 1')
        expect(events[0].timeText).toBe('all-day')
        expect(events[1].title).toBe('event 1')
        expect(events[1].timeText).toBe('all-day')
        expect(events[2].title).toBe('event 1')
        expect(events[2].timeText).toBe('all-day')
      })
    })
  })

  describe('with timed events', function() {

    describe('when single-day', function() {
      pushOptions({
        events: [
          {
            title: 'event 1',
            start: '2016-08-15T07:00'
          },
          {
            title: 'event 2',
            start: '2016-08-17T09:00',
            end: '2016-08-17T11:00'
          }
        ]
      })

      it('renders times', function() {
        initCalendar()

        var events = getEventInfo()

        expect(events.length).toBe(2)
        expect(events[0].title).toBe('event 1')
        expect(events[0].timeText).toBe('7:00am')
        expect(events[1].title).toBe('event 2')
        expect(events[1].timeText).toBe('9:00am - 11:00am')
      })

      it('doesn\'t render times when displayEventTime is false', function() {
        var options = {}
        options.displayEventTime = false
        initCalendar(options)

        var events = getEventInfo()

        expect(events.length).toBe(2)
        expect(events[0].title).toBe('event 1')
        expect(events[0].timeText).toBe('')
        expect(events[1].title).toBe('event 2')
        expect(events[1].timeText).toBe('')
      })

      it('doesn\'t render end times when displayEventEnd is false', function() {
        var options = {}
        options.displayEventEnd = false
        initCalendar(options)

        var events = getEventInfo()

        expect(events.length).toBe(2)
        expect(events[0].title).toBe('event 1')
        expect(events[0].timeText).toBe('7:00am')
        expect(events[1].title).toBe('event 2')
        expect(events[1].timeText).toBe('9:00am')
      })

      // regression test for when localized event dates get unlocalized and leak into view rendering
      it('renders dates and times in locale', function() {
        var options = {}
        options.locale = 'fr'
        initCalendar(options)

        var days = getDayInfo()
        var events = getEventInfo()

        expect(days.length).toBe(2)
        expect(days[0].date.format()).toEqual('2016-08-15')
        expect(days[0].mainText).toEqual('lundi')
        expect(days[0].altText).toEqual('15 août 2016')
        expect(days[1].date.format()).toEqual('2016-08-17')
        expect(days[1].mainText).toEqual('mercredi')
        expect(days[1].altText).toEqual('17 août 2016')

        expect(events.length).toBe(2)
        expect(events[0].title).toBe('event 1')
        expect(events[0].timeText).toBe('07:00')
        expect(events[1].title).toBe('event 2')
        expect(events[1].timeText).toBe('09:00 - 11:00')
      })
    })

    describe('when multi-day', function() {
      pushOptions({
        nextDayThreshold: '00:00'
      })

      it('renders partial and full days', function() {
        var options = {}
        options.events = [
          {
            title: 'event 1',
            start: '2016-08-15T07:00',
            end: '2016-08-17T11:00'
          }
        ]
        initCalendar(options)

        var events = getEventInfo()

        expect(events.length).toBe(3)
        expect(events[0].title).toBe('event 1')
        expect(events[0].timeText).toBe('7:00am - 12:00am')
        expect(events[1].title).toBe('event 1')
        expect(events[1].timeText).toBe('all-day')
        expect(events[2].title).toBe('event 1')
        expect(events[2].timeText).toBe('12:00am - 11:00am')
      })

      it('truncates an out-of-range start', function() {
        var options = {}
        options.events = [
          {
            title: 'event 1',
            start: '2016-08-13T07:00',
            end: '2016-08-16T11:00'
          }
        ]
        initCalendar(options)

        var events = getEventInfo()

        expect(events.length).toBe(3)
        expect(events[0].title).toBe('event 1')
        expect(events[0].timeText).toBe('all-day')
        expect(events[1].title).toBe('event 1')
        expect(events[1].timeText).toBe('all-day')
        expect(events[2].title).toBe('event 1')
        expect(events[2].timeText).toBe('12:00am - 11:00am')
      })

      it('truncates an out-of-range start', function() {
        var options = {}
        options.events = [
          {
            title: 'event 1',
            start: '2016-08-18T07:00',
            end: '2016-08-21T11:00'
          }
        ]
        initCalendar(options)

        var events = getEventInfo()

        expect(events.length).toBe(3)
        expect(events[0].title).toBe('event 1')
        expect(events[0].timeText).toBe('7:00am - 12:00am')
        expect(events[1].title).toBe('event 1')
        expect(events[1].timeText).toBe('all-day')
        expect(events[2].title).toBe('event 1')
        expect(events[2].timeText).toBe('all-day')
      })
    })

    it('renders same days when equal to nextDayThreshold', function() {
      var options = {}
      options.nextDayThreshold = '09:00'
      options.events = [
        {
          title: 'event 1',
          start: '2016-08-15T07:00',
          end: '2016-08-17T09:00'
        }
      ]

      initCalendar(options)

      var events = getEventInfo()

      expect(events.length).toBe(3)
      expect(events[0].title).toBe('event 1')
      expect(events[0].timeText).toBe('7:00am - 12:00am')
      expect(events[1].title).toBe('event 1')
      expect(events[1].timeText).toBe('all-day')
      expect(events[2].title).toBe('event 1')
      expect(events[2].timeText).toBe('12:00am - 9:00am')
    })

    it('renders fewer days when before nextDayThreshold', function() {
      var options = {}
      options.nextDayThreshold = '09:00'
      options.events = [
        {
          title: 'event 1',
          start: '2016-08-15T07:00',
          end: '2016-08-17T08:00'
        }
      ]

      initCalendar(options)

      var events = getEventInfo()

      expect(events.length).toBe(2)
      expect(events[0].title).toBe('event 1')
      expect(events[0].timeText).toBe('7:00am - 12:00am')
      expect(events[1].title).toBe('event 1')
      expect(events[1].timeText).toBe('12:00am - 8:00am')
    })
  })

  describe('when an event has no title', function() {
    it('renders no text for its title', function() {
      var options = {}
      options.events = [
        {
          start: '2016-08-15'
        }
      ]
      initCalendar(options)

      var events = getEventInfo()

      expect(events.length).toBe(1)
      expect(events[0].title).toBe('')
      expect(events[0].timeText).toBe('all-day')
    })
  })

  describe('when no events', function() {
    it('renders an empty message', function() {
      initCalendar()
      expect(getIsEmptyMessage()).toBe(true)
    })
  })

  describe('with lots of events', function() {
    pushOptions({
      now: '2016-08-29',
      events: [
        {
          title: 'All Day Event',
          start: '2016-08-29'
        },
        {
          title: 'Long Event',
          start: '2016-08-28',
          end: '2016-09-04'
        },
        {
          title: 'Meeting',
          start: '2016-08-29T10:30:00'
        },
        {
          title: 'Lunch',
          start: '2016-08-30T12:00:00'
        },
        {
          title: 'Meeting',
          start: '2016-08-30T14:30:00'
        },
        {
          title: 'Happy Hour',
          start: '2014-11-12T17:30:00'
        },
        {
          title: 'Dinner',
          start: '2014-11-12T20:00:00'
        },
        {
          title: 'Birthday Party',
          start: '2016-08-29T07:00:00'
        },
        {
          title: 'Click for Google',
          url: 'http://google.com/',
          start: '2016-08-31'
        }
      ]
    })

    it('sorts events correctly', function() {
      initCalendar()

      var days = getDayInfo()
      var events = getEventInfo()

      expect(days.length).toBe(7)
      expect(days[0].date.format()).toEqual('2016-08-28')
      expect(days[1].date.format()).toEqual('2016-08-29')
      expect(days[2].date.format()).toEqual('2016-08-30')
      expect(days[3].date.format()).toEqual('2016-08-31')
      expect(days[4].date.format()).toEqual('2016-09-01')
      expect(days[5].date.format()).toEqual('2016-09-02')
      expect(days[6].date.format()).toEqual('2016-09-03')

      expect(events.length).toBe(13)
      expect(events[0].title).toBe('Long Event')
      expect(events[0].timeText).toBe('all-day')
      expect(events[1].title).toBe('Long Event')
      expect(events[1].timeText).toBe('all-day')
      expect(events[2].title).toBe('All Day Event')
      expect(events[2].timeText).toBe('all-day')
      expect(events[3].title).toBe('Birthday Party')
      expect(events[3].timeText).toBe('7:00am')
      expect(events[4].title).toBe('Meeting')
      expect(events[4].timeText).toBe('10:30am')
      expect(events[5].title).toBe('Long Event')
      expect(events[5].timeText).toBe('all-day')
      expect(events[6].title).toBe('Lunch')
      expect(events[6].timeText).toBe('12:00pm')
      expect(events[7].title).toBe('Meeting')
      expect(events[7].timeText).toBe('2:30pm')
      expect(events[8].title).toBe('Long Event')
      expect(events[8].timeText).toBe('all-day')
      expect(events[9].title).toBe('Click for Google')
      expect(events[9].timeText).toBe('all-day')
      expect(events[10].title).toBe('Long Event')
      expect(events[10].timeText).toBe('all-day')
      expect(events[11].title).toBe('Long Event')
      expect(events[11].timeText).toBe('all-day')
      expect(events[12].title).toBe('Long Event')
      expect(events[12].timeText).toBe('all-day')
    })

    it('makes scrollbars', function() {
      let $el = $('
').appendTo('body')
      initCalendar({
        header: false
      }, $el)
      let $scrollEl = $('.fc-view .fc-scroller')
      expect(
        $scrollEl[0].scrollHeight
      ).toBeGreaterThan(
        $scrollEl[0].clientHeight + 100
      )
    })

    it('doesn\'t have scrollbars when height is \'auto\'', function() {
      let $el = $('
').appendTo('body')
      initCalendar({
        header: false,
        height: 'auto'
      }, $el)
      let $scrollEl = $('.fc-view .fc-scroller')
      expect(
        Math.abs($scrollEl[0].scrollHeight - $scrollEl[0].clientHeight)
      ).toBeLessThan(2)
    })
  })

  it('updates rendered events despite fetch range being lazy', function() {
    var options = {}
    options.now = '2016-09-12'
    options.defaultView = 'month'
    options.events = [
      { title: 'event1', start: '2016-09-12' }
    ]

    initCalendar(options)
    currentCalendar.changeView('listWeek')

    expect($('.fc-list-item').length).toBe(1)

    currentCalendar.prev()

    expect($('.fc-list-item').length).toBe(0)
  })

  function getDayInfo() {
    return $('.fc-list-heading').map(function(i, el) {
      el = $(el)
      return {
        mainText: el.find('.fc-list-heading-main').text() || '',
        altText: el.find('.fc-list-heading-alt').text() || '',
        date: $.fullCalendar.moment(el.data('date'))
      }
    }).get()
  }

  function getEventInfo() { // gets all *segments*
    return $('.fc-list-item').map(function(i, el) {
      el = $(el)
      return {
        title: el.find('.fc-list-item-title').text() || '', // text!
        timeText: el.find('.fc-list-item-time').text() || '' // text!
      }
    }).get()
  }

  function getIsEmptyMessage() {
    return Boolean($('.fc-list-empty').length)
  }
})
<|endoftext|>