<commit_before>/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
// @ts-check
'use strict';

(function () {
	// From https://remysharp.com/2010/07/21/throttling-function-calls
	function throttle(fn, threshhold, scope) {
		threshhold || (threshhold = 250);
		var last, deferTimer;
		return function () {
			var context = scope || this;

			var now = +new Date,
				args = arguments;
			if (last && now < last + threshhold) {
				// hold on to it
				clearTimeout(deferTimer);
				deferTimer = setTimeout(function () {
					last = now;
					fn.apply(context, args);
				}, threshhold + last - now);
			} else {
				last = now;
				fn.apply(context, args);
			}
		};
	}

	/**
	 * @param {string} command
	 * @param {any[]} args
	 */
	function postMessage(command, args) {
		window.parent.postMessage({
			command,
			args
		}, '*');
	}

	/**
	 * @typedef {{ element: Element, line: number }} CodeLineElement
	 */

	/**
	 * @return {CodeLineElement[]}
	 */
	const getCodeLineElements = (() => {
		/** @type {CodeLineElement[]} */
		let elements;
		return () => {
			if (!elements) {
				elements = Array.prototype.map.call(
					document.getElementsByClassName('code-line'),
					element => {
						const line = +element.getAttribute('data-line');
						return { element, line }
					})
					.filter(x => !isNaN(x.line));
			}
			return elements;
		};
	})()

	/**
	 * Find the html elements that map to a specific target line in the editor.
	 *
	 * If an exact match, returns a single element. If the line is between elements,
	 * returns the element prior to and the element after the given line.
	 *
	 * @param {number} targetLine
	 *
	 * @returns {{ previous: CodeLineElement, next?: CodeLineElement }}
	 */
	function getElementsForSourceLine(targetLine) {
		const lines = getCodeLineElements();
		let previous = lines[0] || null;
		for (const entry of lines) {
			if (entry.line === targetLine) {
				return { previous: entry, next: null };
			} else if (entry.line > targetLine) {
				return { previous, next: entry };
			}
			previous = entry;
		}
		return { previous };
	}

	/**
	 * Find the html elements that are at a specific pixel offset on the page.
	 *
	 * @returns {{ previous: CodeLineElement, next?: CodeLineElement }}
	 */
	function getLineElementsAtPageOffset(offset) {
		const lines = getCodeLineElements()

		const position = offset - window.scrollY;

		let lo = -1;
		let hi = lines.length - 1;
		while (lo + 1 < hi) {
			const mid = Math.floor((lo + hi) / 2);
			const bounds = lines[mid].element.getBoundingClientRect();
			if (bounds.top + bounds.height >= position) {
				hi = mid;
			} else {
				lo = mid;
			}
		}

		const hiElement = lines[hi];
		if (hi >= 1 && hiElement.element.getBoundingClientRect().top > position) {
			const loElement = lines[lo];
			const bounds = loElement.element.getBoundingClientRect();
			const previous = { element: loElement.element, line: loElement.line + (position - bounds.top) / (bounds.height) };
			const next = { element: hiElement.element, line: hiElement.line, fractional: 0 };
			return { previous, next };
		}

		const bounds = hiElement.element.getBoundingClientRect();
		const previous = { element: hiElement.element, line: hiElement.line + (position - bounds.top) / (bounds.height) };
		return { previous };
	}

	function getSourceRevealAddedOffset() {
		return -(window.innerHeight * 1 / 5);
	}

	/**
	 * Attempt to reveal the element for a source line in the editor.
	 *
	 * @param {number} line
	 */
	function scrollToRevealSourceLine(line) {
		const { previous, next } = getElementsForSourceLine(line);
		marker.update(previous && previous.element);
		if (previous && settings.scrollPreviewWithEditorSelection) {
			let scrollTo = 0;
			if (next) {
				// Between two elements. Go to percentage offset between them.
				const betweenProgress = (line - previous.line) / (next.line - previous.line);
				const elementOffset = next.element.getBoundingClientRect().top - previous.element.getBoundingClientRect().top;
				scrollTo = previous.element.getBoundingClientRect().top + betweenProgress * elementOffset;
			} else {
				scrollTo = previous.element.getBoundingClientRect().top;
			}
			window.scroll(0, window.scrollY + scrollTo + getSourceRevealAddedOffset());
		}
	}

	function getEditorLineNumberForPageOffset(offset) {
		const { previous, next } = getLineElementsAtPageOffset(offset);
		if (previous) {
			if (next) {
				const betweenProgress = (offset - window.scrollY - previous.element.getBoundingClientRect().top) / (next.element.getBoundingClientRect().top - previous.element.getBoundingClientRect().top);
				const line = previous.line + betweenProgress * (next.line - previous.line);
				return Math.max(line, 0);
			} else {
				return Math.max(previous.line, 0);
			}
		}
		return null;
	}

	class ActiveLineMarker {
		update(before) {
			this._unmarkActiveElement(this._current);
			this._markActiveElement(before);
			this._current = before;
		}

		_unmarkActiveElement(element) {
			if (!element) {
				return;
			}
			element.className = element.className.replace(/\bcode-active-line\b/g);
		}

		_markActiveElement(element) {
			if (!element) {
				return;
			}
			element.className += ' code-active-line';
		}
	}

	var scrollDisabled = true;
	var marker = new ActiveLineMarker();
	const settings = JSON.parse(document.getElementById('vscode-markdown-preview-data').getAttribute('data-settings'));

	function onLoad() {
		if (settings.scrollPreviewWithEditorSelection) {
			const initialLine = +settings.line;
			if (!isNaN(initialLine)) {
				setTimeout(() => {
					scrollDisabled = true;
					scrollToRevealSourceLine(initialLine);
				}, 0);
			}
		}
	}

	if (document.readyState === 'loading' || document.readyState === 'uninitialized') {
		document.addEventListener('DOMContentLoaded', onLoad);
	} else {
		onLoad();
	}

	window.addEventListener('resize', () => {
		scrollDisabled = true;
	}, true);

	window.addEventListener('message', (() => {
		const doScroll = throttle(line => {
			scrollDisabled = true;
			scrollToRevealSourceLine(line);
		}, 50);
		return event => {
			const line = +event.data.line;
			if (!isNaN(line)) {
				doScroll(line);
			}
		};
	})(), false);

	document.addEventListener('dblclick', event => {
		if (!settings.doubleClickToSwitchToEditor) {
			return;
		}

		// Ignore clicks on links
		for (let node = /** @type {HTMLElement} */(event.target); node; node = /** @type {HTMLElement} */(node.parentNode)) {
			if (node.tagName === "A") {
				return;
			}
		}

		const offset = event.pageY;
		const line = getEditorLineNumberForPageOffset(offset);
		if (!isNaN(line)) {
			postMessage('_markdown.didClick', [settings.source, line]);
		}
	});

	document.addEventListener('click', event => {
		if (!event) {
			return;
		}

		const baseElement = document.getElementsByTagName('base')[0];

		/** @type {*} */
		let node = event.target;
		while (node) {
			if (node.tagName && node.tagName.toLowerCase() === 'a' && node.href) {
				if (node.getAttribute('href').startsWith('#')) {
					break;
				}
				if (node.href.startsWith('file://')) {
					const [path, fragment] = node.href.replace(/^file:\/\//i, '').split('#');
					postMessage('_markdown.openDocumentLink', [{ path, fragment }]);
					event.preventDefault();
					event.stopPropagation();
					break;
				}
				break;
			}
			node = node.parentNode;
		}
	}, true);

	if (settings.scrollEditorWithPreview) {
		window.addEventListener('scroll', throttle(() => {
			if (scrollDisabled) {
				scrollDisabled = false;
			} else {
				const line = getEditorLineNumberForPageOffset(window.scrollY);
				if (!isNaN(line)) {
					postMessage('_markdown.revealLine', [settings.source, line]);
				}
			}
		}, 50));
	}
}());<commit_msg>Fix markdown preview links back to workspace resource<commit_after>/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
// @ts-check
'use strict';

(function () {
	// From https://remysharp.com/2010/07/21/throttling-function-calls
	function throttle(fn, threshhold, scope) {
		threshhold || (threshhold = 250);
		var last, deferTimer;
		return function () {
			var context = scope || this;

			var now = +new Date,
				args = arguments;
			if (last && now < last + threshhold) {
				// hold on to it
				clearTimeout(deferTimer);
				deferTimer = setTimeout(function () {
					last = now;
					fn.apply(context, args);
				}, threshhold + last - now);
			} else {
				last = now;
				fn.apply(context, args);
			}
		};
	}

	/**
	 * @param {string} command
	 * @param {any[]} args
	 */
	function postMessage(command, args) {
		window.parent.postMessage({
			command,
			args
		}, '*');
	}

	/**
	 * @typedef {{ element: Element, line: number }} CodeLineElement
	 */

	/**
	 * @return {CodeLineElement[]}
	 */
	const getCodeLineElements = (() => {
		/** @type {CodeLineElement[]} */
		let elements;
		return () => {
			if (!elements) {
				elements = Array.prototype.map.call(
					document.getElementsByClassName('code-line'),
					element => {
						const line = +element.getAttribute('data-line');
						return { element, line }
					})
					.filter(x => !isNaN(x.line));
			}
			return elements;
		};
	})()

	/**
	 * Find the html elements that map to a specific target line in the editor.
	 *
	 * If an exact match, returns a single element. If the line is between elements,
	 * returns the element prior to and the element after the given line.
	 *
	 * @param {number} targetLine
	 *
	 * @returns {{ previous: CodeLineElement, next?: CodeLineElement }}
	 */
	function getElementsForSourceLine(targetLine) {
		const lines = getCodeLineElements();
		let previous = lines[0] || null;
		for (const entry of lines) {
			if (entry.line === targetLine) {
				return { previous: entry, next: null };
			} else if (entry.line > targetLine) {
				return { previous, next: entry };
			}
			previous = entry;
		}
		return { previous };
	}

	/**
	 * Find the html elements that are at a specific pixel offset on the page.
	 *
	 * @returns {{ previous: CodeLineElement, next?: CodeLineElement }}
	 */
	function getLineElementsAtPageOffset(offset) {
		const lines = getCodeLineElements()

		const position = offset - window.scrollY;

		let lo = -1;
		let hi = lines.length - 1;
		while (lo + 1 < hi) {
			const mid = Math.floor((lo + hi) / 2);
			const bounds = lines[mid].element.getBoundingClientRect();
			if (bounds.top + bounds.height >= position) {
				hi = mid;
			} else {
				lo = mid;
			}
		}

		const hiElement = lines[hi];
		if (hi >= 1 && hiElement.element.getBoundingClientRect().top > position) {
			const loElement = lines[lo];
			const bounds = loElement.element.getBoundingClientRect();
			const previous = { element: loElement.element, line: loElement.line + (position - bounds.top) / (bounds.height) };
			const next = { element: hiElement.element, line: hiElement.line, fractional: 0 };
			return { previous, next };
		}

		const bounds = hiElement.element.getBoundingClientRect();
		const previous = { element: hiElement.element, line: hiElement.line + (position - bounds.top) / (bounds.height) };
		return { previous };
	}

	function getSourceRevealAddedOffset() {
		return -(window.innerHeight * 1 / 5);
	}

	/**
	 * Attempt to reveal the element for a source line in the editor.
	 *
	 * @param {number} line
	 */
	function scrollToRevealSourceLine(line) {
		const { previous, next } = getElementsForSourceLine(line);
		marker.update(previous && previous.element);
		if (previous && settings.scrollPreviewWithEditorSelection) {
			let scrollTo = 0;
			if (next) {
				// Between two elements. Go to percentage offset between them.
				const betweenProgress = (line - previous.line) / (next.line - previous.line);
				const elementOffset = next.element.getBoundingClientRect().top - previous.element.getBoundingClientRect().top;
				scrollTo = previous.element.getBoundingClientRect().top + betweenProgress * elementOffset;
			} else {
				scrollTo = previous.element.getBoundingClientRect().top;
			}
			window.scroll(0, window.scrollY + scrollTo + getSourceRevealAddedOffset());
		}
	}

	function getEditorLineNumberForPageOffset(offset) {
		const { previous, next } = getLineElementsAtPageOffset(offset);
		if (previous) {
			if (next) {
				const betweenProgress = (offset - window.scrollY - previous.element.getBoundingClientRect().top) / (next.element.getBoundingClientRect().top - previous.element.getBoundingClientRect().top);
				const line = previous.line + betweenProgress * (next.line - previous.line);
				return Math.max(line, 0);
			} else {
				return Math.max(previous.line, 0);
			}
		}
		return null;
	}

	class ActiveLineMarker {
		update(before) {
			this._unmarkActiveElement(this._current);
			this._markActiveElement(before);
			this._current = before;
		}

		_unmarkActiveElement(element) {
			if (!element) {
				return;
			}
			element.className = element.className.replace(/\bcode-active-line\b/g);
		}

		_markActiveElement(element) {
			if (!element) {
				return;
			}
			element.className += ' code-active-line';
		}
	}

	var scrollDisabled = true;
	var marker = new ActiveLineMarker();
	const settings = JSON.parse(document.getElementById('vscode-markdown-preview-data').getAttribute('data-settings'));

	function onLoad() {
		if (settings.scrollPreviewWithEditorSelection) {
			const initialLine = +settings.line;
			if (!isNaN(initialLine)) {
				setTimeout(() => {
					scrollDisabled = true;
					scrollToRevealSourceLine(initialLine);
				}, 0);
			}
		}
	}

	if (document.readyState === 'loading' || document.readyState === 'uninitialized') {
		document.addEventListener('DOMContentLoaded', onLoad);
	} else {
		onLoad();
	}

	window.addEventListener('resize', () => {
		scrollDisabled = true;
	}, true);

	window.addEventListener('message', (() => {
		const doScroll = throttle(line => {
			scrollDisabled = true;
			scrollToRevealSourceLine(line);
		}, 50);
		return event => {
			const line = +event.data.line;
			if (!isNaN(line)) {
				doScroll(line);
			}
		};
	})(), false);

	document.addEventListener('dblclick', event => {
		if (!settings.doubleClickToSwitchToEditor) {
			return;
		}

		// Ignore clicks on links
		for (let node = /** @type {HTMLElement} */(event.target); node; node = /** @type {HTMLElement} */(node.parentNode)) {
			if (node.tagName === "A") {
				return;
			}
		}

		const offset = event.pageY;
		const line = getEditorLineNumberForPageOffset(offset);
		if (!isNaN(line)) {
			postMessage('_markdown.didClick', [settings.source, line]);
		}
	});

	document.addEventListener('click', event => {
		if (!event) {
			return;
		}

		const baseElement = document.getElementsByTagName('base')[0];

		/** @type {*} */
		let node = event.target;
		while (node) {
			if (node.tagName && node.tagName.toLowerCase() === 'a' && node.href) {
				if (node.getAttribute('href').startsWith('#')) {
					break;
				}
				if (node.href.startsWith('file://') || node.href.startsWith('vscode-workspace-resource:')) {
					const [path, fragment] = node.href.replace(/^(file:\/\/|vscode-workspace-resource:)/i, '').split('#');
					postMessage('_markdown.openDocumentLink', [{ path, fragment }]);
					event.preventDefault();
					event.stopPropagation();
					break;
				}
				break;
			}
			node = node.parentNode;
		}
	}, true);

	if (settings.scrollEditorWithPreview) {
		window.addEventListener('scroll', throttle(() => {
			if (scrollDisabled) {
				scrollDisabled = false;
			} else {
				const line = getEditorLineNumberForPageOffset(window.scrollY);
				if (!isNaN(line)) {
					postMessage('_markdown.revealLine', [settings.source, line]);
				}
			}
		}, 50));
	}
}());<|endoftext|>


<commit_before>var g_AWSRegions =[
  'us-east-1',
  'us-west-1',
  'us-west-2',
  'eu-west-1',
  'eu-central-1',
  'ap-southeast-1',
  'ap-southeast-2',
  'ap-northeast-1',
  'sa-east-1'
];
var g_EC2Data = [];
var g_EC2DataTimer = null;

function resetAWSValues() {
  g_EC2Data = [];
  clearInterval(g_EC2DataTimer);
  g_EC2DataTimer = null;
}

function queryAllAWSRegionsForEC2Data(key, secret) {
  resetEc2DataTable()
  resetAWSValues();
  for(var i = 0; i < g_AWSRegions.length; i++) {
    queryAWS(g_AWSRegions[i], key, secret);
  }
  // Because of the asynchronous nature of the AWS SDK calls, we need to
  // wait until all data is returned for all regions before we proceed
  g_EC2DataTimer = setInterval(waitForEC2ToGetReturned, 1000);
}

function waitForEC2ToGetReturned() {
  if( g_EC2Data.length == g_AWSRegions.length ) {
    clearInterval(g_EC2DataTimer);
    displayEc2DataTable(g_EC2Data);
  }
}

function queryAWS(region, key, secret) {
  var ec2 = new AWS.EC2(
    {
      accessKeyId: key,
      secretAccessKey: secret,
      region: region,
      maxRetries: 5
    }
  );
  var params = {
    Filters: [
      { // only find running instances
        Name: 'instance-state-name',
        Values: [ 'running' ]
      },
    ],
    MaxResults: 1000 // max
  };
  ec2.describeInstances(params, function(err, data) {
    if (err) {
      console.log(err, err.stack);
      resultsDiv.innerHTML = "The following error has occured: " +
        err + "; see the javascript console for more details.";
    } else {
      //console.log(data);
      queryAWSReturn( data, region );
    }
  });
}

function queryAWSReturn(regionData, region) {
  g_EC2Data.push(
    {
      "region": region,
      "data": mungeEc2Data(regionData)
    }
  );
}

function mungeEc2Data(data) {
  var mungedDataArr = [];
  if( !data || !data.Reservations || data.Reservations.length == 0 ) {
    return mungedDataArr;
  }
  var dataLen = data.Reservations.length;
  for(var i=0; i < dataLen; i++) {
    var tags = data.Reservations[i].Instances[0].Tags;
    var name = "";
    if(tags.length > 1) {
      var tagLen = tags.length;
      for(var y=0; y < tagLen; y++) {
        if(tags[y].Key.toLowerCase() == "aws:autoscaling:groupName".toLowerCase() && name == "") {
          name = tags[y].Value;
        }
        if(tags[y].Key.toLowerCase() == "name") {
          name = tags[y].Value;
        }
      }
    } else {
      if(tags.length == 1) {
        name = tags[0].Value;
      } else {
        console.log("No name tag found for instance with id: " + data.Reservations[i].Instances[0].InstanceId)
      }
    }
    mungedDataArr[i]["name"] = name;
    mungedDataArr[i]["id"] = data.Reservations[i].Instances[0].InstanceId;
    mungedDataArr[i]["type"] = data.Reservations[i].Instances[0].InstanceType;
    mungedDataArr[i]["region"] = region;
  }
  return mungedDataArr;
}
<commit_msg>fix array bug<commit_after>var g_AWSRegions =[
  'us-east-1',
  'us-west-1',
  'us-west-2',
  'eu-west-1',
  'eu-central-1',
  'ap-southeast-1',
  'ap-southeast-2',
  'ap-northeast-1',
  'sa-east-1'
];
var g_EC2Data = [];
var g_EC2DataTimer = null;

function resetAWSValues() {
  g_EC2Data = [];
  clearInterval(g_EC2DataTimer);
  g_EC2DataTimer = null;
}

function queryAllAWSRegionsForEC2Data(key, secret) {
  resetEc2DataTable()
  resetAWSValues();
  for(var i = 0; i < g_AWSRegions.length; i++) {
    queryAWS(g_AWSRegions[i], key, secret);
  }
  // Because of the asynchronous nature of the AWS SDK calls, we need to
  // wait until all data is returned for all regions before we proceed
  g_EC2DataTimer = setInterval(waitForEC2ToGetReturned, 1000);
}

function waitForEC2ToGetReturned() {
  if( g_EC2Data.length == g_AWSRegions.length ) {
    clearInterval(g_EC2DataTimer);
    displayEc2DataTable(g_EC2Data);
  }
}

function queryAWS(region, key, secret) {
  var ec2 = new AWS.EC2(
    {
      accessKeyId: key,
      secretAccessKey: secret,
      region: region,
      maxRetries: 5
    }
  );
  var params = {
    Filters: [
      { // only find running instances
        Name: 'instance-state-name',
        Values: [ 'running' ]
      },
    ],
    MaxResults: 1000 // max
  };
  ec2.describeInstances(params, function(err, data) {
    if (err) {
      console.log(err, err.stack);
      resultsDiv.innerHTML = "The following error has occured: " +
        err + "; see the javascript console for more details.";
    } else {
      //console.log(data);
      queryAWSReturn( data, region );
    }
  });
}

function queryAWSReturn(regionData, region) {
  g_EC2Data.push(
    {
      "region": region,
      "data": mungeEc2Data(regionData)
    }
  );
}

function mungeEc2Data(data) {
  var mungedDataArr = [];
  if( !data || !data.Reservations || data.Reservations.length == 0 ) {
    return mungedDataArr;
  }
  var dataLen = data.Reservations.length;
  for(var i=0; i < dataLen; i++) {
    var tags = data.Reservations[i].Instances[0].Tags;
    var name = "";
    if(tags.length > 1) {
      var tagLen = tags.length;
      for(var y=0; y < tagLen; y++) {
        if(tags[y].Key.toLowerCase() == "aws:autoscaling:groupName".toLowerCase() && name == "") {
          name = tags[y].Value;
        }
        if(tags[y].Key.toLowerCase() == "name") {
          name = tags[y].Value;
        }
      }
    } else {
      if(tags.length == 1) {
        name = tags[0].Value;
      } else {
        console.log("No name tag found for instance with id: " + data.Reservations[i].Instances[0].InstanceId)
      }
    }
    mungedDataArr[i] = {};
    mungedDataArr[i]["name"] = name;
    mungedDataArr[i]["id"] = data.Reservations[i].Instances[0].InstanceId;
    mungedDataArr[i]["type"] = data.Reservations[i].Instances[0].InstanceType;
    mungedDataArr[i]["region"] = region;
  }
  return mungedDataArr;
}
<|endoftext|>


<commit_before>/**
 * Brackets Themes Copyright (c) 2014 Miguel Castillo.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */
/*global $, define, require */

define(function (require, exports, module) {
    "use strict";

    var currentDocMode, currentThemes = [];

    var _                  = require("thirdparty/lodash"),
        CodeMirror         = require("thirdparty/CodeMirror2/lib/codemirror"),
        PreferencesManager = require("preferences/PreferencesManager"),
        prefs              = PreferencesManager.getExtensionPrefs("themes");

    var $scrollbars = $("<style id='scrollbars'>").appendTo("head");

    /**
     * Load scrollbar styling based on whether or not theme scrollbars are enabled.
     *
     * @param {ThemeManager.Theme} theme Is the theme object with the corresponding scrollbar style
     *   to be updated
     */
    function updateScrollbars(theme) {
        theme = theme || {};
        if (prefs.get("themeScrollbars")) {
            var scrollbar = (theme.scrollbar || []).join(" ");
            $scrollbars.text(scrollbar || "");
        } else {
            $scrollbars.text("");
        }
    }

    /**
     *  Handles updating codemirror with the current selection of themes.
     *
     * @param {CodeMirror} cm is the CodeMirror instance currently loaded
     */
    function updateThemes(cm) {
        var newTheme = prefs.get("theme"),
            cmTheme  = (cm.getOption("theme") || "").replace(/[\s]*/, ""); // Normalize themes string

        // Check if the editor already has the theme applied...
        if (cmTheme === newTheme) {
            return;
        }

        // Setup current and further documents to get the new theme...
        CodeMirror.defaults.theme = newTheme;
        cm.setOption("theme", newTheme);
    }

    /**
     * Sets the document type in the DOM to enable styling per doc type
     *
     * @param {CodeMirror} cm is the CodeMirror instance currently loaded in the editor
     * @return {string} current document type
     */
    function setDocumentMode(cm) {
        var mode = cm.getDoc().getMode();
        var docMode = mode && (mode.helperType || mode.name);
        $("#editor-holder .CodeMirror").removeClass("doctype-" + currentDocMode).addClass("doctype-" + docMode);
        currentDocMode = docMode; // Update docMode
        return docMode;
    }

    exports.updateScrollbars = updateScrollbars;
    exports.updateThemes     = updateThemes;
    exports.setDocumentMode  = setDocumentMode;
});
<commit_msg>Removes the `doctype-` class from the editor (#8579)<commit_after>/**
 * Brackets Themes Copyright (c) 2014 Miguel Castillo.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */
/*global $, define, require */

define(function (require, exports, module) {
    "use strict";

    var currentDocMode, currentThemes = [];

    var _                  = require("thirdparty/lodash"),
        CodeMirror         = require("thirdparty/CodeMirror2/lib/codemirror"),
        PreferencesManager = require("preferences/PreferencesManager"),
        prefs              = PreferencesManager.getExtensionPrefs("themes");

    var $scrollbars = $("<style id='scrollbars'>").appendTo("head");

    /**
     * Load scrollbar styling based on whether or not theme scrollbars are enabled.
     *
     * @param {ThemeManager.Theme} theme Is the theme object with the corresponding scrollbar style
     *   to be updated
     */
    function updateScrollbars(theme) {
        theme = theme || {};
        if (prefs.get("themeScrollbars")) {
            var scrollbar = (theme.scrollbar || []).join(" ");
            $scrollbars.text(scrollbar || "");
        } else {
            $scrollbars.text("");
        }
    }

    /**
     *  Handles updating codemirror with the current selection of themes.
     *
     * @param {CodeMirror} cm is the CodeMirror instance currently loaded
     */
    function updateThemes(cm) {
        var newTheme = prefs.get("theme"),
            cmTheme  = (cm.getOption("theme") || "").replace(/[\s]*/, ""); // Normalize themes string

        // Check if the editor already has the theme applied...
        if (cmTheme === newTheme) {
            return;
        }

        // Setup current and further documents to get the new theme...
        CodeMirror.defaults.theme = newTheme;
        cm.setOption("theme", newTheme);
    }

    /**
     * Sets the document type in the DOM to enable styling per doc type
     *
     * @param {CodeMirror} cm is the CodeMirror instance currently loaded in the editor
     * @return {string} current document type
     */
    function setDocumentMode(cm) {
        var mode = cm.getDoc().getMode();
        var docMode = mode && (mode.helperType || mode.name);
        currentDocMode = docMode; // Update docMode
        return docMode;
    }

    exports.updateScrollbars = updateScrollbars;
    exports.updateThemes     = updateThemes;
    exports.setDocumentMode  = setDocumentMode;
});
<|endoftext|>


<commit_before>/*
 * CMS.js v1.0.0
 * Copyright 2015 Chris Diana
 * www.cdmedia.github.io/cms.js
 * Free to use under the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
 */

var CMS = {

	settings: {
		siteName: 'CMS.js',
		siteTagline: 'Your site tagline',
		siteEmail: 'your_email@example.com',
		siteAuthor: 'Your Name',
		siteUrl: '',
		siteNavItems: [
			{ name: 'Github', href: '#', newWindow: false},
			{ name: 'About' }
		],
		pagination: 3,
		postsFolder: 'posts',
		postSnippetLength: 120,
		pagesFolder: 'pages',
		fadeSpeed: 300,
		mainContainer: $('.cms_main'),
		footerContainer: $('.cms_footer'),
		footerText: '© ' + new Date().getFullYear() + ' All Rights Reserved.',
		parseSeperator: '---',
		loader: '
Loading...
',
		get siteAttributes() {
			return [
				{ attr: 'title', value: CMS.settings.siteName },
				{ attr: '.cms_sitename', value: CMS.settings.siteName},
				{ attr: '.cms_tagline', value: CMS.settings.siteTagline},
				{ attr: '.cms_footer_text', value: CMS.settings.footerText}
			];
		},
		mode: 'Github',
		githubUserSettings: {
			username: 'yourusername',
			repo: 'yourrepo',
		},
		githubSettings: {
			branch: 'gh-pages',
			host: 'https://api.github.com'
		}
	},

	posts: [],
	pages: [],
	loaded: {},

	extend: function (target, opts, callback) {
		var next;
		if (typeof opts === "undefined") {
			opts = target;
			target = CMS;
		}
		for (next in opts) {
			if (Object.prototype.hasOwnProperty.call(opts, next)) {
				target[next] = opts[next];
			}
		}
		callback(); // check user config options
		return target;
	},

	render: function (url) {
		CMS.settings.mainContainer.html('').fadeOut(CMS.settings.fadeSpeed);
		CMS.settings.footerContainer.hide();

		var type = url.split('/')[0];
		var map = {

			// Main view
			'' : function () {
				CMS.renderPosts();
			},

			// Post view
			'#post' : function() {
				var id = url.split('#post/')[1].trim();
				CMS.renderPost(id);
			},

			// Post view
			'#page' : function() {
				var title = url.split('#page/')[1].trim();
				CMS.renderPage(title);
			}

		};

		if (map[type]) {
			map[type]();
		} else {
			var errorMsg = 'Error loading page.';
			CMS.renderError(errorMsg);
		}
	},

        renderPage: function(title) {
	        CMS.pages.sort(function(a,b) {return a.date - b.date});
		CMS.pages.forEach(function(page){
			if(page.title == title) {

				var tpl = $('#page-template').html(),
					$tpl = $(tpl);

				$tpl.find('.page-title').html(page.title);
				$tpl.find('.page-content').html(page.contentData);

				CMS.settings.mainContainer.html($tpl).hide().fadeIn(CMS.settings.fadeSpeed);
			}
		});
		CMS.renderFooter();
	},

	renderPost: function(id) {
		CMS.posts.forEach(function(post){
			if(post.id == id) {

				var tpl = $('#post-template').html(),
					$tpl = $(tpl);

				$tpl.find('.post-title').html(post.title);
				$tpl.find('.post-date').html((post.date.getMonth() + 1) + '/' + post.date.getDate() + '/' +  post.date.getFullYear());
				$tpl.find('.post-content').html(post.contentData);

				CMS.settings.mainContainer.html($tpl).hide().fadeIn(CMS.settings.fadeSpeed);
			}
		});
		CMS.renderFooter();
	},

        renderPosts: function() {
	        CMS.posts.sort(function(a,b) {return a.date - b.date});
		CMS.posts.forEach(function(post){
			var tpl = $('#post-template').html(),
				$tpl = $(tpl);

			var title = '' + post.title + '',
				date = (post.date.getMonth() + 1) + '/' + post.date.getDate() + '/' +  post.date.getFullYear(),
				snippet = post.contentData.split('.')[0] + '.';

			var postLink = $tpl.find('.post-title'),
				postDate = $tpl.find('.post-date'),
				postSnippet = $tpl.find('.post-content');

			postLink.on('click', function (e) {
				e.preventDefault();
				window.location.hash = 'post/' + post.id;
			});

			postLink.html(title);
			postSnippet.html(snippet);
			postDate.html(date);
			CMS.settings.mainContainer.append($tpl).hide().fadeIn(CMS.settings.fadeSpeed);
		});
		CMS.renderFooter();
	},

	renderFooter: function() {
		// Load footer later so things dont look weird loading ajax stuff
		setTimeout(function () {
			CMS.settings.footerContainer.fadeIn(CMS.settings.fadeSpeed);
		}, 800);
	},

	renderError: function(msg) {
		var tpl = $('#error-template').html(),
			$tpl = $(tpl);

		$tpl.find('.error_text').html(msg);

		CMS.settings.mainContainer.html('').fadeOut(CMS.settings.fadeSpeed, function(){
			CMS.settings.mainContainer.html($tpl).fadeIn(CMS.settings.fadeSpeed);
		});
	},

	contentLoaded: function(type) {

		CMS.loaded[type] = true;

		if(CMS.loaded.page && CMS.loaded.post) {

			// Set navigation
			this.setNavigation();

	        // Manually trigger on initial load
			$(window).trigger('hashchange');
		}
	},

	parseContent: function(content, type, file, counter, numFiles) {

		var data = content.split(CMS.settings.parseSeperator),
			contentObj = {},
			id = counter,
			date = file.date;

		contentObj.id = id;
		contentObj.date = date;

		// Get content info
		var infoData = data[1].split(/[\n\r]+/);

		$.each(infoData, function(k, v) {
			if(v.length) {
				v.replace(/^\s+|\s+$/g, '').trim();
				var i = v.split(':');
				var val = i[1];
				k = i[0];
				contentObj[k] = val.trim();
			}
		});

		// Drop stuff we dont need
		data.splice(0,2);

		// Put everything back together if broken
		var contentData = data.join();
		contentObj.contentData = marked(contentData);

		if(type == 'post') {
			CMS.posts.push(contentObj);
		} else if (type == 'page') {
			CMS.pages.push(contentObj);
		}

		// Execute after all content is loaded
		if(counter === numFiles) {
			CMS.contentLoaded(type);
		}
	},

	getContent: function(type, file, counter, numFiles) {

		var urlFolder = '';

		switch(type) {
			case 'post':
				urlFolder = CMS.settings.postsFolder;
				break;
			case 'page':
				urlFolder = CMS.settings.pagesFolder;
				break;
		}

		if(CMS.settings.mode == 'Github') {
			url = file.link;
		} else {
			url = urlFolder + '/' + file.name;
		}

		$.ajax({
			type: 'GET',
			url: url,
			dataType: 'html',
			success: function(content) {
				CMS.parseContent(content, type, file, counter, numFiles);
			},
			error: function() {
				var errorMsg = 'Error loading ' + type + ' content';
				CMS.renderError(errorMsg);
			}
		});
	},

	getFiles: function(type) {

		var folder = '',
			url = '';

		switch(type) {
			case 'post':
				folder = CMS.settings.postsFolder;
				break;
			case 'page':
				folder = CMS.settings.pagesFolder;
				break;
		}

		if(CMS.settings.mode == 'Github') {
			var gus = CMS.settings.githubUserSettings,
				gs = CMS.settings.githubSettings;
			url = gs.host + '/repos/' + gus.username + '/' + gus.repo + '/contents/' + folder + '?ref=' + gs.branch;
		} else {
			url = folder;
		}

		$.ajax({
			url: url,
			success: function(data) {

				var files = [],
					linkFiles;

				if(CMS.settings.mode == 'Github') {
					linkFiles = data;
				} else {
					linkFiles = $(data).find("a");
				}

				$(linkFiles).each(function(k, f) {

					var filename,
						downloadLink;

					if(CMS.settings.mode == 'Github') {
						filename = f.name;
						downloadLink = f.download_url;
					} else {
						filename = $(f).attr("href");
					}

					if(filename.endsWith('.md')) {
						var file = {};
						file.date = new Date(filename.substring(0, 10));
						file.name = filename;
						if(downloadLink) {
							file.link = downloadLink;
						}
						files.push(file);
					}

				});

				var counter = 0,
					numFiles = files.length;

				if(files.length > 0) {
					$(files).each(function(k, file) {
						counter++;
						CMS.getContent(type, file, counter, numFiles);
					});
				} else {
					var errorMsg = 'Error loading ' + type + 's in directory. Make sure ' +
						'there are Markdown ' + type + 's in the ' + type + 's folder.';
					CMS.renderError(errorMsg);
				}
			},
			error: function() {
				var errorMsg;
				if(CMS.settings.mode == 'Github') {
					errorMsg = 'Error loading ' + type + 's directory. Make sure ' +
						'your Github settings are correctly set in your config.js file.';
				} else {
					errorMsg = 'Error loading ' + type + 's directory. Make sure ' +
						type + 's directory is set correctly in config and .htaccess is in ' +
						type + 's directory with Apache "Options Indexes" set on.';
				}
				CMS.renderError(errorMsg);
			}
		});
	},

	setNavigation: function() {

		var nav = '
';
		CMS.settings.siteNavItems.forEach(function(navItem) {
			if(navItem.hasOwnProperty('href')) {
				nav += '
' + navItem.name + '
';
			} else {
				CMS.pages.forEach(function(page) {
					if(navItem.name == page.title) {
						nav += '
' + navItem.name + '
';
					}
				});
			}
		});
		nav += '
';

		$('.cms_nav').html(nav).hide().fadeIn(CMS.settings.fadeSpeed);

		// Set onclicks for nav links
		$.each($('.cms_nav_link'), function(k, link) {
			var title =  $(this).attr("id");
			$(this).on('click', function (e) {
				e.preventDefault();
				window.location.hash = 'page/' + title;
			});

		});
	},

	setSiteAttributes: function() {
		CMS.settings.siteAttributes.forEach(function(attribute) {

			var value;

			// Set brand
			if(attribute.attr == '.cms_sitename') {
				if (attribute.value.match(/\.(jpeg|jpg|gif|png)$/)) {
		            value = '';
		        } else {
		            value = attribute.value;
		        }
			} else {
				value = attribute.value;
			}
			$(attribute.attr).html(value).hide().fadeIn(CMS.settings.fadeSpeed);
		});
	},

	generateSite: function() {

		this.setSiteAttributes();

		var types = ['post', 'page'];

		types.forEach(function(type){
			CMS.getFiles(type);
		});

		// Check for hash changes
        $(window).on('hashchange', function () {
            CMS.render(window.location.hash);
        });
	},

	init: function (options) {
		if ($.isPlainObject(options)) {
			return this.extend(this.settings, options, function () {
				CMS.generateSite();
			});
		}
	}

};
<commit_msg>fixed: if infoData has config like ‘date : 2016-01-20 14:42’<commit_after>/*
 * CMS.js v1.0.0
 * Copyright 2015 Chris Diana
 * www.cdmedia.github.io/cms.js
 * Free to use under the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
 */

var CMS = {

	settings: {
		siteName: 'CMS.js',
		siteTagline: 'Your site tagline',
		siteEmail: 'your_email@example.com',
		siteAuthor: 'Your Name',
		siteUrl: '',
		siteNavItems: [
			{ name: 'Github', href: '#', newWindow: false},
			{ name: 'About' }
		],
		pagination: 3,
		postsFolder: 'posts',
		postSnippetLength: 120,
		pagesFolder: 'pages',
		fadeSpeed: 300,
		mainContainer: $('.cms_main'),
		footerContainer: $('.cms_footer'),
		footerText: '© ' + new Date().getFullYear() + ' All Rights Reserved.',
		parseSeperator: '---',
		loader: '
Loading...
',
		get siteAttributes() {
			return [
				{ attr: 'title', value: CMS.settings.siteName },
				{ attr: '.cms_sitename', value: CMS.settings.siteName},
				{ attr: '.cms_tagline', value: CMS.settings.siteTagline},
				{ attr: '.cms_footer_text', value: CMS.settings.footerText}
			];
		},
		mode: 'Github',
		githubUserSettings: {
			username: 'yourusername',
			repo: 'yourrepo',
		},
		githubSettings: {
			branch: 'gh-pages',
			host: 'https://api.github.com'
		}
	},

	posts: [],
	pages: [],
	loaded: {},

	extend: function (target, opts, callback) {
		var next;
		if (typeof opts === "undefined") {
			opts = target;
			target = CMS;
		}
		for (next in opts) {
			if (Object.prototype.hasOwnProperty.call(opts, next)) {
				target[next] = opts[next];
			}
		}
		callback(); // check user config options
		return target;
	},

	render: function (url) {
		CMS.settings.mainContainer.html('').fadeOut(CMS.settings.fadeSpeed);
		CMS.settings.footerContainer.hide();

		var type = url.split('/')[0];
		var map = {

			// Main view
			'' : function () {
				CMS.renderPosts();
			},

			// Post view
			'#post' : function() {
				var id = url.split('#post/')[1].trim();
				CMS.renderPost(id);
			},

			// Post view
			'#page' : function() {
				var title = url.split('#page/')[1].trim();
				CMS.renderPage(title);
			}

		};

		if (map[type]) {
			map[type]();
		} else {
			var errorMsg = 'Error loading page.';
			CMS.renderError(errorMsg);
		}
	},

        renderPage: function(title) {
	        CMS.pages.sort(function(a,b) {return a.date - b.date});
		CMS.pages.forEach(function(page){
			if(page.title == title) {

				var tpl = $('#page-template').html(),
					$tpl = $(tpl);

				$tpl.find('.page-title').html(page.title);
				$tpl.find('.page-content').html(page.contentData);

				CMS.settings.mainContainer.html($tpl).hide().fadeIn(CMS.settings.fadeSpeed);
			}
		});
		CMS.renderFooter();
	},

	renderPost: function(id) {
		CMS.posts.forEach(function(post){
			if(post.id == id) {

				var tpl = $('#post-template').html(),
					$tpl = $(tpl);

				$tpl.find('.post-title').html(post.title);
				$tpl.find('.post-date').html((post.date.getMonth() + 1) + '/' + post.date.getDate() + '/' +  post.date.getFullYear());
				$tpl.find('.post-content').html(post.contentData);

				CMS.settings.mainContainer.html($tpl).hide().fadeIn(CMS.settings.fadeSpeed);
			}
		});
		CMS.renderFooter();
	},

        renderPosts: function() {
	        CMS.posts.sort(function(a,b) {return a.date - b.date});
		CMS.posts.forEach(function(post){
			var tpl = $('#post-template').html(),
				$tpl = $(tpl);

			var title = '' + post.title + '',
				date = (post.date.getMonth() + 1) + '/' + post.date.getDate() + '/' +  post.date.getFullYear(),
				snippet = post.contentData.split('.')[0] + '.';

			var postLink = $tpl.find('.post-title'),
				postDate = $tpl.find('.post-date'),
				postSnippet = $tpl.find('.post-content');

			postLink.on('click', function (e) {
				e.preventDefault();
				window.location.hash = 'post/' + post.id;
			});

			postLink.html(title);
			postSnippet.html(snippet);
			postDate.html(date);
			CMS.settings.mainContainer.append($tpl).hide().fadeIn(CMS.settings.fadeSpeed);
		});
		CMS.renderFooter();
	},

	renderFooter: function() {
		// Load footer later so things dont look weird loading ajax stuff
		setTimeout(function () {
			CMS.settings.footerContainer.fadeIn(CMS.settings.fadeSpeed);
		}, 800);
	},

	renderError: function(msg) {
		var tpl = $('#error-template').html(),
			$tpl = $(tpl);

		$tpl.find('.error_text').html(msg);

		CMS.settings.mainContainer.html('').fadeOut(CMS.settings.fadeSpeed, function(){
			CMS.settings.mainContainer.html($tpl).fadeIn(CMS.settings.fadeSpeed);
		});
	},

	contentLoaded: function(type) {

		CMS.loaded[type] = true;

		if(CMS.loaded.page && CMS.loaded.post) {

			// Set navigation
			this.setNavigation();

	        // Manually trigger on initial load
			$(window).trigger('hashchange');
		}
	},

	parseContent: function(content, type, file, counter, numFiles) {

		var data = content.split(CMS.settings.parseSeperator),
			contentObj = {},
			id = counter,
			date = file.date;

		contentObj.id = id;
		contentObj.date = date;

		// Get content info
		var infoData = data[1].split(/[\n\r]+/);

		$.each(infoData, function(k, v) {
			if(v.length) {
				v.replace(/^\s+|\s+$/g, '').trim();
				var i = v.split(':');
				var val = v.slice(v.indexOf(':')+1);
				k = i[0];

				val = (k == 'date' ? (new Date(val)) : val);

				contentObj[k] = (val.trim ? val.trim() : val);
			}
		});

		// Drop stuff we dont need
		data.splice(0,2);

		// Put everything back together if broken
		var contentData = data.join();
		contentObj.contentData = marked(contentData);

		if(type == 'post') {
			CMS.posts.push(contentObj);
		} else if (type == 'page') {
			CMS.pages.push(contentObj);
		}

		// Execute after all content is loaded
		if(counter === numFiles) {
			CMS.contentLoaded(type);
		}
	},

	getContent: function(type, file, counter, numFiles) {

		var urlFolder = '';

		switch(type) {
			case 'post':
				urlFolder = CMS.settings.postsFolder;
				break;
			case 'page':
				urlFolder = CMS.settings.pagesFolder;
				break;
		}

		if(CMS.settings.mode == 'Github') {
			url = file.link;
		} else {
			url = urlFolder + '/' + file.name;
		}

		$.ajax({
			type: 'GET',
			url: url,
			dataType: 'html',
			success: function(content) {
				CMS.parseContent(content, type, file, counter, numFiles);
			},
			error: function() {
				var errorMsg = 'Error loading ' + type + ' content';
				CMS.renderError(errorMsg);
			}
		});
	},

	getFiles: function(type) {

		var folder = '',
			url = '';

		switch(type) {
			case 'post':
				folder = CMS.settings.postsFolder;
				break;
			case 'page':
				folder = CMS.settings.pagesFolder;
				break;
		}

		if(CMS.settings.mode == 'Github') {
			var gus = CMS.settings.githubUserSettings,
				gs = CMS.settings.githubSettings;
			url = gs.host + '/repos/' + gus.username + '/' + gus.repo + '/contents/' + folder + '?ref=' + gs.branch;
		} else {
			url = folder;
		}

		$.ajax({
			url: url,
			success: function(data) {

				var files = [],
					linkFiles;

				if(CMS.settings.mode == 'Github') {
					linkFiles = data;
				} else {
					linkFiles = $(data).find("a");
				}

				$(linkFiles).each(function(k, f) {

					var filename,
						downloadLink;

					if(CMS.settings.mode == 'Github') {
						filename = f.name;
						downloadLink = f.download_url;
					} else {
						filename = $(f).attr("href");
					}

					if(filename.endsWith('.md')) {
						var file = {};
						file.date = new Date(filename.substring(0, 10));
						file.name = filename;
						if(downloadLink) {
							file.link = downloadLink;
						}
						files.push(file);
					}

				});

				var counter = 0,
					numFiles = files.length;

				if(files.length > 0) {
					$(files).each(function(k, file) {
						counter++;
						CMS.getContent(type, file, counter, numFiles);
					});
				} else {
					var errorMsg = 'Error loading ' + type + 's in directory. Make sure ' +
						'there are Markdown ' + type + 's in the ' + type + 's folder.';
					CMS.renderError(errorMsg);
				}
			},
			error: function() {
				var errorMsg;
				if(CMS.settings.mode == 'Github') {
					errorMsg = 'Error loading ' + type + 's directory. Make sure ' +
						'your Github settings are correctly set in your config.js file.';
				} else {
					errorMsg = 'Error loading ' + type + 's directory. Make sure ' +
						type + 's directory is set correctly in config and .htaccess is in ' +
						type + 's directory with Apache "Options Indexes" set on.';
				}
				CMS.renderError(errorMsg);
			}
		});
	},

	setNavigation: function() {

		var nav = '
';
		CMS.settings.siteNavItems.forEach(function(navItem) {
			if(navItem.hasOwnProperty('href')) {
				nav += '
' + navItem.name + '
';
			} else {
				CMS.pages.forEach(function(page) {
					if(navItem.name == page.title) {
						nav += '
' + navItem.name + '
';
					}
				});
			}
		});
		nav += '
';

		$('.cms_nav').html(nav).hide().fadeIn(CMS.settings.fadeSpeed);

		// Set onclicks for nav links
		$.each($('.cms_nav_link'), function(k, link) {
			var title =  $(this).attr("id");
			$(this).on('click', function (e) {
				e.preventDefault();
				window.location.hash = 'page/' + title;
			});

		});
	},

	setSiteAttributes: function() {
		CMS.settings.siteAttributes.forEach(function(attribute) {

			var value;

			// Set brand
			if(attribute.attr == '.cms_sitename') {
				if (attribute.value.match(/\.(jpeg|jpg|gif|png)$/)) {
		            value = '';
		        } else {
		            value = attribute.value;
		        }
			} else {
				value = attribute.value;
			}
			$(attribute.attr).html(value).hide().fadeIn(CMS.settings.fadeSpeed);
		});
	},

	generateSite: function() {

		this.setSiteAttributes();

		var types = ['post', 'page'];

		types.forEach(function(type){
			CMS.getFiles(type);
		});

		// Check for hash changes
        $(window).on('hashchange', function () {
            CMS.render(window.location.hash);
        });
	},

	init: function (options) {
		if ($.isPlainObject(options)) {
			return this.extend(this.settings, options, function () {
				CMS.generateSite();
			});
		}
	}

};
<|endoftext|>


<commit_before>//API Documentation JS
(function(){

    //vars
    var
        jsonObject = {},
        glossList = Spektral.getElement("glossaryList"),
        methodContainer = Spektral.getElement("methodContainer");

    //Comment for production
    Spektral.debug();

    init();

    ////////////////////
    ////INIT
    ////////////////////
    function init() {
        if(document.readyState === "complete") {
            loadJSON(null);
        }
        else {
            Spektral.attachEventListener(window, 'load', loadJSON);
        }
    }

    ////////////////////
    ////LOAD JSON
    ////////////////////
    function loadJSON(e) {
        Spektral.loadJSON("js/documentation.json", onJSONLoaded);
    }

    ////////////////////
    ////ON JSON LOADED
    ////////////////////
    function onJSONLoaded(e) {
        jsonObject = e.methods;
        buildGlossary();
    }

    ////////////////////
    ////BUILD GLOSSARY
    ////////////////////
    function buildGlossary() {
        var key, item, listItem;

        for (key in jsonObject) {
            item = jsonObject[key].title;

            listItem = Spektral.createNewElement("li", "item" + key, glossList);
            listItem.innerHTML = item;
            Spektral.attachEventListener(listItem, 'click', onListItemClick);
        }
    }

    ////////////////////
    ////ON LIST ITEM CLICK
    ////////////////////
    function onListItemClick (e) {

        scrollToTop(e);
        var target = Spektral.getTargetID(e), num = Spektral.stripString(target, "item");
        populateMethodContainer(num);
    }

    ////////////////////
    ////POPULATE METHOD CONTAINER
    ////////////////////
    function populateMethodContainer(id) {

        clearMethodContainer();

        var
            title,
            description,
            code, params,
            paramsList, paramObj,
            parameter, paramTitle,
            paramDesc, returnsTitle, returns, depend,
            dependTitle, compatibilityTitle,
            compatibility, key,
            k, details;

        var info = Spektral.getInfo(jsonObject[id]);
        Spektral.log("Method info: " + info);

        title = Spektral.createNewElement("h2", "title", methodContainer);
        title.innerHTML = jsonObject[id].title;

        description = Spektral.createNewElement("p", "description", methodContainer);
        description.innerHTML = jsonObject[id].description;

        code = Spektral.createNewElement("code", "code", methodContainer);
        code.innerHTML = jsonObject[id].code;

        params = Spektral.createNewElement("section", "params", methodContainer);

        paramsList = jsonObject[id].params;

        parameter = Spektral.createNewElement("div", "paramContainer", params);

        if (Spektral.isObjectEmpty(paramsList) === false) {
            for (key in paramsList) {
            //parameter = Spektral.createNewElement("div", "param" + key, params);
            paramObj = paramsList[key];
                for(k in paramObj) {
                    paramTitle = Spektral.createNewElement("h3", "paramTitle", parameter);
                    paramTitle.innerHTML = k;

                    paramDesc = Spektral.createNewElement("p", "paramDesc", parameter);
                    paramDesc.innerHTML = paramObj[k];
                }
            }
        } else {
            paramDesc = Spektral.createNewElement("p", "paramDesc", parameter);
            paramDesc.innerHTML = "No parameters."
        }

        details = Spektral.createNewElement("section", "details", methodContainer);

        returnsTitle = Spektral.createNewElement("h3", "returnsTitle", details);
        returnsTitle.innerHTML = "Returns";

        returns = Spektral.createNewElement("p", "returns", details);
        returns.innerHTML = jsonObject[id].returns;

        dependTitle = Spektral.createNewElement("h3", "dependTitle", details);
        dependTitle.innerHTML = "Dependencies";

        depend = Spektral.createNewElement("p", "dependencies", details);
        depend.innerHTML = jsonObject[id].dependencies;

        compatibilityTitle = Spektral.createNewElement("h3", "compatibilityTitle", details);
        compatibilityTitle.innerHTML = "Compatibility";

        compatibility = Spektral.createNewElement("p", "compatibility", details);
        compatibility.innerHTML = jsonObject[id].compatibility;

        TweenLite.to(methodContainer, 0.25, {opacity:"1", ease:Expo.easeIn});
    }

    ////////////////////
    ////CLEAR METHOD CONTAINER
    ////////////////////
    function clearMethodContainer() {
        Spektral.setStyle(methodContainer, "opacity:0");
        Spektral.clearAllChildren(methodContainer);
    }

    ////////////////////
    ////SCROLL TO TOP
    ////////////////////
    function scrollToTop(e) {
        TweenLite.to(window, 0.5, {scrollTo:{y:0}, ease: Expo.easeOut});
    }

}(window));
<commit_msg>Slight change to doc.js.<commit_after>//API Documentation JS
(function(){

    //vars
    var
        jsonObject = {},
        glossList = Spektral.getElement("glossaryList"),
        methodContainer = Spektral.getElement("methodContainer");

    //Comment for production
    Spektral.debug();

    init();

    ////////////////////
    ////INIT
    ////////////////////
    function init() {
        if(document.readyState === "complete") {
            loadJSON(null);
        }
        else {
            Spektral.attachEventListener(window, 'load', loadJSON);
        }
    }

    ////////////////////
    ////LOAD JSON
    ////////////////////
    function loadJSON(e) {
        Spektral.loadJSON("js/documentation.json", onJSONLoaded);
    }

    ////////////////////
    ////ON JSON LOADED
    ////////////////////
    function onJSONLoaded(e) {
        jsonObject = e.methods;
        buildGlossary();
    }

    ////////////////////
    ////BUILD GLOSSARY
    ////////////////////
    function buildGlossary() {
        var key, item, listItem;

        for (key in jsonObject) {
            item = jsonObject[key].title;

            listItem = Spektral.createNewElement("li", "item" + key, glossList);
            listItem.innerHTML = item;
            Spektral.attachEventListener(listItem, 'click', onListItemClick);
        }
    }

    ////////////////////
    ////ON LIST ITEM CLICK
    ////////////////////
    function onListItemClick (e) {

        scrollToTop(e);
        var target = Spektral.getTargetID(e), num = Spektral.stripString(target, "item");
        populateMethodContainer(num);
    }

    ////////////////////
    ////POPULATE METHOD CONTAINER
    ////////////////////
    function populateMethodContainer(id) {

        clearMethodContainer();

        var
            title,
            description,
            code, params,
            paramsList, paramObj,
            parameter, paramTitle,
            paramDesc, returnsTitle, returns, depend,
            dependTitle, compatibilityTitle,
            compatibility, key,
            k, details, info;

        info = Spektral.getInfo(jsonObject[id]);
        //Spektral.log("Method info: " + info);

        title = Spektral.createNewElement("h2", "title", methodContainer);
        title.innerHTML = jsonObject[id].title;

        description = Spektral.createNewElement("p", "description", methodContainer);
        description.innerHTML = jsonObject[id].description;

        code = Spektral.createNewElement("code", "code", methodContainer);
        code.innerHTML = jsonObject[id].code;

        params = Spektral.createNewElement("section", "params", methodContainer);

        paramsList = jsonObject[id].params;

        parameter = Spektral.createNewElement("div", "paramContainer", params);

        if (Spektral.isObjectEmpty(paramsList) === false) {
            for (key in paramsList) {
            //parameter = Spektral.createNewElement("div", "param" + key, params);
            paramObj = paramsList[key];
                for(k in paramObj) {
                    paramTitle = Spektral.createNewElement("h3", "paramTitle", parameter);
                    paramTitle.innerHTML = k;

                    paramDesc = Spektral.createNewElement("p", "paramDesc", parameter);
                    paramDesc.innerHTML = paramObj[k];
                }
            }
        } else {
            paramDesc = Spektral.createNewElement("p", "paramDesc", parameter);
            paramDesc.innerHTML = "No parameters."
        }

        details = Spektral.createNewElement("section", "details", methodContainer);

        returnsTitle = Spektral.createNewElement("h3", "returnsTitle", details);
        returnsTitle.innerHTML = "Returns";

        returns = Spektral.createNewElement("p", "returns", details);
        returns.innerHTML = jsonObject[id].returns;

        dependTitle = Spektral.createNewElement("h3", "dependTitle", details);
        dependTitle.innerHTML = "Dependencies";

        depend = Spektral.createNewElement("p", "dependencies", details);
        depend.innerHTML = jsonObject[id].dependencies;

        compatibilityTitle = Spektral.createNewElement("h3", "compatibilityTitle", details);
        compatibilityTitle.innerHTML = "Compatibility";

        compatibility = Spektral.createNewElement("p", "compatibility", details);
        compatibility.innerHTML = jsonObject[id].compatibility;

        TweenLite.to(methodContainer, 0.25, {opacity:"1", ease:Expo.easeIn});
    }

    ////////////////////
    ////CLEAR METHOD CONTAINER
    ////////////////////
    function clearMethodContainer() {
        Spektral.setStyle(methodContainer, "opacity:0");
        Spektral.clearAllChildren(methodContainer);
    }

    ////////////////////
    ////SCROLL TO TOP
    ////////////////////
    function scrollToTop(e) {
        TweenLite.to(window, 0.5, {scrollTo:{y:0}, ease: Expo.easeOut});
    }

}(window));
<|endoftext|>


<commit_before>(function(app) {
  'use strict';

  var helper = app.helper || require('./helper.js');

  var dom = {};

  dom.export = function(key, value) {
    var g = (typeof global !== 'undefined' ? global : window);
    helper.define(g, key, value);
  };

  dom.find = function(el, selector) {
    return el.querySelector(selector);
  };

  dom.body = function() {
    return document.body;
  };

  dom.render = function(s) {
    var el = document.createRange().createContextualFragment(s).firstChild;
    dom.remove(el);
    return el;
  };

  dom.append = function(parent, el) {
    parent.appendChild(el);
  };

  dom.remove = function(el) {
    if (el.parentNode) {
      el.parentNode.removeChild(el);
    }
  };

  dom.childNode = function() {
    return helper.toArray(arguments).reduce(function(el, index) {
      return ('childNodes' in el ? el.childNodes[index] : null);
    });
  };

  dom.parent = function(el) {
    return el.parentNode;
  };

  dom.contains = function(el, other) {
    return el.contains(other);
  };

  dom.attr = function(el, props) {
    Object.keys(props).forEach(function(key) {
      el.setAttribute(key, props[key]);
    });
  };

  dom.css = function(el, props) {
    var style = el.style;
    Object.keys(props).forEach(function(key) {
      style[key] = props[key];
    });
  };

  dom.className = function(el, className) {
    dom.attr(el, { 'class': className });
  };

  dom.addClass = function(el, className) {
    el.classList.add(className);
  };

  dom.toggleClass = function(el, className, force) {
    if (typeof force === 'undefined') {
      el.classList.toggle(className);
      return;
    }
    if (force) {
      el.classList.add(className);
    } else {
      el.classList.remove(className);
    }
  };

  dom.hasClass = function(el, className) {
    return el.classList.contains(className);
  };

  dom.data = function(el, key, value) {
    if (typeof value === 'undefined') {
      return el.dataset[key];
    }
    el.dataset[key] = value;
  };

  dom.name = function(el, s) {
    el.name = s;
  };

  dom.text = function(el, s) {
    el.textContent = s;
  };

  dom.value = function(el, s) {
    if (typeof s === 'undefined') {
      return el.value;
    }
    el.value = s;
  };

  dom.hasSelection = function(el) {
    return (el.selectionStart !== el.selectionEnd);
  };

  dom.selectAll = function(el) {
    el.setSelectionRange(0, 9999);
  };

  dom.rect = function(el) {
    return el.getBoundingClientRect();
  };

  dom.offsetHeight = function(el) {
    return el.offsetHeight;
  };

  dom.scrollLeft = function(el) {
    return el.scrollLeft;
  };

  dom.scrollTop = function(el) {
    return el.scrollTop;
  };

  dom.file = function(el) {
    return el.files[0];
  };

  dom.contentWindow = function(iframe) {
    return iframe.contentWindow;
  };

  dom.writeContent = function(iframe, s) {
    var doc = iframe.contentDocument;
    doc.open();
    doc.write(s);
    doc.close();
  };

  dom.fillContentHeight = function(iframe) {
    iframe.style.height = iframe.contentDocument.documentElement.scrollHeight + 'px';
  };

  dom.isFocused = function(el) {
    return (el === document.activeElement);
  };

  dom.removeFocus = function() {
    document.activeElement.blur();
  };

  dom.clone = function(el) {
    return el.cloneNode(true);
  };

  dom.transform = function(el, value) {
    dom.css(el, {
      transform: value,
      webkitTransform: value,
    });
  };

  dom.translate = function(el, x, y) {
    dom.transform(el, 'translate(' + x + 'px, ' + y + 'px)');
  };

  dom.translateY = function(el, y) {
    dom.transform(el, 'translateY(' + y + 'px)');
  };

  dom.on = function(el, type, listener, useCapture) {
    el.addEventListener(type, listener, !!useCapture);
  };

  dom.off = function(el, type, listener, useCapture) {
    el.removeEventListener(type, listener, !!useCapture);
  };

  dom.ready = function(listener) {
    document.addEventListener('DOMContentLoaded', listener, false);
  };

  dom.click = function(el) {
    el.click();
  };

  dom.transition = function(el, callback) {
    return new Promise(function(resolve, reject) {
      var ontransitionend = function() {
        dom.off(el, 'transitionend', ontransitionend);
        resolve();
      };
      dom.on(el, 'transitionend', ontransitionend);
      callback();
    });
  };

  dom.supportsTouch = function() {
    return ('createTouch' in document);
  };

  dom.changedTouch = function(event) {
    return (dom.supportsTouch() ? helper.dig(event, 'changedTouches', 0) : null);
  };

  dom.target = function(event) {
    var touch = dom.changedTouch(event);
    return (touch ? document.elementFromPoint(touch.clientX, touch.clientY) : event.target);
  };

  dom.cancel = function(event) {
    event.preventDefault();
  };

  dom.origin = function(event) {
    return event.origin;
  };

  dom.messageData = function(event) {
    return event.data;
  };

  dom.eventType = function(name) {
    var supportsTouch = dom.supportsTouch();
    switch (name) {
      case 'start':
        return (supportsTouch ? 'touchstart' : 'mousedown');
      case 'move':
        return (supportsTouch ? 'touchmove' : 'mousemove');
      case 'end':
        return (supportsTouch ? 'touchend' : 'mouseup');
      default:
        throw new Error('Invalid event type');
    }
  };

  dom.diffPoints = function(p0, p1) {
    return { dx: p0.x - p1.x, dy: p0.y - p1.y };
  };

  dom.pagePoint = function(event) {
    var p = dom.changedTouch(event) || event;
    return { x: p.pageX, y: p.pageY };
  };

  dom.clientX = function(event) {
    return (dom.changedTouch(event) || event).clientX;
  };

  dom.clientY = function(event) {
    return (dom.changedTouch(event) || event).clientY;
  };

  dom.identifier = function(event) {
    var touch = dom.changedTouch(event);
    return (touch ? touch.identifier : null);
  };

  dom.Draggable = (function() {
    var Draggable = function(props) {
      this.element = props.element;
      this.onstart = props.onstart;
      this.onmove = props.onmove;
      this.onend = props.onend;
      this.start = start.bind(this);
      this.move = move.bind(this);
      this.end = end.bind(this);
      this.lock = false;
      this.identifier = null;
      this.startingPoint = null;
      this.context = {};

      dom.on(this.element, dom.eventType('start'), this.start);
    };

    Draggable.prototype.destroy = function() {
      dom.off(this.element, dom.eventType('start'), this.start);
      dom.off(document, dom.eventType('move'), this.move);
      dom.off(document, dom.eventType('end'), this.end);
      this.context = null;
    };

    var start = function(event) {
      if (this.lock) {
        return;
      }

      this.lock = true;
      this.identifier = dom.identifier(event);
      this.startingPoint = dom.pagePoint(event);

      var onstart = this.onstart;
      if (typeof onstart === 'function') {
        var rect = dom.rect(this.element);
        var x = dom.clientX(event) - rect.left + dom.scrollLeft(this.element);
        var y = dom.clientY(event) - rect.top + dom.scrollTop(this.element);
        onstart(x, y, event, this.context);
      }

      dom.on(document, dom.eventType('move'), this.move);
      dom.on(document, dom.eventType('end'), this.end);
    };

    var move = function(event) {
      var identifier = this.identifier;

      if (identifier && identifier !== dom.identifier(event)) {
        return;
      }

      var onmove = this.onmove;
      if (typeof onmove === 'function') {
        var d = dom.diffPoints(dom.pagePoint(event), this.startingPoint);
        onmove(d.dx, d.dy, event, this.context);
      }
    };

    var end = function(event) {
      var identifier = this.identifier;

      if (identifier && identifier !== dom.identifier(event)) {
        return;
      }

      dom.off(document, dom.eventType('move'), this.move);
      dom.off(document, dom.eventType('end'), this.end);

      var onend = this.onend;
      if (typeof onend === 'function') {
        var d = dom.diffPoints(dom.pagePoint(event), this.startingPoint);
        onend(d.dx, d.dy, event, this.context);
      }

      this.lock = false;
    };

    return Draggable;
  })();

  dom.readFile = function(file) {
    return new Promise(function(resolve, reject) {
      var reader = new FileReader();

      var onfailed = function() {
        reject(new Error('Failed to read file: ' + file.name));
      };

      reader.onload = function(event) {
        resolve(event.target.result);
      };

      reader.onerror = onfailed;
      reader.onabort = onfailed;

      reader.readAsText(file);
    });
  };

  dom.ajax = function(opt) {
    var type = opt.type;
    var url = opt.url;

    return new Promise(function(resolve, reject) {
      var req = new XMLHttpRequest();

      var onfailed = function() {
        reject(new Error('Failed to load resource: ' + type + ' ' + url));
      };

      req.onload = function() {
        if (req.status >= 200 && req.status < 400) {
          resolve(req.response);
        } else {
          onfailed();
        }
      };

      req.onerror = onfailed;
      req.onabort = onfailed;

      req.open(type, url, true);
      req.send();
    });
  };

  dom.loadJSON = function(url) {
    return dom.ajax({
      type: 'GET',
      url: url,
    }).then(function(text) {
      return JSON.parse(text);
    });
  };

  dom.location = function() {
    return document.location;
  };

  dom.urlOrigin = function(url) {
    return url.protocol + '//' + url.host;
  };

  dom.urlQuery = function(url) {
    return url.search.substring(1).split('&').reduce(function(obj, param) {
      var items = param.split('=');
      var key = items[0];
      if (key) {
        obj[decodeURIComponent(key)] = decodeURIComponent(items[1] || '');
      }
      return obj;
    }, {});
  };

  dom.Listenable = (function() {
    var Listenable = function(props) {
      this.element = props.element;
      this.type = props.type;
      this.callback = props.callback;
      this.resolve = props.resolve;
      this.reject = props.reject;
      this.listener = Listenable.prototype.listener.bind(this);

      dom.on(this.element, this.type, this.listener);
    };

    Listenable.prototype.destroy = function() {
      dom.off(this.element, this.type, this.listener);
    };

    Listenable.prototype.listener = function(event) {
      try {
        this.callback(event);
        this.resolve();
      } catch (e) {
        this.reject(e);
      }
    };

    return Listenable;
  })();

  if (typeof module !== 'undefined' && module.exports) {
    module.exports = dom;
  } else {
    app.dom = dom;
  }
})(this.app || (this.app = {}));
<commit_msg>Modify utility method to get page point<commit_after>(function(app) {
  'use strict';

  var helper = app.helper || require('./helper.js');

  var dom = {};

  dom.export = function(key, value) {
    var g = (typeof global !== 'undefined' ? global : window);
    helper.define(g, key, value);
  };

  dom.find = function(el, selector) {
    return el.querySelector(selector);
  };

  dom.body = function() {
    return document.body;
  };

  dom.render = function(s) {
    var el = document.createRange().createContextualFragment(s).firstChild;
    dom.remove(el);
    return el;
  };

  dom.append = function(parent, el) {
    parent.appendChild(el);
  };

  dom.remove = function(el) {
    if (el.parentNode) {
      el.parentNode.removeChild(el);
    }
  };

  dom.childNode = function() {
    return helper.toArray(arguments).reduce(function(el, index) {
      return ('childNodes' in el ? el.childNodes[index] : null);
    });
  };

  dom.parent = function(el) {
    return el.parentNode;
  };

  dom.contains = function(el, other) {
    return el.contains(other);
  };

  dom.attr = function(el, props) {
    Object.keys(props).forEach(function(key) {
      el.setAttribute(key, props[key]);
    });
  };

  dom.css = function(el, props) {
    var style = el.style;
    Object.keys(props).forEach(function(key) {
      style[key] = props[key];
    });
  };

  dom.className = function(el, className) {
    dom.attr(el, { 'class': className });
  };

  dom.addClass = function(el, className) {
    el.classList.add(className);
  };

  dom.toggleClass = function(el, className, force) {
    if (typeof force === 'undefined') {
      el.classList.toggle(className);
      return;
    }
    if (force) {
      el.classList.add(className);
    } else {
      el.classList.remove(className);
    }
  };

  dom.hasClass = function(el, className) {
    return el.classList.contains(className);
  };

  dom.data = function(el, key, value) {
    if (typeof value === 'undefined') {
      return el.dataset[key];
    }
    el.dataset[key] = value;
  };

  dom.name = function(el, s) {
    el.name = s;
  };

  dom.text = function(el, s) {
    el.textContent = s;
  };

  dom.value = function(el, s) {
    if (typeof s === 'undefined') {
      return el.value;
    }
    el.value = s;
  };

  dom.hasSelection = function(el) {
    return (el.selectionStart !== el.selectionEnd);
  };

  dom.selectAll = function(el) {
    el.setSelectionRange(0, 9999);
  };

  dom.rect = function(el) {
    return el.getBoundingClientRect();
  };

  dom.offsetHeight = function(el) {
    return el.offsetHeight;
  };

  dom.scrollLeft = function(el) {
    return el.scrollLeft;
  };

  dom.scrollTop = function(el) {
    return el.scrollTop;
  };

  dom.file = function(el) {
    return el.files[0];
  };

  dom.contentWindow = function(iframe) {
    return iframe.contentWindow;
  };

  dom.writeContent = function(iframe, s) {
    var doc = iframe.contentDocument;
    doc.open();
    doc.write(s);
    doc.close();
  };

  dom.fillContentHeight = function(iframe) {
    iframe.style.height = iframe.contentDocument.documentElement.scrollHeight + 'px';
  };

  dom.isFocused = function(el) {
    return (el === document.activeElement);
  };

  dom.removeFocus = function() {
    document.activeElement.blur();
  };

  dom.clone = function(el) {
    return el.cloneNode(true);
  };

  dom.transform = function(el, value) {
    dom.css(el, {
      transform: value,
      webkitTransform: value,
    });
  };

  dom.translate = function(el, x, y) {
    dom.transform(el, 'translate(' + x + 'px, ' + y + 'px)');
  };

  dom.translateY = function(el, y) {
    dom.transform(el, 'translateY(' + y + 'px)');
  };

  dom.on = function(el, type, listener, useCapture) {
    el.addEventListener(type, listener, !!useCapture);
  };

  dom.off = function(el, type, listener, useCapture) {
    el.removeEventListener(type, listener, !!useCapture);
  };

  dom.ready = function(listener) {
    document.addEventListener('DOMContentLoaded', listener, false);
  };

  dom.click = function(el) {
    el.click();
  };

  dom.transition = function(el, callback) {
    return new Promise(function(resolve, reject) {
      var ontransitionend = function() {
        dom.off(el, 'transitionend', ontransitionend);
        resolve();
      };
      dom.on(el, 'transitionend', ontransitionend);
      callback();
    });
  };

  dom.supportsTouch = function() {
    return ('createTouch' in document);
  };

  dom.changedTouch = function(event) {
    return (dom.supportsTouch() ? helper.dig(event, 'changedTouches', 0) : null);
  };

  dom.target = function(event) {
    var touch = dom.changedTouch(event);
    return (touch ? document.elementFromPoint(touch.clientX, touch.clientY) : event.target);
  };

  dom.cancel = function(event) {
    event.preventDefault();
  };

  dom.origin = function(event) {
    return event.origin;
  };

  dom.messageData = function(event) {
    return event.data;
  };

  dom.eventType = function(name) {
    var supportsTouch = dom.supportsTouch();
    switch (name) {
      case 'start':
        return (supportsTouch ? 'touchstart' : 'mousedown');
      case 'move':
        return (supportsTouch ? 'touchmove' : 'mousemove');
      case 'end':
        return (supportsTouch ? 'touchend' : 'mouseup');
      default:
        throw new Error('Invalid event type');
    }
  };

  dom.pageX = function(event) {
    return (dom.changedTouch(event) || event).pageX;
  };

  dom.pageY = function(event) {
    return (dom.changedTouch(event) || event).pageY;
  };

  dom.clientX = function(event) {
    return (dom.changedTouch(event) || event).clientX;
  };

  dom.clientY = function(event) {
    return (dom.changedTouch(event) || event).clientY;
  };

  dom.identifier = function(event) {
    var touch = dom.changedTouch(event);
    return (touch ? touch.identifier : null);
  };

  dom.Draggable = (function() {
    var Draggable = function(props) {
      this.element = props.element;
      this.onstart = props.onstart;
      this.onmove = props.onmove;
      this.onend = props.onend;
      this.start = start.bind(this);
      this.move = move.bind(this);
      this.end = end.bind(this);
      this.lock = false;
      this.identifier = null;
      this.startPageX = 0;
      this.startPageY = 0;
      this.context = {};

      dom.on(this.element, dom.eventType('start'), this.start);
    };

    Draggable.prototype.destroy = function() {
      dom.off(this.element, dom.eventType('start'), this.start);
      dom.off(document, dom.eventType('move'), this.move);
      dom.off(document, dom.eventType('end'), this.end);
      this.context = null;
    };

    var start = function(event) {
      if (this.lock) {
        return;
      }

      this.lock = true;
      this.identifier = dom.identifier(event);
      this.startPageX = dom.pageX(event);
      this.startPageY = dom.pageY(event);

      var onstart = this.onstart;
      if (typeof onstart === 'function') {
        var rect = dom.rect(this.element);
        var x = dom.clientX(event) - rect.left + dom.scrollLeft(this.element);
        var y = dom.clientY(event) - rect.top + dom.scrollTop(this.element);
        onstart(x, y, event, this.context);
      }

      dom.on(document, dom.eventType('move'), this.move);
      dom.on(document, dom.eventType('end'), this.end);
    };

    var move = function(event) {
      var identifier = this.identifier;

      if (identifier && identifier !== dom.identifier(event)) {
        return;
      }

      var onmove = this.onmove;
      if (typeof onmove === 'function') {
        var dx = dom.pageX(event) - this.startPageX;
        var dy = dom.pageY(event) - this.startPageY;
        onmove(dx, dy, event, this.context);
      }
    };

    var end = function(event) {
      var identifier = this.identifier;

      if (identifier && identifier !== dom.identifier(event)) {
        return;
      }

      dom.off(document, dom.eventType('move'), this.move);
      dom.off(document, dom.eventType('end'), this.end);

      var onend = this.onend;
      if (typeof onend === 'function') {
        var dx = dom.pageX(event) - this.startPageX;
        var dy = dom.pageY(event) - this.startPageY;
        onend(dx, dy, event, this.context);
      }

      this.lock = false;
    };

    return Draggable;
  })();

  dom.readFile = function(file) {
    return new Promise(function(resolve, reject) {
      var reader = new FileReader();

      var onfailed = function() {
        reject(new Error('Failed to read file: ' + file.name));
      };

      reader.onload = function(event) {
        resolve(event.target.result);
      };

      reader.onerror = onfailed;
      reader.onabort = onfailed;

      reader.readAsText(file);
    });
  };

  dom.ajax = function(opt) {
    var type = opt.type;
    var url = opt.url;

    return new Promise(function(resolve, reject) {
      var req = new XMLHttpRequest();

      var onfailed = function() {
        reject(new Error('Failed to load resource: ' + type + ' ' + url));
      };

      req.onload = function() {
        if (req.status >= 200 && req.status < 400) {
          resolve(req.response);
        } else {
          onfailed();
        }
      };

      req.onerror = onfailed;
      req.onabort = onfailed;

      req.open(type, url, true);
      req.send();
    });
  };

  dom.loadJSON = function(url) {
    return dom.ajax({
      type: 'GET',
      url: url,
    }).then(function(text) {
      return JSON.parse(text);
    });
  };

  dom.location = function() {
    return document.location;
  };

  dom.urlOrigin = function(url) {
    return url.protocol + '//' + url.host;
  };

  dom.urlQuery = function(url) {
    return url.search.substring(1).split('&').reduce(function(obj, param) {
      var items = param.split('=');
      var key = items[0];
      if (key) {
        obj[decodeURIComponent(key)] = decodeURIComponent(items[1] || '');
      }
      return obj;
    }, {});
  };

  dom.Listenable = (function() {
    var Listenable = function(props) {
      this.element = props.element;
      this.type = props.type;
      this.callback = props.callback;
      this.resolve = props.resolve;
      this.reject = props.reject;
      this.listener = Listenable.prototype.listener.bind(this);

      dom.on(this.element, this.type, this.listener);
    };

    Listenable.prototype.destroy = function() {
      dom.off(this.element, this.type, this.listener);
    };

    Listenable.prototype.listener = function(event) {
      try {
        this.callback(event);
        this.resolve();
      } catch (e) {
        this.reject(e);
      }
    };

    return Listenable;
  })();

  if (typeof module !== 'undefined' && module.exports) {
    module.exports = dom;
  } else {
    app.dom = dom;
  }
})(this.app || (this.app = {}));
<|endoftext|>


<commit_before>import won from "../won-es6.js";
import angular from "angular";
import groupAdministrationHeaderModule from "./group-administration-header.js";
import postHeaderModule from "./post-header.js";
import labelledHrModule from "./labelled-hr.js";
import { connect2Redux } from "../won-utils.js";
import { attach, getIn, delay } from "../utils.js";
import { actionCreators } from "../actions/actions.js";
import { getGroupChatPostUriFromRoute } from "../selectors/general-selectors.js";
import { getGroupChatConnectionsByNeedUri } from "../selectors/connection-selectors.js";

import "style/_group-administration.scss";
import "style/_rdflink.scss";

const serviceDependencies = ["$ngRedux", "$scope", "$element"];

function genComponentConf() {
  let template = `

                <svg style="--local-primary:var(--won-primary-color);"
                     class="ga__header__back__icon clickable">
                    <use xlink:href="#ico36_backarrow" href="#ico36_backarrow"></use>
                </svg>

            <won-group-administration-header
              need-uri="self.groupPostAdminUri">
            </won-group-administration-header>

                <won-post-header
                  need-uri="conn.get('remoteNeedUri')"
                  hide-image="::false">
                </won-post-header>

                        Accept

                        Reject

                        Request

                        Waiting for Accept...

                        Remove

            <button class="ga__footer__button won-button--filled red" ng-click="self.joinGroup()">
                Join Group
            </button>

    `;

  class Controller {
    constructor(/* arguments = dependency injections */) {
      attach(this, serviceDependencies, arguments);
      window.pgm4dbg = this;
      this.won = won;

      this.scrollContainer().addEventListener("scroll", e => this.onScroll(e));

      const selectFromState = state => {
        const groupPostAdminUri = getGroupChatPostUriFromRoute(state);
        const groupChatPost = getIn(state, ["needs", groupPostAdminUri]);
        const groupChatConnections = getGroupChatConnectionsByNeedUri(
          state,
          groupPostAdminUri
        );

        return {
          groupPostAdminUri,
          groupChatPost,
          groupChatConnections,
          hasGroupChatConnections:
            groupChatConnections && groupChatConnections.size > 0,
          groupChatConnectionsArray:
            groupChatConnections && groupChatConnections.toArray(),
          /*isSentRequest:
            connection && connection.get("state") === won.WON.RequestSent,
          isReceivedRequest:
            connection && connection.get("state") === won.WON.RequestReceived,
          isConnected:
            connection && connection.get("state") === won.WON.Connected,
          isSuggested:
            connection && connection.get("state") === won.WON.Suggested,*/
        };
      };

      connect2Redux(selectFromState, actionCreators, [], this);

      this._snapBottom = true; //Don't snap to bottom immediately, because this scrolls the whole page... somehow?

      this.$scope.$watch(
        () => this.groupChatConnections && this.groupChatConnections.size, // trigger if there's messages added (or removed)
        () =>
          delay(0).then(() =>
            // scroll to bottom directly after rendering, if snapped
            this.updateScrollposition()
          )
      );
    }

    snapToBottom() {
      this._snapBottom = true;
      this.scrollToBottom();
    }
    unsnapFromBottom() {
      this._snapBottom = false;
    }
    updateScrollposition() {
      if (this._snapBottom) {
        this.scrollToBottom();
      }
    }
    scrollToBottom() {
      this._programmaticallyScrolling = true;

      this.scrollContainer().scrollTop = this.scrollContainer().scrollHeight;
    }
    onScroll() {
      if (!this._programmaticallyScrolling) {
        //only unsnap if the user scrolled themselves
        this.unsnapFromBottom();
      }

      const sc = this.scrollContainer();
      const isAtBottom = sc.scrollTop + sc.offsetHeight >= sc.scrollHeight;
      if (isAtBottom) {
        this.snapToBottom();
      }

      this._programmaticallyScrolling = false;
    }
    scrollContainer() {
      if (!this._scrollContainer) {
        this._scrollContainer = this.$element[0].querySelector(".ga__content");
      }
      return this._scrollContainer;
    }

    openRequest(connUri, message) {
      this.connections__open(connUri, message);
    }

    sendRequest(connUri, remoteNeedUri, message) {
      this.connections__rate(connUri, won.WON.binaryRatingGood);
      this.needs__connect(
        this.groupPostAdminUri,
        connUri,
        remoteNeedUri,
        message
      );
    }

    closeConnection(connUri, rateBad = false) {
      rateBad && this.connections__rate(connUri, won.WON.binaryRatingBad);
      this.connections__close(connUri);
    }

    joinGroup(persona) {
      //TODO: FIGURE OUT HOW TO USE won-submit-button instead so we can add a persona if need be
      if (this.groupPostAdminUri) {
        this.connections__connectAdHoc(
          this.groupPostAdminUri,
          "" /*message cant be undefined for whatever reason*/,
          persona
        );
      }

      //this.router__stateGoCurrent({connectionUri: null, sendAdHocRequest: null});
    }
  }
  Controller.$inject = serviceDependencies;

  return {
    restrict: "E",
    controller: Controller,
    controllerAs: "self",
    bindToController: true, //scope-bindings -> ctrl
    scope: {},
    template: template,
  };
}

export default angular
  .module("won.owner.components.groupAdministration", [
    groupAdministrationHeaderModule,
    postHeaderModule,
    labelledHrModule,
  ])
  .directive("wonGroupAdministration", genComponentConf).name;
<commit_msg>Clean up component<commit_after>import won from "../won-es6.js";
import angular from "angular";
import groupAdministrationHeaderModule from "./group-administration-header.js";
import postHeaderModule from "./post-header.js";
import labelledHrModule from "./labelled-hr.js";
import { connect2Redux } from "../won-utils.js";
import { attach, getIn } from "../utils.js";
import { actionCreators } from "../actions/actions.js";
import { getGroupChatPostUriFromRoute } from "../selectors/general-selectors.js";
import { getGroupChatConnectionsByNeedUri } from "../selectors/connection-selectors.js";

import "style/_group-administration.scss";
import "style/_rdflink.scss";

const serviceDependencies = ["$ngRedux", "$scope", "$element"];

function genComponentConf() {
  let template = `

                <svg style="--local-primary:var(--won-primary-color);"
                     class="ga__header__back__icon clickable">
                    <use xlink:href="#ico36_backarrow" href="#ico36_backarrow"></use>
                </svg>

            <won-group-administration-header
              need-uri="self.groupPostAdminUri">
            </won-group-administration-header>

                <won-post-header
                  need-uri="conn.get('remoteNeedUri')"
                  hide-image="::false">
                </won-post-header>

                        Accept

                        Reject

                        Request

                        Waiting for Accept...

                        Remove

            <button class="ga__footer__button won-button--filled red" ng-click="self.joinGroup()">
                Join Group
            </button>

    `;

  class Controller {
    constructor(/* arguments = dependency injections */) {
      attach(this, serviceDependencies, arguments);
      window.pgm4dbg = this;
      this.won = won;

      const selectFromState = state => {
        const groupPostAdminUri = getGroupChatPostUriFromRoute(state);
        const groupChatPost = getIn(state, ["needs", groupPostAdminUri]);
        const groupChatConnections = getGroupChatConnectionsByNeedUri(
          state,
          groupPostAdminUri
        );

        return {
          groupPostAdminUri,
          groupChatPost,
          groupChatConnections,
          hasGroupChatConnections:
            groupChatConnections && groupChatConnections.size > 0,
          groupChatConnectionsArray:
            groupChatConnections && groupChatConnections.toArray(),
        };
      };

      connect2Redux(selectFromState, actionCreators, [], this);
    }

    openRequest(connUri, message) {
      this.connections__open(connUri, message);
    }

    sendRequest(connUri, remoteNeedUri, message) {
      this.connections__rate(connUri, won.WON.binaryRatingGood);
      this.needs__connect(
        this.groupPostAdminUri,
        connUri,
        remoteNeedUri,
        message
      );
    }

    closeConnection(connUri, rateBad = false) {
      rateBad && this.connections__rate(connUri, won.WON.binaryRatingBad);
      this.connections__close(connUri);
    }

    joinGroup(persona) {
      //TODO: FIGURE OUT HOW TO USE won-submit-button instead so we can add a persona if need be
      if (this.groupPostAdminUri) {
        this.connections__connectAdHoc(
          this.groupPostAdminUri,
          "" /*message cant be undefined for whatever reason*/,
          persona
        );
      }

      //this.router__stateGoCurrent({connectionUri: null, sendAdHocRequest: null});
    }
  }
  Controller.$inject = serviceDependencies;

  return {
    restrict: "E",
    controller: Controller,
    controllerAs: "self",
    bindToController: true, //scope-bindings -> ctrl
    scope: {},
    template: template,
  };
}

export default angular
  .module("won.owner.components.groupAdministration", [
    groupAdministrationHeaderModule,
    postHeaderModule,
    labelledHrModule,
  ])
  .directive("wonGroupAdministration", genComponentConf).name;
<|endoftext|>