<commit_before>(function() {

"use strict";

function clickInsideElement( e, className ) {
	var el = document.getElementsByClassName(className)[0];

	var pos = getPosition(e);

	var bounds = el.getBoundingClientRect();

	var doc = document.documentElement;
	var clientLeft = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0);
	var clientTop = (window.pageYOffset || doc.scrollTop)  - (doc.clientTop || 0);

	pos.y -= clientTop;
	pos.x -= clientLeft;

	if (pos.x < bounds.left || pos.x > bounds.right || pos.y < bounds.top || pos.y > bounds.bottom) {
		return false;
	}

	return true;
}

function getPosition(e) {
	var posx = 0;
	var posy = 0;

	if (!e) var e = window.event;

	if (e.pageX || e.pageY) {
		posx = e.pageX;
		posy = e.pageY;
	} else if (e.clientX || e.clientY) {
		posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
		posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
	}

	return {
		x: posx,
		y: posy
	}
}

function updateNodeList(type) {
	var items = document.getElementById(contextMenuItemsClassName).children;
	var result = fuse.search(type);
	for (var i = 0; i < items.length; i++) {
		var item = items[i];
		var found = true;
		if (type.length) {
			found = false;
			for (var j = 0; j < result.length; j++) {
				if (item.innerHTML === result[j].type) {
					found = true;
					break;
				}
			}
		}
		if (found) {
			item.style.display = "block";
		} else {
			item.style.display = "none";
		}
	}
}

function clearHoveredMenuItems() {
	var items = document.getElementById(contextMenuItemsClassName).children;
	var hovered = -1;
	for (var i = 0; i < items.length; i++) {
		if (items[i].isHovered) {
			items[i].classList.remove(contextMenuItemHoverClassName);
			items[i].isHovered = false;
			hovered = i;
		}
	}
	return hovered;
}

function placeCaretAtEnd(element) {
    element.focus();
    if (typeof window.getSelection != "undefined"
            && typeof document.createRange != "undefined") {
        var range = document.createRange();
        range.selectNodeContents(element);
        range.collapse(false);
        var sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
    } else if (typeof document.body.createTextRange != "undefined") {
        var textRange = document.body.createTextRange();
        textRange.moveToElementText(element);
        textRange.collapse(false);
        textRange.select();
    }
}

var contextMenuClassName = "context-menu";
var contextMenuItemClassName = "menu-item";
var contextMenuItemHoverClassName = "menu-item-hover";
var contextMenuItemsClassName = "menu-items";
var contextMenuActiveClassName = "context-menu--active";

var graphClassName = "graph";

var searchClassName = "search";

var graphInContext;

var clickCoordsX;
var clickCoordsY;

var menu = document.querySelector("#context-menu");
var menuState = 0;
var menuWidth;
var menuHeight;
var menuPosition;
var menuPositionX;
var menuPositionY;

var clientRight;
var clientBottom;

var nodeTypes = [];

var fuse;
var fuseOptions = {
  caseSensitive: false,
  includeScore: false,
  shouldSort: true,
  tokenize: true,
  threshold: 0.3,
  location: 0,
  distance: 100,
  maxPatternLength: 32,
  keys: ["type"]
};

function init() {
	searchListeners();
	graphReadyListerner();
	contextListener();
	clickListener();
	keyupListener();
	resizeListener();
}

function graphReadyListerner() {
	window.addEventListener('WebComponentsReady', function(e) {
		parent.shaderGraph = document.getElementById("graph");
		if (parent.shaderGraph) {
			// build the list of nodes
			var menu = document.getElementById(contextMenuItemsClassName);
			nodeTypes = parent.shaderGraph.nodeList();
			for (var i = 0; i < nodeTypes.length; i++) {
				var a = document.createElement("a");
				a.type = a.innerHTML = nodeTypes[i].type;
				a.className = contextMenuItemClassName;
				a.onclick = function () {
					parent.shaderGraph.addNode({
						type: this.type,
						pos: [clickCoordsX, clickCoordsY]
					});
				};
				a.onmouseover = function () {
					clearHoveredMenuItems();
					this.isHovered = true;
					this.classList.add(contextMenuItemHoverClassName);
				}
				a.onmouseout = function () {
					this.isHovered = false;
					this.classList.remove(contextMenuItemHoverClassName);
				}
				a.onmousemove = function (e) {
					if (!this.isHovered) {
						this.onmouseover(e);
					}
				}
				menu.appendChild(a);
			}
		}

		fuse = new ShaderGraph.Fuse(nodeTypes, fuseOptions);

		parent.preview.onload = function(){
			parent.shaderGraph.updateShader();
		};
		parent.preview.init();
		parent.shaderGraph.onShaderUpdate = function(shader){
			var shaderDef = shader.buildShader()
			var source = document.getElementById("source");
			source.innerHTML = ShaderGraph.Beautify(
				optimize_glsl(shaderDef.fshader(), "2", "fs"),
				//fs,
				{
					"indent_size": 1,
					"indent_char": '\t',
					"max_preserve_newlines": -1,
					"brace_style": "expand",
					"wrap_line_length": 0
				}
			);

			source.classList.remove("prettyprinted");
			prettyPrint();

			parent.preview.updateShader(shaderDef);
		};

		//*
		var demos = [
			{ name: "Pattern",
				nodes: [
					{type:"fragColor", pos:[650, 130]},
					{type:"value", pos:[0, 0], value:70},
					{type:"uv", pos:[0, 100]},
					{type:"value", pos:[0, 220], value:35},
					{type:"value", pos:[0, 320], value:0.5},
					{type:"multiply", pos:[200, 50]},
					{type:"multiply", pos:[200, 150]},
					{type:"cos", pos:[350, 50]},
					{type:"sin", pos:[350, 150]},
					{type:"join", pos:[500, 100]},
					{type:"value", pos:[320, 250], value: 1}
				],
				links: [
					[1, 5],
					[2.1, 5.1],
					[2.2, 6],
					[3, 6.1],
					[5, 7],
					[6, 8],
					[7, 9],
					[8, 9.1],
					[4, 9.2],
					[10, 9.3],
					[9, 0]
				]
			},
			{ name: "Black and White",
				nodes: [
					{type:"fragColor", pos:[660, 200]},
					{type:"texture", pos:[0, 0]},
					{type:"split", pos:[0, 170]},
					{type:"add", pos:[135, 90]},
					{type:"add", pos:[267, 90]},
					{type:"divide", pos:[400, 90]},
					{type:"value", pos:[250, 175], value:3},
					{type:"join", pos:[530, 170]}
				],
				links: [
					[1, 2],
					[2, 3],
					[2.1, 3.1],
					[3, 4],
					[2.2, 4.1],
					[4, 5],
					[6, 5.1],
					[5, 7],
					[5, 7.1],
					[5, 7.2],
					[2.3, 7.3],
					[7, 0]
				]
			}];

		var placeholder = document.getElementById("demos");

		var element = document.createElement("a");
		element.onclick = function() {
			parent.shaderGraph.clearGraph();
		};
		element.innerHTML = "Clear";
		element.className = "demo";
		element.style.color = "red";
		placeholder.appendChild(element);

		for (var i = 0; i < demos.length; i++) {
			var element = document.createElement("a");
			element.demo = demos[i];
			element.onclick = function() {
				parent.shaderGraph.loadGraph(this.demo);
			};
			element.innerHTML = element.demo.name;
			element.className = "demo";
			placeholder.appendChild(element);
		}
	});
}

function searchListeners() {
	document.getElementById(searchClassName).onkeypress = function(e) {
		var code = e.keyCode || e.which;
		if (code === 13) {
			e.preventDefault();
		}
	};
	document.getElementById(searchClassName).onkeydown = function(e) {
		var code = e.keyCode || e.which;
		if (code === 8 && this.innerHTML.length === 1) {
			this.innerHTML = "";
			e.preventDefault();
		} else if (code === 38) {
			var container = document.getElementById(contextMenuItemsClassName);
			var items = container.children;
			var hovered = clearHoveredMenuItems();
			var i = hovered, item;
			while((item = items[--i]) && item.style.display === "none");
			if (i < 0) {
				i = items.length;
				while(i > hovered && (item = items[--i]) && item.style.display === "none");
			}
			items[i].classList.add(contextMenuItemHoverClassName);
			items[i].isHovered = true;
			this.innerHTML = items[i].type;
			placeCaretAtEnd(this);
			var offsetHeight = items[i].offsetHeight;
			var offsetTop = Math.floor(items[i].offsetTop / offsetHeight) * offsetHeight;
			container.scrollTop = Math.min(container.scrollTop, offsetTop);
			container.scrollTop = Math.max(container.scrollTop, offsetTop + offsetHeight - container.clientHeight);
			e.preventDefault();
		} else if (code === 40) {
			var container = document.getElementById(contextMenuItemsClassName);
			var items = container.children;
			var hovered = clearHoveredMenuItems();
			var i = hovered, item;
			while((item = items[++i]) && item.style.display === "none");
			if (i === items.length) {
				i = -1;
				while(i < hovered && (item = items[++i]) && item.style.display === "none");
			}
			items[i].classList.add(contextMenuItemHoverClassName);
			items[i].isHovered = true;
			this.innerHTML = items[i].type;
			placeCaretAtEnd(this);
			var offsetHeight = items[i].offsetHeight;
			var offsetTop = Math.floor(items[i].offsetTop / offsetHeight) * offsetHeight;
			container.scrollTop = Math.min(container.scrollTop, offsetTop);
			container.scrollTop = Math.max(container.scrollTop, offsetTop + offsetHeight - container.clientHeight);
			e.preventDefault();
		}
	};
	document.getElementById(searchClassName).onkeyup = function(e) {
		var code = e.keyCode || e.which;
		if (code !== 38 && code !== 40) {
			updateNodeList(this.innerHTML);
		}
	};
}

function contextListener() {
	document.addEventListener( "contextmenu", function(e) {
		graphInContext = clickInsideElement( e, graphClassName );

		if ( graphInContext ) {
			e.preventDefault();
			toggleMenuOn();
			positionMenu(e);
		} else {
			graphInContext = null;
			toggleMenuOff();
		}
	});
}

function clickListener() {
	document.addEventListener( "click", function(e) {
		var clickeElIsLink = clickInsideElement( e, contextMenuClassName );

		if ( clickeElIsLink ) {
			e.preventDefault();
			if (!clickInsideElement( e, searchClassName )) {
				toggleMenuOff();
			}
		} else {
			var button = e.which || e.button;
			if ( button === 1 ) {
				toggleMenuOff();
			}
		}
	});
}

function keyupListener() {
	window.onkeyup = function(e) {
		if ( e.keyCode === 27 ) {
			toggleMenuOff();
		}
	}
}

function resizeListener() {
	window.onresize = function(e) {
		toggleMenuOff();
	};
}

function toggleMenuOn() {
	if ( menuState !== 1 ) {
		menuState = 1;
		menu.classList.add( contextMenuActiveClassName );
		document.getElementById(searchClassName).focus();
		document.getElementById(contextMenuItemsClassName).scrollTop = 0;
	}
}

function toggleMenuOff() {
	if ( menuState !== 0 ) {
		menuState = 0;
		menu.classList.remove( contextMenuActiveClassName );
		document.getElementById(searchClassName).value = "";
		updateNodeList("");
	}
}

function positionMenu(e) {
	var doc = document.documentElement;
	var clientLeft = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0);
	var clientTop = (window.pageYOffset || doc.scrollTop)  - (doc.clientTop || 0);

	var pos = getPosition(e);
	clickCoordsX = pos.x - clientLeft;
	clickCoordsY = pos.y - clientTop;

	menuWidth = menu.offsetWidth + 4;
	menuHeight = menu.offsetHeight + 4;

	clientRight = clientLeft + window.innerWidth;
	clientBottom = clientTop + window.innerHeight;

	if ( (clientRight - clickCoordsX - clientLeft) < menuWidth ) {
		menu.style.left = clientRight - menuWidth + "px";
	} else {
		menu.style.left = clickCoordsX + clientLeft + "px";
	}

	if ( (clientBottom - clickCoordsY - clientTop) < menuHeight ) {
		menu.style.top = clientBottom - menuHeight + "px";
	} else {
		menu.style.top = clickCoordsY + clientTop + "px";
	}
}

init();

})();<commit_msg>refactor a bit<commit_after>(function() {

"use strict";

function clickInsideElement( e, className ) {
	var el = document.getElementsByClassName(className)[0];

	var pos = getPosition(e);

	var bounds = el.getBoundingClientRect();

	var doc = document.documentElement;
	var clientLeft = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0);
	var clientTop = (window.pageYOffset || doc.scrollTop)  - (doc.clientTop || 0);

	pos.y -= clientTop;
	pos.x -= clientLeft;

	if (pos.x < bounds.left || pos.x > bounds.right || pos.y < bounds.top || pos.y > bounds.bottom) {
		return false;
	}

	return true;
}

function getPosition(e) {
	var posx = 0;
	var posy = 0;

	if (!e) var e = window.event;

	if (e.pageX || e.pageY) {
		posx = e.pageX;
		posy = e.pageY;
	} else if (e.clientX || e.clientY) {
		posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
		posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
	}

	return {
		x: posx,
		y: posy
	}
}

function updateNodeList(type) {
	var items = document.getElementById(contextMenuItemsClassName).children;
	var result = fuse.search(type);
	for (var i = 0; i < items.length; i++) {
		var item = items[i];
		var found = true;
		if (type.length) {
			found = false;
			for (var j = 0; j < result.length; j++) {
				if (item.innerHTML === result[j].type) {
					found = true;
					break;
				}
			}
		}
		if (found) {
			item.style.display = "block";
		} else {
			item.style.display = "none";
		}
	}
}

function clearHoveredMenuItems() {
	var items = document.getElementById(contextMenuItemsClassName).children;
	var hovered = -1;
	for (var i = 0; i < items.length; i++) {
		if (items[i].isHovered) {
			items[i].classList.remove(contextMenuItemHoverClassName);
			items[i].isHovered = false;
			hovered = i;
		}
	}
	return hovered;
}

function placeCaretAtEnd(element) {
    element.focus();
    if (typeof window.getSelection != "undefined"
            && typeof document.createRange != "undefined") {
        var range = document.createRange();
        range.selectNodeContents(element);
        range.collapse(false);
        var sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
    } else if (typeof document.body.createTextRange != "undefined") {
        var textRange = document.body.createTextRange();
        textRange.moveToElementText(element);
        textRange.collapse(false);
        textRange.select();
    }
}

var contextMenuClassName = "context-menu";
var contextMenuItemClassName = "menu-item";
var contextMenuItemHoverClassName = "menu-item-hover";
var contextMenuItemsClassName = "menu-items";
var contextMenuActiveClassName = "context-menu--active";

var graphClassName = "graph";

var searchClassName = "search";

var graphInContext;

var clickCoordsX;
var clickCoordsY;

var menu = document.querySelector("#context-menu");
var menuState = 0;
var menuWidth;
var menuHeight;
var menuPosition;
var menuPositionX;
var menuPositionY;

var clientRight;
var clientBottom;

var nodeTypes = [];

var fuse;
var fuseOptions = {
  caseSensitive: false,
  includeScore: false,
  shouldSort: true,
  tokenize: true,
  threshold: 0.3,
  location: 0,
  distance: 100,
  maxPatternLength: 32,
  keys: ["type"]
};

function init() {
	searchListeners();
	graphReadyListerner();
	contextListener();
	clickListener();
	keyupListener();
	resizeListener();
}

function graphReadyListerner() {
	window.addEventListener('WebComponentsReady', function(e) {
		parent.shaderGraph = document.getElementById("graph");
		if (parent.shaderGraph) {
			// build the list of nodes
			var menu = document.getElementById(contextMenuItemsClassName);
			nodeTypes = parent.shaderGraph.nodeList();
			for (var i = 0; i < nodeTypes.length; i++) {
				var a = document.createElement("a");
				a.type = a.innerHTML = nodeTypes[i].type;
				a.className = contextMenuItemClassName;
				a.onclick = function () {
					parent.shaderGraph.addNode({
						type: this.type,
						pos: [clickCoordsX, clickCoordsY]
					});
				};
				a.onmouseover = function () {
					clearHoveredMenuItems();
					this.isHovered = true;
					this.classList.add(contextMenuItemHoverClassName);
				}
				a.onmouseout = function () {
					this.isHovered = false;
					this.classList.remove(contextMenuItemHoverClassName);
				}
				a.onmousemove = function (e) {
					if (!this.isHovered) {
						this.onmouseover(e);
					}
				}
				menu.appendChild(a);
			}
		}

		fuse = new ShaderGraph.Fuse(nodeTypes, fuseOptions);

		parent.preview.onload = function(){
			parent.shaderGraph.updateShader();
		};
		parent.preview.init();
		parent.shaderGraph.onShaderUpdate = function(shader){
			var shaderDef = shader.buildShader()
			var source = document.getElementById("source");
			source.innerHTML = ShaderGraph.Beautify(
				optimize_glsl(shaderDef.fshader(), "2", "fs"),
				//fs,
				{
					"indent_size": 1,
					"indent_char": '\t',
					"max_preserve_newlines": -1,
					"brace_style": "expand",
					"wrap_line_length": 0
				}
			);

			source.classList.remove("prettyprinted");
			prettyPrint();

			parent.preview.updateShader(shaderDef);
		};

		//*
		var demos = [
			{ name: "Pattern",
				nodes: [
					{type:"fragColor", pos:[650, 130]},
					{type:"value", pos:[0, 0], value:70},
					{type:"uv", pos:[0, 100]},
					{type:"value", pos:[0, 220], value:35},
					{type:"value", pos:[0, 320], value:0.5},
					{type:"multiply", pos:[200, 50]},
					{type:"multiply", pos:[200, 150]},
					{type:"cos", pos:[350, 50]},
					{type:"sin", pos:[350, 150]},
					{type:"join", pos:[500, 100]},
					{type:"value", pos:[320, 250], value: 1}
				],
				links: [
					[1, 5],
					[2.1, 5.1],
					[2.2, 6],
					[3, 6.1],
					[5, 7],
					[6, 8],
					[7, 9],
					[8, 9.1],
					[4, 9.2],
					[10, 9.3],
					[9, 0]
				]
			},
			{ name: "Black and White",
				nodes: [
					{type:"fragColor", pos:[660, 200]},
					{type:"texture", pos:[0, 0]},
					{type:"split", pos:[0, 170]},
					{type:"add", pos:[135, 90]},
					{type:"add", pos:[267, 90]},
					{type:"divide", pos:[400, 90]},
					{type:"value", pos:[250, 175], value:3},
					{type:"join", pos:[530, 170]}
				],
				links: [
					[1, 2],
					[2, 3],
					[2.1, 3.1],
					[3, 4],
					[2.2, 4.1],
					[4, 5],
					[6, 5.1],
					[5, 7],
					[5, 7.1],
					[5, 7.2],
					[2.3, 7.3],
					[7, 0]
				]
			}];

		var placeholder = document.getElementById("demos");

		var element = document.createElement("a");
		element.onclick = function() {
			parent.shaderGraph.clearGraph();
		};
		element.innerHTML = "Clear";
		element.className = "demo";
		element.style.color = "red";
		placeholder.appendChild(element);

		for (var i = 0; i < demos.length; i++) {
			var element = document.createElement("a");
			element.demo = demos[i];
			element.onclick = function() {
				parent.shaderGraph.loadGraph(this.demo);
			};
			element.innerHTML = element.demo.name;
			element.className = "demo";
			placeholder.appendChild(element);
		}
	});
}

function searchListeners() {
	document.getElementById(searchClassName).onkeypress = function(e) {
		var code = e.keyCode || e.which;
		if (code === 13) {
			e.preventDefault();
		}
	};
	document.getElementById(searchClassName).onkeydown = function(e) {
		var code = e.keyCode || e.which;
		if (code === 8 && this.innerHTML.length === 1) {
			this.innerHTML = "";
			e.preventDefault();
		} else if (code === 38 || code === 40) {
			var container = document.getElementById(contextMenuItemsClassName);
			var items = container.children;
			var hovered = clearHoveredMenuItems();
			var i = hovered, item;
			if (code === 38) {
				while((item = items[--i]) && item.style.display === "none");
				if (i < 0) {
					i = items.length;
					while(i > hovered && (item = items[--i]) && item.style.display === "none");
				}
			} else {
				while((item = items[++i]) && item.style.display === "none");
				if (i === items.length) {
					i = -1;
					while(i < hovered && (item = items[++i]) && item.style.display === "none");
				}
			}
			items[i].classList.add(contextMenuItemHoverClassName);
			items[i].isHovered = true;
			this.innerHTML = items[i].type;
			placeCaretAtEnd(this);
			var offsetHeight = items[i].offsetHeight;
			var offsetTop = Math.floor(items[i].offsetTop / offsetHeight) * offsetHeight;
			container.scrollTop = Math.min(container.scrollTop, offsetTop);
			container.scrollTop = Math.max(container.scrollTop, offsetTop + offsetHeight - container.clientHeight);
			e.preventDefault();
		}
	};
	document.getElementById(searchClassName).onkeyup = function(e) {
		var code = e.keyCode || e.which;
		if (code !== 38 && code !== 40) {
			updateNodeList(this.innerHTML);
		}
	};
}

function contextListener() {
	document.addEventListener( "contextmenu", function(e) {
		graphInContext = clickInsideElement( e, graphClassName );

		if ( graphInContext ) {
			e.preventDefault();
			toggleMenuOn();
			positionMenu(e);
		} else {
			graphInContext = null;
			toggleMenuOff();
		}
	});
}

function clickListener() {
	document.addEventListener( "click", function(e) {
		var clickeElIsLink = clickInsideElement( e, contextMenuClassName );

		if ( clickeElIsLink ) {
			e.preventDefault();
			if (!clickInsideElement( e, searchClassName )) {
				toggleMenuOff();
			}
		} else {
			var button = e.which || e.button;
			if ( button === 1 ) {
				toggleMenuOff();
			}
		}
	});
}

function keyupListener() {
	window.onkeyup = function(e) {
		if ( e.keyCode === 27 ) {
			toggleMenuOff();
		}
	}
}

function resizeListener() {
	window.onresize = function(e) {
		toggleMenuOff();
	};
}

function toggleMenuOn() {
	if ( menuState !== 1 ) {
		menuState = 1;
		menu.classList.add( contextMenuActiveClassName );
		document.getElementById(searchClassName).focus();
		document.getElementById(contextMenuItemsClassName).scrollTop = 0;
	}
}

function toggleMenuOff() {
	if ( menuState !== 0 ) {
		menuState = 0;
		menu.classList.remove( contextMenuActiveClassName );
		document.getElementById(searchClassName).value = "";
		updateNodeList("");
	}
}

function positionMenu(e) {
	var doc = document.documentElement;
	var clientLeft = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0);
	var clientTop = (window.pageYOffset || doc.scrollTop)  - (doc.clientTop || 0);

	var pos = getPosition(e);
	clickCoordsX = pos.x - clientLeft;
	clickCoordsY = pos.y - clientTop;

	menuWidth = menu.offsetWidth + 4;
	menuHeight = menu.offsetHeight + 4;

	clientRight = clientLeft + window.innerWidth;
	clientBottom = clientTop + window.innerHeight;

	if ( (clientRight - clickCoordsX - clientLeft) < menuWidth ) {
		menu.style.left = clientRight - menuWidth + "px";
	} else {
		menu.style.left = clickCoordsX + clientLeft + "px";
	}

	if ( (clientBottom - clickCoordsY - clientTop) < menuHeight ) {
		menu.style.top = clientBottom - menuHeight + "px";
	} else {
		menu.style.top = clickCoordsY + clientTop + "px";
	}
}

init();

})();<|endoftext|>


<commit_before>var templateManager = function(fs) {

    //Private members
    var _fs = fs;
    var templatePath = "";
    var viewsPath = "";
    var templateContent = null;
    var fileEncoding = "utf-8";

    //Loads template html content from cache or fom file
    function loadTemplate() {
        return _fs.readFileSync(templatePath, fileEncoding);
    }

    function loadView(viewName, callback) {
        _fs.readFile(viewsPath + viewName,fileEncoding, function(err, content) {
            if (err) throw err;
            callback(content);
        });
    }

    //public members
    this.init = function(template, viewsFolder) {
        templatePath = template;
        viewsPath = viewsFolder;
        templateContent = loadTemplate();
    }

    this.processView = function(viewName, params) {

        if (templatePath.length <= 0) {
            throw "template not specified";
        }

        if (viewsPath.length <= 0) {
            throw "view directory not specified";
        }

        var templatePattern = /@[[a-zA-Z0-9]+]/g;
        var templatePlaceholders = templateContent.match(templatePattern);

        loadView(viewName,function(viewContent){
            debugger;
            var viewPattern = />>[A-Za-z0-9]+:(\r\n){1}(.+\r\n)*<</g;
            var viewTags = viewContent.match(viewPattern);
            debugger;
        });

    }

};

var fs = require("fs");

var man = new templateManager(fs);
man.init("./test/template/masterLayout.html", "./test/views/");

man.processView("index.html", null);<commit_msg>cdpace: changes<commit_after>var templateManager = function(fs) {

    //Private members
    var _fs = fs;
    var templatePath = "";
    var viewsPath = "";
    var templateContent = null;
    var templatePlaceholders = [];
    var fileEncoding = "utf-8";

    //Loads template html content from cache or fom file
    function loadTemplate() {
        var templatePattern = /@[[a-zA-Z0-9]+]/g;

        templateContent = _fs.readFileSync(templatePath, fileEncoding);
        templatePlaceholders = templateContent.match(templatePattern);

    }

    function loadView(viewName, callback) {
        _fs.readFile(viewsPath + viewName, fileEncoding, function(err, content) {
            if (err) throw err;
            callback(content);
        });
    }

    //public members
    this.init = function(template, viewsFolder) {
        templatePath = template;
        viewsPath = viewsFolder;
        loadTemplate();
    }

    this.processView = function(viewName, params) {

        if (templatePath.length <= 0) {
            throw "template not specified";
        }

        if (viewsPath.length <= 0) {
            throw "view directory not specified";
        }

        loadView(viewName, function(viewContent) {
            debugger;
            var viewPattern = />>[A-Za-z0-9]+:(\r\n){1}(.+\r\n)*<</g;
            var viewTags = viewContent.match(viewPattern);
        });

    }

};

var fs = require("fs");

var man = new templateManager(fs);
man.init("./test/template/masterLayout.html", "./test/views/");

man.processView("index.html", null);<|endoftext|>


<commit_before>var http = require('http'),
	fs = require('fs'),
	path = require('path'),
	util = require('./lib/util')

module.exports = {
	listen: listen,
	mount: mount,
	connect: connect,
	isRequireRequest: isRequireRequest,
	addPath: addPath,
	addFile: addFile,
	addReplacement: addReplacement,
	setOpts: setOpts,
	handleRequest: handleRequest
}

function addReplacement(searchFor, replaceWith) {
	util.addReplacement(searchFor, replaceWith)
	return module.exports
}

function addPath() {
	util.addPath.apply(util, arguments)
	return module.exports
}

function addFile() {
	util.addFile.apply(util, arguments)
	return module.exports
}

function listen(port, _opts) {
	if (!_opts) { _opts = { port:port }}
	else if(port) { _opts.port= port }
	setOpts(_opts)
	opts.handleAllRequests = true
	var server = http.createServer()
	mount(server)
	server.listen(opts.port, opts.host)
}

function mount(server, _opts, handleAllRequests) {
	setOpts(_opts)
	server.on('request', function(req, res) {
		if (isRequireRequest(req) || opts.handleAllRequests) {
			handleRequest(req, res)
		}
	})
	return server
}

function connect(opts) {
	setOpts(opts)
	return function require(req, res, next) {
		if (!isRequireRequest(req)) { return next() }
		handleRequest(req, res)
	}
}

function isRequireRequest(req) {
	return req.url.substr(1, opts.root.length) == opts.root
}

/* options
 *********/
var opts = {
	path: process.cwd(),
	root: 'require',
	port: null,
	host: null
}

function setOpts(_opts) {
	opts = util.extend(_opts, opts)
}

function _normalizeURL(url) {
	return url.replace(/\?.*/g, '').replace(/\/js$/, '.js')
}

/* request handlers
 ******************/
function handleRequest(req, res) {
	var reqPath = _normalizeURL(req.url).substr(opts.root.length + 2)
	if (!reqPath.match(/\.js$/)) {
		_handleMainModuleRequest(reqPath, req, res)
	} else {
		_handleModuleRequest(reqPath, res)
	}
}

function _handleMainModuleRequest(reqPath, req, res) {
	var prefix = util.hasAddedPath(reqPath.split('/')[0]) ? '' : './',
		modulePath = util.resolve(prefix + reqPath, opts.path)
	if (!modulePath) { return _sendError(res, 'Could not find module "'+reqPath+'" from "'+opts.path+'"') }

	try { var deps = util.getDependencyList(modulePath) }
	catch(err) { return _sendError(res, 'in util.getDependencyList: ' + err) }

	var response = ['__require__ = {}', 'require=function(){}']

	var userAgent = req.headers['user-agent'],
		isMobile = userAgent.match('iPad') || userAgent.match('iPod') || userAgent.match('iPhone') || userAgent.match('Android')

	if (isMobile) {
		// mobile clients take too long per js file request. Inline all the JS into a single request
		for (var i=0, dependency; dependency = deps[i]; i++) {
			response.push(_getModuleCode(res, dependency) + "\n")
		}
	} else {
		response.push(
			'__require__.__scripts = []',
			'__require__.__loadNext = function() {',
			'	var src = __require__.__scripts.shift()',
			'	var url = location.protocol+"//"+location.host + src',
			'	if (!src) { return }',
			'	document.getElementsByTagName("head")[0].appendChild(document.createElement("script")).src = url',
		'}')

		for (var i=0, dependency; dependency = deps[i]; i++) {
			var src = _getBase() + '/' + dependency
			response.push('__require__.__scripts.push("'+src+'")')
		}

		response.push('__require__.__loadNext()')
	}

	var buf = new Buffer(response.join('\n'), encoding='utf8')
	res.writeHead(200, { 'Cache-Control':'no-cache', 'Expires':'Fri, 31 Dec 1998 12:00:00 GMT', 'Content-Length':buf.length, 'Content-Type':'text/javascript' })
	res.end(buf)
}

function _handleModuleRequest(reqPath, res) {
	try { var code = _getModuleCode(res, reqPath) }
	catch(err) { return _sendError(res, err.stack || err) }

	code += '\n__require__.__loadNext()'

	var buf = new Buffer(code, encoding='utf8')
	res.writeHead(200, { 'Cache-Control':'no-cache', 'Expires':'Fri, 31 Dec 1998 12:00:00 GMT', 'Content-Length':buf.length, 'Content-Type':'text/javascript' })
	res.end(buf)
}

function _getModuleCode(res, reqPath) {
	var _closureStart = ';(function() {',
		_moduleDef = 'var module = {exports:{}}; var exports = module.exports;',
		_closureEnd = '})()'

	var code = util.getCode(reqPath),
		requireStatements = util.getRequireStatements(code)

	for (var i=0, requireStmnt; requireStmnt = requireStatements[i]; i++) {
		try { var depPath = util.resolveRequireStatement(requireStmnt, reqPath) }
		catch (e) { _sendError(res, e.message || e) }
		if (!depPath) { return _sendError(res, 'Could not resolve module') }

		code = code.replace(requireStmnt, '__require__["'+depPath+'"]')
	}

	return _closureStart
		+ _moduleDef
		+ code // all on the first line
		+ '\n__require__["'+reqPath+'"]=module.exports '+ _closureEnd
}

/* util
 ******/
function _sendError(res, msg) {
	if (msg) { msg = msg.replace(/\n/g, '\\n').replace(/"/g, '\\"') }
	res.writeHead(200)
	res.end('alert("error: ' + msg + '")')
}

function _getBase() {
	var host = opts.host,
		port = (!opts.usePagePort && opts.port)

	if (host && port) {
		return '//' + host + ':' + port + '/' + opts.root
	} else {
		return '/' + opts.root
	}
}
<commit_msg>make require work in dev mode with phantomjs<commit_after>var http = require('http'),
	fs = require('fs'),
	path = require('path'),
	util = require('./lib/util')

module.exports = {
	listen: listen,
	mount: mount,
	connect: connect,
	isRequireRequest: isRequireRequest,
	addPath: addPath,
	addFile: addFile,
	addReplacement: addReplacement,
	setOpts: setOpts,
	handleRequest: handleRequest
}

function addReplacement(searchFor, replaceWith) {
	util.addReplacement(searchFor, replaceWith)
	return module.exports
}

function addPath() {
	util.addPath.apply(util, arguments)
	return module.exports
}

function addFile() {
	util.addFile.apply(util, arguments)
	return module.exports
}

function listen(port, _opts) {
	if (!_opts) { _opts = { port:port }}
	else if(port) { _opts.port= port }
	setOpts(_opts)
	opts.handleAllRequests = true
	var server = http.createServer()
	mount(server)
	server.listen(opts.port, opts.host)
}

function mount(server, _opts, handleAllRequests) {
	setOpts(_opts)
	server.on('request', function(req, res) {
		if (isRequireRequest(req) || opts.handleAllRequests) {
			handleRequest(req, res)
		}
	})
	return server
}

function connect(opts) {
	setOpts(opts)
	return function require(req, res, next) {
		if (!isRequireRequest(req)) { return next() }
		handleRequest(req, res)
	}
}

function isRequireRequest(req) {
	return req.url.substr(1, opts.root.length) == opts.root
}

/* options
 *********/
var opts = {
	path: process.cwd(),
	root: 'require',
	port: null,
	host: null
}

function setOpts(_opts) {
	opts = util.extend(_opts, opts)
}

function _normalizeURL(url) {
	return url.replace(/\?.*/g, '').replace(/\/js$/, '.js')
}

/* request handlers
 ******************/
function handleRequest(req, res) {
	var reqPath = _normalizeURL(req.url).substr(opts.root.length + 2)
	if (!reqPath.match(/\.js$/)) {
		_handleMainModuleRequest(reqPath, req, res)
	} else {
		_handleModuleRequest(reqPath, res)
	}
}

function _handleMainModuleRequest(reqPath, req, res) {
	var prefix = util.hasAddedPath(reqPath.split('/')[0]) ? '' : './',
		modulePath = util.resolve(prefix + reqPath, opts.path)
	if (!modulePath) { return _sendError(res, 'Could not find module "'+reqPath+'" from "'+opts.path+'"') }

	try { var deps = util.getDependencyList(modulePath) }
	catch(err) { return _sendError(res, 'in util.getDependencyList: ' + err) }

	var response = ['__require__ = {}', 'require=function(){}']

	var userAgent = req.headers['user-agent']
	var isMobile = userAgent.match('iPad') || userAgent.match('iPod') || userAgent.match('iPhone') || userAgent.match('Android')
	var isPhantom = userAgent.match(/PhantomJS/)

	if (isMobile) {
		// mobile clients take too long per js file request. Inline all the JS into a single request
		for (var i=0, dependency; dependency = deps[i]; i++) {
			response.push(_getModuleCode(res, dependency) + "\n")
		}
	} else {
		response.push(
			'__require__.__scripts = []',
			'__require__.__loadNext = function() {',
			'	var src = __require__.__scripts.shift()',
			'	var url = location.protocol+"//"+location.host + src',
			'	if (!src) { return }',
			isPhantom ? '	setTimeout(function() {' : '',
			'		document.getElementsByTagName("head")[0].appendChild(document.createElement("script")).src = url',
			isPhantom ? '	}, 20)' : '',
		'}')

		for (var i=0, dependency; dependency = deps[i]; i++) {
			var src = _getBase() + '/' + dependency
			response.push('__require__.__scripts.push("'+src+'")')
		}

		response.push('__require__.__loadNext()')
	}

	var buf = new Buffer(response.join('\n'), encoding='utf8')
	res.writeHead(200, { 'Cache-Control':'no-cache', 'Expires':'Fri, 31 Dec 1998 12:00:00 GMT', 'Content-Length':buf.length, 'Content-Type':'text/javascript' })
	res.end(buf)
}

function _handleModuleRequest(reqPath, res) {
	try { var code = _getModuleCode(res, reqPath) }
	catch(err) { return _sendError(res, err.stack || err) }

	code += '\n__require__.__loadNext()'

	var buf = new Buffer(code, encoding='utf8')
	res.writeHead(200, { 'Cache-Control':'no-cache', 'Expires':'Fri, 31 Dec 1998 12:00:00 GMT', 'Content-Length':buf.length, 'Content-Type':'text/javascript' })
	res.end(buf)
}

function _getModuleCode(res, reqPath) {
	var _closureStart = ';(function() {',
		_moduleDef = 'var module = {exports:{}}; var exports = module.exports;',
		_closureEnd = '})()'

	var code = util.getCode(reqPath),
		requireStatements = util.getRequireStatements(code)

	for (var i=0, requireStmnt; requireStmnt = requireStatements[i]; i++) {
		try { var depPath = util.resolveRequireStatement(requireStmnt, reqPath) }
		catch (e) { _sendError(res, e.message || e) }
		if (!depPath) { return _sendError(res, 'Could not resolve module') }

		code = code.replace(requireStmnt, '__require__["'+depPath+'"]')
	}

	return _closureStart
		+ _moduleDef
		+ code // all on the first line
		+ '\n__require__["'+reqPath+'"]=module.exports '+ _closureEnd
}

/* util
 ******/
function _sendError(res, msg) {
	if (msg) { msg = msg.replace(/\n/g, '\\n').replace(/"/g, '\\"') }
	res.writeHead(200)
	res.end('alert("error: ' + msg + '")')
}

function _getBase() {
	var host = opts.host,
		port = (!opts.usePagePort && opts.port)

	if (host && port) {
		return '//' + host + ':' + port + '/' + opts.root
	} else {
		return '/' + opts.root
	}
}
<|endoftext|>


<commit_before>var _          = require('lodash');
var fs         = require('fs');
var path       = require('path');
var RSVP       = require('rsvp');
var quickTemp  = require('quick-temp');
var mkdirp     = require('mkdirp');
var browserify = require('browserify');
var walkSync   = require('walk-sync');
var glob       = require('glob');
var hashTree   = require('broccoli-kitchen-sink-helpers').hashTree;

function FastBrowserify(inputTree, options) {
  if (!(this instanceof FastBrowserify)) { return new FastBrowserify(inputTree, options); }

  this.options = this.getOptions(options || {});
  this.destDir = quickTemp.makeOrRemake(this, 'tmpDestDir');

  this.inputTree = inputTree;

  this.bundles = {};
  this.cache = {};
  this.watchFiles = {};
  this.packageCache = {};
}

FastBrowserify.prototype.getOptions = function(options) {
  var bundleExtension = options.bundleExtension || '.browserify';
  var outputExtension = options.outputExtension || '.js';
  var self = this;

  if (bundleExtension[0] != '.') { bundleExtension = '.' + bundleExtension; }
  if (outputExtension[0] != '.') { outputExtension = '.' + outputExtension; }

  var defaultBundleTemplate = {};
  defaultBundleTemplate['**/*' + bundleExtension] = {
    key: '**/*' + bundleExtension,
    glob: true,

    entryPoints: function(relativePath) {
      return [relativePath];
    },

    outputPath: function(relativePath) {
      // remove the bundle extension from the filename
      var regex = new RegExp(this.options.bundleExtension.replace(/\./, '\\.') + '$');
      var out = relativePath.replace(regex, '');

      // If the file already has the output file extension (e.g. bundle.js.browserify)
      // Then don't do anything, else add the output extension to the filename
      var outExtensionRegex = new RegExp(this.options.outputExtension.replace(/\./, '\\.') + '$');
      if (! out.match(outExtensionRegex)) {
        out = out + outputExtension;
      }

      return out;
    }
  };

  // add the bundle's key to the bundle's config, for convenience
  if (_.isObject(options.bundles)) {
    for (var key in options.bundles) {
      options.bundles[key].key = key;
    }
  }

  return _.extend({
    browserify: {},
    bundleExtension: bundleExtension,
    outputExtension: outputExtension,
    outputDirectory: null,
    bundles: defaultBundleTemplate
  }, options);
};

FastBrowserify.prototype.cleanup = function() {
  quickTemp.remove(this, 'tmpDestDir');
};

FastBrowserify.prototype.read = function(readTree) {
  var self = this;
  var promises = [];

  return readTree(this.inputTree).then(function(srcDir) {
    // remove output files that don't have a corrisponding input file anymore
    self.cleanupBundles();
    self.invalidateCache();

    for (var bundleNameOrGlob in self.options.bundles) {
      var bundleTemplate = self.options.bundles[bundleNameOrGlob];
      var bundleFiles = [];

      // If we're dealing with multiple bundle files in a single declaration
      // then the bundle key is a glob to the files that serve as the basis to
      // determine which bundles to create (they are often the entrypoints to the bundle)
      if (bundleTemplate.glob) {
        bundleFiles = glob.sync(bundleNameOrGlob, { cwd: srcDir, mark: true });
      } else {
        // If we're dealing with a single bundle declaration, then the bundle key
        // is the path to the output bundle, and the user must specify a list of
        // entryPoints
        bundleFiles = [bundleNameOrGlob];
      }

      bundleFiles.forEach(function(relativePath) {
        var bundle = self.bundles[relativePath];

        if (! bundle) {
          var outputBasename;
          var outputRelativePath;
          var outputAbsolutePath;
          var entryPoints;

          if (bundleTemplate.glob) {
            if (! _.isFunction(bundleTemplate.outputPath)) {
              throw "When glob == true, outputPath must be a function that returns the output bundle filename";
            }
            outputRelativePath = bundleTemplate.outputPath.call(self, relativePath);
          } else {
            if (bundleTemplate.outputPath) {
              throw "outputPath is only valid for glob bundle specifications, specify the output bundle filename in the key of the bundle specification";
            }
            outputRelativePath = relativePath;
          }

          // Add on the globally specified output directory if specified
          if (self.options.outputDirectory && _.isString(self.options.outputDirectory)) {
            outputRelativePath = path.join(self.options.outputDirectory, outputRelativePath);
          }

          entryPoints = self.readEntryPoints(srcDir, relativePath, bundleTemplate);

          if (entryPoints.absolute.length === 0) {
            console.log("Bundle specified by \"", relativePath, "\" does not have any entry files");
          } else {
            // hash the entryPoints so we can tell if they change so we can update
            // the browerify optins with the new files
            var entryPointsHashes = [];
            for (var i = 0; i < entryPoints.absolute.length; ++i) {
              entryPointsHashes.push(hashTree(entryPoints.absolute[i]));
            }

            outputBasename = path.basename(outputRelativePath);
            outputAbsolutePath = path.resolve(self.destDir, outputRelativePath);

            bundle = {
              key: relativePath,
              srcDir: srcDir,
              template: bundleTemplate,
              browserify: null,
              entryPoints: entryPoints.absolute,
              entryPointsHashes: entryPointsHashes,
              outputBasename: outputBasename,
              outputFileName: outputAbsolutePath,
              browserifyOptions: {},
              dependentFileNames: {}
            };

            bundle.browserifyOptions = _.extend(bundle.browserifyOptions, {
              basedir: srcDir,
              cache: self.cache,
              packageCache: self.packageCache,
              fullPaths: true,
              extensions: ['.js', self.options.bundleExtension].concat(self.options.browserify.extensions || []),
              entries: entryPoints.relative
            });

            bundle.browserify = browserify(bundle.browserifyOptions);

            bundle.browserify.on('dep', function(dep) {
              if (typeof dep.id == 'string') {
                bundle.browserifyOptions.cache[dep.id] = dep;
              }
              if (typeof dep.file == 'string') {
                var file = dep.file;
                if (file[0] == '.') {
                  file = path.resolve(dep.basedir, file);
                }
                self.watchFiles[file] = hashTree(file);
                bundle.dependentFileNames[file] = file;
              }
            });

            bundle.browserify.on('file', function(file) {
              self.watchFiles[file] = hashTree(file);
              bundle.dependentFileNames[file] = file;
            });

            bundle.browserify.on('package', function(pkg) {
              var packageFile = path.join(pkg.__dirname, 'package.json');
              self.watchFiles[packageFile] = hashTree(packageFile);
              bundle.dependentFileNames[packageFile] = packageFile;
            });

            self.bundles[relativePath] = bundle;

            // Create the target directory in the destination
            mkdirp.sync(path.dirname(bundle.outputFileName));

            promise = self.bundle(bundle);
            promises.push(promise);
          }
        }
      });
    }

    return RSVP.all(promises).then(function(outputFiles) {
      return self.destDir;
    });
  });
};

FastBrowserify.prototype.readEntryPoints = function(srcDir, bundleKey, bundleTemplate) {
  var entryPoints = [];
  var entryPointsAbsolute = [];
  var entryPointGlobs = [];
  var i;
  var entryPoint;

  if (_.isFunction(bundleTemplate.entryPoints)) {
    entryPointGlobs = bundleTemplate.entryPoints.call(this, bundleKey);
  } else if (_.isArray(bundleTemplate.entryPoints)) {
    entryPointGlobs = bundleTemplate.entryPoints;
  } else if (_.isString(bundleTemplate.entryPoints)) {
    entryPointGlobs = [bundleTemplate.entryPoints];
  } else {
    // If this is a glob bundle specification, then let's assume that the entryPoints are the results of the glob
    if (bundleTemplate.glob) {
      entryPointGlobs = [bundleKey];
    } else {
      throw "You must specify entryPoints as a function, array, or string";
    }
  }

  // go through the entrypoints the user specified and resolve the globs
  entryPointGlobs.forEach(function(g) {
    entryPoints = entryPoints.concat(glob.sync(g, { cwd: srcDir, nodir: true }));
  });

  for (i = 0; i < entryPoints.length; ++i) {
    entryPoint = entryPoints[i];
    if (entryPoint[0] !== '/') {
      entryPointsAbsolute[i] = path.resolve(srcDir, entryPoint);
    }
  }

  // GO through the entry points and prepend ./ to their names to make them relative commonjs modules
  for (i = 0; i < entryPoints.length; ++i) {
    entryPoint = entryPoints[i];
    if (entryPoint[0] !== '/' && ! entryPoint.match(/^\.\//)) {
      entryPoints[i] = './' + entryPoint;
    }
  }

  return {
    relative: entryPoints,
    absolute: entryPointsAbsolute
  };
};

FastBrowserify.prototype.invalidateCache = function() {
  var outputFileMTimes = {};
  var bundle;
  var bundleKey;
  var file;
  var i;
  var time;
  var fileMTime;

  for (bundleKey in this.bundles) {
    bundle = this.bundles[bundleKey];
    if (fs.existsSync(bundle.outputFileName)) {
      time = fs.statSync(bundle.outputFileName).mtime.getTime();
      outputFileMTimes[bundleKey] = time;
    }
  }

  var invalidatedBundles = [];
  var invalidatedFiles = [];

  // Look for watched files that have changed, and mark them for deletion
  for (file in this.watchFiles) {
    if (! fs.existsSync(file) || hashTree(file) !== this.watchFiles[file]) {
      invalidatedFiles.push(file);

      // look through the bundles to see if any of them depend on this file and are older than this file
      for (bundleKey in this.bundles) {
        bundle = this.bundles[bundleKey];

        // look through this bundle's dependencies and test if they are newer than the output file
        if (bundle.dependentFileNames[file] && ! _.include(invalidatedBundles, bundleKey)) {
          invalidatedBundles.push(bundleKey);
        }
      }
    }
  }

  // if the entry file names are different now than before, invalidate the bundle
  for (bundleKey in this.bundles) {
    bundle = this.bundles[bundleKey];
    var newEntries = this.readEntryPoints(bundle.srcDir, bundle.key, bundle.template);
    var entries = bundle.entryPoints;
    // if the entrypoints have changed, invalidate the bundle so we can rebuild with the new entry point
    for (i = 0; i < newEntries.absolute.length; ++i) {
      if (i >= entries.length || newEntries.absolute[i] != entries[i]) {
        if (! _.include(invalidatedBundles, bundleKey)) {
          invalidatedBundles.push(bundleKey);
        }
      }
    }
  }

  // remove the invalidated files from the cache
  invalidatedFiles.forEach(function(file) {
    delete this.cache[file];
    delete this.watchFiles[file];
  }.bind(this));

  invalidatedBundles.forEach(function(bundleKey) {
    delete this.bundles[bundleKey];
  }.bind(this));
};

FastBrowserify.prototype.cleanupBundles = function() {
  // remove stale output files
  var bundlesToDelete = [];

  for (var key in this.bundles) {
    var bundle = this.bundles[key];

    var anyFilesExist = _.any(bundle.entryPoints, fs.existsSync);

    if (! anyFilesExist) {
      if (fs.existsSync(bundle.outputFileName)) {
        fs.unlinkSync(bundle.outputFileName);
      }
      bundlesToDelete.push(key);
    }
  }

  bundlesToDelete.forEach(function(key) {
    delete this.bundles[key];
  }.bind(this));
};

FastBrowserify.prototype.bundle = function(bundle) {
  return new RSVP.Promise(function(resolve, reject) {
    // clear the dependent file name list
    // we want to have a fresh dependency list every time we build
    // this way, the bundle can be skipped if non of its dependencies change
    bundle.dependentFileNames = {};

    bundle.browserify.bundle(function(err, data) {
      if (err) {
        reject(err);
      } else {
        fs.writeFileSync(bundle.outputFileName, data);
        resolve(bundle.outputFileName);
      }
    });
  });
};

module.exports = FastBrowserify;
<commit_msg>Pass browserify options into the browserify function<commit_after>var _          = require('lodash');
var fs         = require('fs');
var path       = require('path');
var RSVP       = require('rsvp');
var quickTemp  = require('quick-temp');
var mkdirp     = require('mkdirp');
var browserify = require('browserify');
var walkSync   = require('walk-sync');
var glob       = require('glob');
var hashTree   = require('broccoli-kitchen-sink-helpers').hashTree;

function FastBrowserify(inputTree, options) {
  if (!(this instanceof FastBrowserify)) { return new FastBrowserify(inputTree, options); }

  this.options = this.getOptions(options || {});
  this.destDir = quickTemp.makeOrRemake(this, 'tmpDestDir');

  this.inputTree = inputTree;

  this.bundles = {};
  this.cache = {};
  this.watchFiles = {};
  this.packageCache = {};
}

FastBrowserify.prototype.getOptions = function(options) {
  var bundleExtension = options.bundleExtension || '.browserify';
  var outputExtension = options.outputExtension || '.js';
  var self = this;

  if (bundleExtension[0] != '.') { bundleExtension = '.' + bundleExtension; }
  if (outputExtension[0] != '.') { outputExtension = '.' + outputExtension; }

  var defaultBundleTemplate = {};
  defaultBundleTemplate['**/*' + bundleExtension] = {
    key: '**/*' + bundleExtension,
    glob: true,

    entryPoints: function(relativePath) {
      return [relativePath];
    },

    outputPath: function(relativePath) {
      // remove the bundle extension from the filename
      var regex = new RegExp(this.options.bundleExtension.replace(/\./, '\\.') + '$');
      var out = relativePath.replace(regex, '');

      // If the file already has the output file extension (e.g. bundle.js.browserify)
      // Then don't do anything, else add the output extension to the filename
      var outExtensionRegex = new RegExp(this.options.outputExtension.replace(/\./, '\\.') + '$');
      if (! out.match(outExtensionRegex)) {
        out = out + outputExtension;
      }

      return out;
    }
  };

  // add the bundle's key to the bundle's config, for convenience
  if (_.isObject(options.bundles)) {
    for (var key in options.bundles) {
      options.bundles[key].key = key;
    }
  }

  return _.extend({
    browserify: {
      debug: true
    },
    bundleExtension: bundleExtension,
    outputExtension: outputExtension,
    outputDirectory: null,
    bundles: defaultBundleTemplate
  }, options);
};

FastBrowserify.prototype.cleanup = function() {
  quickTemp.remove(this, 'tmpDestDir');
};

FastBrowserify.prototype.read = function(readTree) {
  var self = this;
  var promises = [];

  return readTree(this.inputTree).then(function(srcDir) {
    // remove output files that don't have a corrisponding input file anymore
    self.cleanupBundles();
    self.invalidateCache();

    for (var bundleNameOrGlob in self.options.bundles) {
      var bundleTemplate = self.options.bundles[bundleNameOrGlob];
      var bundleFiles = [];

      // If we're dealing with multiple bundle files in a single declaration
      // then the bundle key is a glob to the files that serve as the basis to
      // determine which bundles to create (they are often the entrypoints to the bundle)
      if (bundleTemplate.glob) {
        bundleFiles = glob.sync(bundleNameOrGlob, { cwd: srcDir, mark: true });
      } else {
        // If we're dealing with a single bundle declaration, then the bundle key
        // is the path to the output bundle, and the user must specify a list of
        // entryPoints
        bundleFiles = [bundleNameOrGlob];
      }

      bundleFiles.forEach(function(relativePath) {
        var bundle = self.bundles[relativePath];

        if (! bundle) {
          var outputBasename;
          var outputRelativePath;
          var outputAbsolutePath;
          var entryPoints;

          if (bundleTemplate.glob) {
            if (! _.isFunction(bundleTemplate.outputPath)) {
              throw "When glob == true, outputPath must be a function that returns the output bundle filename";
            }
            outputRelativePath = bundleTemplate.outputPath.call(self, relativePath);
          } else {
            if (bundleTemplate.outputPath) {
              throw "outputPath is only valid for glob bundle specifications, specify the output bundle filename in the key of the bundle specification";
            }
            outputRelativePath = relativePath;
          }

          // Add on the globally specified output directory if specified
          if (self.options.outputDirectory && _.isString(self.options.outputDirectory)) {
            outputRelativePath = path.join(self.options.outputDirectory, outputRelativePath);
          }

          entryPoints = self.readEntryPoints(srcDir, relativePath, bundleTemplate);

          if (entryPoints.absolute.length === 0) {
            console.log("Bundle specified by \"", relativePath, "\" does not have any entry files");
          } else {
            // hash the entryPoints so we can tell if they change so we can update
            // the browerify optins with the new files
            var entryPointsHashes = [];
            for (var i = 0; i < entryPoints.absolute.length; ++i) {
              entryPointsHashes.push(hashTree(entryPoints.absolute[i]));
            }

            outputBasename = path.basename(outputRelativePath);
            outputAbsolutePath = path.resolve(self.destDir, outputRelativePath);

            bundle = {
              key: relativePath,
              srcDir: srcDir,
              template: bundleTemplate,
              browserify: null,
              entryPoints: entryPoints.absolute,
              entryPointsHashes: entryPointsHashes,
              outputBasename: outputBasename,
              outputFileName: outputAbsolutePath,
              browserifyOptions: _.clone(self.options.browserify),
              dependentFileNames: {}
            };

            bundle.browserifyOptions = _.extend(bundle.browserifyOptions, {
              basedir: srcDir,
              cache: self.cache,
              packageCache: self.packageCache,
              fullPaths: true,
              extensions: ['.js', self.options.bundleExtension].concat(self.options.browserify.extensions || []),
              entries: entryPoints.relative
            });

            bundle.browserify = browserify(bundle.browserifyOptions);

            bundle.browserify.on('dep', function(dep) {
              if (typeof dep.id == 'string') {
                bundle.browserifyOptions.cache[dep.id] = dep;
              }
              if (typeof dep.file == 'string') {
                var file = dep.file;
                if (file[0] == '.') {
                  file = path.resolve(dep.basedir, file);
                }
                self.watchFiles[file] = hashTree(file);
                bundle.dependentFileNames[file] = file;
              }
            });

            bundle.browserify.on('file', function(file) {
              self.watchFiles[file] = hashTree(file);
              bundle.dependentFileNames[file] = file;
            });

            bundle.browserify.on('package', function(pkg) {
              var packageFile = path.join(pkg.__dirname, 'package.json');
              self.watchFiles[packageFile] = hashTree(packageFile);
              bundle.dependentFileNames[packageFile] = packageFile;
            });

            self.bundles[relativePath] = bundle;

            // Create the target directory in the destination
            mkdirp.sync(path.dirname(bundle.outputFileName));

            promise = self.bundle(bundle);
            promises.push(promise);
          }
        }
      });
    }

    return RSVP.all(promises).then(function(outputFiles) {
      return self.destDir;
    });
  });
};

FastBrowserify.prototype.readEntryPoints = function(srcDir, bundleKey, bundleTemplate) {
  var entryPoints = [];
  var entryPointsAbsolute = [];
  var entryPointGlobs = [];
  var i;
  var entryPoint;

  if (_.isFunction(bundleTemplate.entryPoints)) {
    entryPointGlobs = bundleTemplate.entryPoints.call(this, bundleKey);
  } else if (_.isArray(bundleTemplate.entryPoints)) {
    entryPointGlobs = bundleTemplate.entryPoints;
  } else if (_.isString(bundleTemplate.entryPoints)) {
    entryPointGlobs = [bundleTemplate.entryPoints];
  } else {
    // If this is a glob bundle specification, then let's assume that the entryPoints are the results of the glob
    if (bundleTemplate.glob) {
      entryPointGlobs = [bundleKey];
    } else {
      throw "You must specify entryPoints as a function, array, or string";
    }
  }

  // go through the entrypoints the user specified and resolve the globs
  entryPointGlobs.forEach(function(g) {
    entryPoints = entryPoints.concat(glob.sync(g, { cwd: srcDir, nodir: true }));
  });

  for (i = 0; i < entryPoints.length; ++i) {
    entryPoint = entryPoints[i];
    if (entryPoint[0] !== '/') {
      entryPointsAbsolute[i] = path.resolve(srcDir, entryPoint);
    }
  }

  // GO through the entry points and prepend ./ to their names to make them relative commonjs modules
  for (i = 0; i < entryPoints.length; ++i) {
    entryPoint = entryPoints[i];
    if (entryPoint[0] !== '/' && ! entryPoint.match(/^\.\//)) {
      entryPoints[i] = './' + entryPoint;
    }
  }

  return {
    relative: entryPoints,
    absolute: entryPointsAbsolute
  };
};

FastBrowserify.prototype.invalidateCache = function() {
  var outputFileMTimes = {};
  var bundle;
  var bundleKey;
  var file;
  var i;
  var time;
  var fileMTime;

  for (bundleKey in this.bundles) {
    bundle = this.bundles[bundleKey];
    if (fs.existsSync(bundle.outputFileName)) {
      time = fs.statSync(bundle.outputFileName).mtime.getTime();
      outputFileMTimes[bundleKey] = time;
    }
  }

  var invalidatedBundles = [];
  var invalidatedFiles = [];

  // Look for watched files that have changed, and mark them for deletion
  for (file in this.watchFiles) {
    if (! fs.existsSync(file) || hashTree(file) !== this.watchFiles[file]) {
      invalidatedFiles.push(file);

      // look through the bundles to see if any of them depend on this file and are older than this file
      for (bundleKey in this.bundles) {
        bundle = this.bundles[bundleKey];

        // look through this bundle's dependencies and test if they are newer than the output file
        if (bundle.dependentFileNames[file] && ! _.include(invalidatedBundles, bundleKey)) {
          invalidatedBundles.push(bundleKey);
        }
      }
    }
  }

  // if the entry file names are different now than before, invalidate the bundle
  for (bundleKey in this.bundles) {
    bundle = this.bundles[bundleKey];
    var newEntries = this.readEntryPoints(bundle.srcDir, bundle.key, bundle.template);
    var entries = bundle.entryPoints;
    // if the entrypoints have changed, invalidate the bundle so we can rebuild with the new entry point
    for (i = 0; i < newEntries.absolute.length; ++i) {
      if (i >= entries.length || newEntries.absolute[i] != entries[i]) {
        if (! _.include(invalidatedBundles, bundleKey)) {
          invalidatedBundles.push(bundleKey);
        }
      }
    }
  }

  // remove the invalidated files from the cache
  invalidatedFiles.forEach(function(file) {
    delete this.cache[file];
    delete this.watchFiles[file];
  }.bind(this));

  invalidatedBundles.forEach(function(bundleKey) {
    delete this.bundles[bundleKey];
  }.bind(this));
};

FastBrowserify.prototype.cleanupBundles = function() {
  // remove stale output files
  var bundlesToDelete = [];

  for (var key in this.bundles) {
    var bundle = this.bundles[key];

    var anyFilesExist = _.any(bundle.entryPoints, fs.existsSync);

    if (! anyFilesExist) {
      if (fs.existsSync(bundle.outputFileName)) {
        fs.unlinkSync(bundle.outputFileName);
      }
      bundlesToDelete.push(key);
    }
  }

  bundlesToDelete.forEach(function(key) {
    delete this.bundles[key];
  }.bind(this));
};

FastBrowserify.prototype.bundle = function(bundle) {
  return new RSVP.Promise(function(resolve, reject) {
    // clear the dependent file name list
    // we want to have a fresh dependency list every time we build
    // this way, the bundle can be skipped if non of its dependencies change
    bundle.dependentFileNames = {};

    bundle.browserify.bundle(function(err, data) {
      if (err) {
        reject(err);
      } else {
        fs.writeFileSync(bundle.outputFileName, data);
        resolve(bundle.outputFileName);
      }
    });
  });
};

module.exports = FastBrowserify;
<|endoftext|>


<commit_before>tm.main(function() {
    var app = tm.hybrid.Application("#canvas2d", "#canvas3d");
    app.resize(640, 960).fitWindow().run();

    app.replaceScene(tm.game.LoadingScene({
        width: 640, height: 960,
        assets: {
            hiyoko: "assets/hiyoco_nomal_full.png",

            //urlをモデルデータ、モーションデータのの順に指定
            miku: {
                type: "mmd",
                url: ["pmd/miku_v2.pmd", "vmd/wavefile_v2.vmd"],
            },
        },
        nextScene: MikuOnStage,
    }));
});

tm.define("MikuOnStage", {
    superClass: "tm.hybrid.Scene", // tm.app.Sceneの3D向け拡張
    init: function() {
        this.superInit();

        // カメラ調整
        this.camera.setPosition(0, 20, 30);
        this.camera.lookAt(new THREE.Vector3(0, 10, 0));

        // ライトを動かす
        this.directionalLight.setPosition(0, 100, -80);

        // メッシュを表示する
        var miku = tm.hybrid.Mesh("miku")
            .addChildTo(this)
            .setPosition(0, 0, 0)
            .on("enterframe", function() {
                if (this.rolling) this.rotationY += 10; // Y軸回転
            });
        miku.rolling = false;

        // 2Dスプライトとの併用も可能
        var hiyoko = tm.display.Sprite("hiyoko", 32, 32)
            .setScale(4)
            .setFrameIndex(0)
            .addChildTo(this)
            .on("enterframe", function() {
                this.x += this.vx * 10;
                this.y += this.vy * 10;
                if (this.x < 0 || 640 < this.x) this.vx *= -1;
                if (this.y < 0 || 960 < this.y) this.vy *= -1;

                this.frameIndex = (this.frameIndex + 1) % 4;
                this.rotation += 2;
            });
        hiyoko.vx = 1;
        hiyoko.vy = 1;

        tm.ui.FlatButton({ text: "かいてん" })
            .setPosition(320, 100)
            .addChildTo(this)
            .on("push", function() {
                miku.rolling = !miku.rolling;
                this.label.text = miku.rolling ? "とまる" : "かいてん";
            });
        this.time = 0;
    },
    update: function(e) {
        var delta = 1/20;
        THREE.AnimationHandler.update(delta);
    },
});
<commit_msg>change delta time<commit_after>tm.main(function() {
    var app = tm.hybrid.Application("#canvas2d", "#canvas3d");
    app.resize(640, 960).fitWindow().run();
    app.enableStats();

    app.replaceScene(tm.game.LoadingScene({
        width: 640, height: 960,
        assets: {
            hiyoko: "assets/hiyoco_nomal_full.png",

            //urlをモデルデータ、モーションデータのの順に指定
            miku: {
                type: "mmd",
                url: ["pmd/miku_v2.pmd", "vmd/wavefile_v2.vmd"],
            },
        },
        nextScene: MikuOnStage,
    }));
});

tm.define("MikuOnStage", {
    superClass: "tm.hybrid.Scene", // tm.app.Sceneの3D向け拡張
    init: function() {
        this.superInit();

        // カメラ調整
        this.camera.setPosition(0, 20, 30);
        this.camera.lookAt(new THREE.Vector3(0, 10, 0));

        // ライトを動かす
        this.directionalLight.setPosition(0, 100, -80);

        // メッシュを表示する
        var miku = tm.hybrid.Mesh("miku")
            .addChildTo(this)
            .setPosition(0, 0, 0)
            .on("enterframe", function() {
                if (this.rolling) this.rotationY += 10; // Y軸回転
            });
        miku.rolling = false;

        // 2Dスプライトとの併用も可能
        var hiyoko = tm.display.Sprite("hiyoko", 32, 32)
            .setScale(4)
            .setFrameIndex(0)
            .addChildTo(this)
            .on("enterframe", function() {
                this.x += this.vx * 10;
                this.y += this.vy * 10;
                if (this.x < 0 || 640 < this.x) this.vx *= -1;
                if (this.y < 0 || 960 < this.y) this.vy *= -1;

                this.frameIndex = (this.frameIndex + 1) % 4;
                this.rotation += 2;
            });
        hiyoko.vx = 1;
        hiyoko.vy = 1;

        tm.ui.FlatButton({ text: "かいてん" })
            .setPosition(320, 100)
            .addChildTo(this)
            .on("push", function() {
                miku.rolling = !miku.rolling;
                this.label.text = miku.rolling ? "とまる" : "かいてん";
            });
        this.time = 0;
    },
    update: function(app) {
        var delta = app.deltaTime/1000;
        THREE.AnimationHandler.update(delta);
    },
});
<|endoftext|>


<commit_before>/*
==========================
How Easy! Slideshow.
==========================
*/
var HESlideshow = new(function() {
    var nextBtn = document.getElementById('nextBtn'),
        prevBtn = document.getElementById('prevBtn');

    this.basicSetting = function(config) {
        settingDOM(config);
    };
    var settingDOM = function(config) {
        //basic dom setting
        var slideContainer = document.querySelector(config.slideContainer),
            imgContent = document.querySelector(config.imgContent),
            imgBlock = document.querySelectorAll(config.imgBlock);
        if (slideContainer.length <= 0 || imgContent.length <= 0 || imgBlock.length <= 0) {
            console.log('please key-in true element');
        } else {
            imgContent.setAttribute('style', setContentWidth(imgBlock));
            basicAnimate();
        };

        function basicAnimate() {
            imgContent.addEventListener('mouseover', function() {

                // nextBtn.style.opacity = '0.8';
                // prevBtn.style.opacity = '0.8';
            });
            imgContent.addEventListener('mouseout', function() {

                // nextBtn.style.opacity = '0';
                // prevBtn.style.opacity = '0';
            });
        }
    };

    function fadeIn(dom, Num, speed) {
    }

    function setContentWidth(Detail) {
        //content width count
        var imgContentWidth = 0;
        for (var i = 0; i < Detail.length; i++) {
            imgContentWidth += outerWH(Detail[i])[0];
        }
        var returnData = 'width:' + imgContentWidth * 2 + 'px';
        return returnData;
    }

    function outerWH(dom) {
        // block outer width & outer height
        var widthDom = dom.offsetWidth,
            heightDom = dom.offsetHeight;
        var defaultStyle = getComputedStyle(dom);
        widthDom += parseInt(defaultStyle.marginLeft) + parseInt(defaultStyle.marginRight);
        heightDom += parseInt(defaultStyle.marginTop) + parseInt(defaultStyle.marginBottom);
        return [widthDom, heightDom];
    }

    function animate() {

    }

    // /* -- Auto Slide show -- */
    // this.setAuto = false;
    // this.AutoTime = 2000;

    // /* -- Image resize -- */
    // this.Imgresize = false;

    // /* -- set slide show DOM -- */
    // this.slideContainer = '';
    // this.imgContent = '';
    // this.imgBlock = '';

    // /* -- Slide show effect -- */
    // this.effectStyle = 'basic';

    // /* -- flicking dot -- */
    // this.flickingDot = false;

    // function activeBtn() {
    //     var nextBtn = function() {
    //         var nextBtn = document.getElementById('nextBtn');
    //     }
    //     var prevBtn = function() {
    //         var prevBtn = document.getElementById('prevBtn');
    //     }
    //     var flickingDot = function() {}
    // }

})();

HESlideshow.basicSetting({
    slideContainer: '.slideContainer',
    imgContent: '.imgTotal',
    imgBlock: '.imgBlock'
});
<commit_msg>cut two part of animate<commit_after>/*
==========================
How Easy! Slideshow.
==========================
*/
var HESlideshow = new(function() {

    this.basicSetting = function(config) {
        Setting(config);
    };
    var Setting = function(config) {
        //basic data get
        var slideContainer = document.querySelector(config.slideContainer),
            imgContent = document.querySelector(config.imgContent),
            imgBlock = document.querySelectorAll(config.imgBlock),
            effect = (config.effect == undefined) ? 'basic' : config.effect,
            effectSpeed = (config.effectSpeed == undefined) ? 2000 : config.effectSpeed,
            auto = (config.auto == undefined) ? true : config.auto,
            autoSpeed = (config.autoSpeed == undefined) ? 2000 : config.autoSpeed;
        // put Dom to setting
        settingDOM(slideContainer, imgContent, imgBlock);
        var effectSuit = [effect, effectSpeed];
        HESlideEffect.putEffect(btnReaction(slideContainer), effectSuit);
    }

    var settingDOM = function(slideContainer, imgContent, imgBlock) {
        //basic dom setting
        if (slideContainer.length <= 0 || imgContent.length <= 0 || imgBlock.length <= 0) {
            console.log('please key-in true element');
        } else {
            // set basic image width.
            imgContent.setAttribute('style', setContentWidth(imgBlock));
        };
    };

    function btnReaction(slideBlock) {
        //provide Btn dom
        var nextBtn = document.getElementById('nextBtn'),
            prevBtn = document.getElementById('prevBtn');
        return [slideBlock, nextBtn, prevBtn];
    }

    function setContentWidth(Detail) {
        //content width count
        var imgContentWidth = 0;
        for (var i = 0; i < Detail.length; i++) {
            imgContentWidth += outerWH(Detail[i])[0];
        }
        var returnData = 'width:' + imgContentWidth * 2 + 'px';
        return returnData;
    }

    function outerWH(dom) {
        // block outer width & outer height
        var widthDom = dom.offsetWidth,
            heightDom = dom.offsetHeight;
        var defaultStyle = getComputedStyle(dom);
        widthDom += parseInt(defaultStyle.marginLeft) + parseInt(defaultStyle.marginRight);
        heightDom += parseInt(defaultStyle.marginTop) + parseInt(defaultStyle.marginBottom);
        return [widthDom, heightDom];
    }

    // /* -- Auto Slide show -- */
    // this.setAuto = false;
    // this.AutoTime = 2000;

    // /* -- Image resize -- */
    // this.Imgresize = false;

    // /* -- set slide show DOM -- */
    // this.slideContainer = '';
    // this.imgContent = '';
    // this.imgBlock = '';

    // /* -- Slide show effect -- */
    // this.effectStyle = 'basic';

    // /* -- flicking dot -- */
    // this.flickingDot = false;

    // function activeBtn() {
    //     var nextBtn = function() {
    //         var nextBtn = document.getElementById('nextBtn');
    //     }
    //     var prevBtn = function() {
    //         var prevBtn = document.getElementById('prevBtn');
    //     }
    //     var flickingDot = function() {}
    // }

})();

// all effect
var HESlideEffect = new(function() {
    this.putEffect = function(effectDom, effectSuit) {
        if (Array.isArray(effectDom) && Array.isArray(effectSuit)) {
            //basic effect is fadeIn & fadeout
            setupEffect(effectDom, effectSuit);
        }
    };

    function setupEffect(dom, setting) {
        var slideContainer = dom[0],
            nextBtn = dom[1],
            prevBtn = dom[2];
        var effectName = setting[0],
            effectSpeed = setting[1];
        slideContainer.addEventListener('mouseenter', function(){})
        slideContainer.addEventListener('mouseleave', function(){})
    }

})();

HESlideshow.basicSetting({
    slideContainer: '.slideContainer',
    imgContent: '.imgTotal',
    imgBlock: '.imgBlock',
    effect: 'basic'
});
<|endoftext|>


<commit_before>/* eslint strict: 0 */
'use strict';

process.env.NODE_ENV = process.env.NODE_ENV || 'production';

const electron = require('electron');
const storage = require('electron-json-storage');
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;
const Menu = electron.Menu;
const crashReporter = electron.crashReporter;
const shell = electron.shell;
const config = require('./config');
let menu;
let template;
let mainWindow = null;

crashReporter.start({
  productName: 'doubanFMac',
  companyName: 'darmody',
  submitURL: 'http://github.com/darmody/doubanFMac/issues'
});

if (process.env.NODE_ENV === 'development') {
  require('electron-debug')();
}

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') app.quit();
});

app.on('ready', () => {
  mainWindow = new BrowserWindow(config.window);

  const webContents = mainWindow.webContents;

  // manipulate cookies for douban
  const getDoubanCookies = (webContents) => {
    storage.get(config.electronStorageKey, (error, data) => {
      if (error) {
        return console.log('Electron storage read error.', error);
      }
      if (data.cookies && data.cookies.length > 0) {
        data.cookies.forEach((cookie) => {
          webContents.session.cookies.set({
            name: cookie[0],
            value: cookie[1],
            url: 'http://douban.fm',
          }, (error) => {
            if (error) console.log('Douban cookie set error.', error);
          });
        });
      }
    });

  };
  const setDoubanCookies = (webContents, originalURL, headers) => {
    if (originalURL !== 'http://douban.fm/j/login') return;

    const cookies = (headers['set-cookie'] || []).map((cookie) => {
      return cookie.split(';')[0].split('=');
    });

    storage.set(config.electronStorageKey, { cookies }, (error) => {
      if (error) console.log('Douban cookie save to storage error', error);
    });
  };

  webContents.on('did-get-response-details', (event, status, newURL, originalURL, code, method, referrer, headers) => {
    setDoubanCookies(webContents, originalURL, headers);
  });

  getDoubanCookies(webContents);

  mainWindow.loadURL(`file://${__dirname}/app/app.html`);

  mainWindow.on('closed', () => {
    mainWindow = null;
  });

  if (process.env.NODE_ENV === 'development') {
    mainWindow.openDevTools();
  }

  if (process.platform === 'darwin') {
    template = [{
      label: 'Electron',
      submenu: [{
        label: 'About ElectronReact',
        selector: 'orderFrontStandardAboutPanel:'
      }, {
        type: 'separator'
      }, {
        label: 'Services',
        submenu: []
      }, {
        type: 'separator'
      }, {
        label: 'Hide ElectronReact',
        accelerator: 'Command+H',
        selector: 'hide:'
      }, {
        label: 'Hide Others',
        accelerator: 'Command+Shift+H',
        selector: 'hideOtherApplications:'
      }, {
        label: 'Show All',
        selector: 'unhideAllApplications:'
      }, {
        type: 'separator'
      }, {
        label: 'Quit',
        accelerator: 'Command+Q',
        click() {
          app.quit();
        }
      }]
    }, {
      label: 'Edit',
      submenu: [{
        label: 'Undo',
        accelerator: 'Command+Z',
        selector: 'undo:'
      }, {
        label: 'Redo',
        accelerator: 'Shift+Command+Z',
        selector: 'redo:'
      }, {
        type: 'separator'
      }, {
        label: 'Cut',
        accelerator: 'Command+X',
        selector: 'cut:'
      }, {
        label: 'Copy',
        accelerator: 'Command+C',
        selector: 'copy:'
      }, {
        label: 'Paste',
        accelerator: 'Command+V',
        selector: 'paste:'
      }, {
        label: 'Select All',
        accelerator: 'Command+A',
        selector: 'selectAll:'
      }]
    }, {
      label: 'View',
      submenu: (process.env.NODE_ENV === 'development') ? [{
        label: 'Reload',
        accelerator: 'Command+R',
        click() {
          mainWindow.restart();
        }
      }, {
        label: 'Toggle Full Screen',
        accelerator: 'Ctrl+Command+F',
        click() {
          mainWindow.setFullScreen(!mainWindow.isFullScreen());
        }
      }, {
        label: 'Toggle Developer Tools',
        accelerator: 'Alt+Command+I',
        click() {
          mainWindow.toggleDevTools();
        }
      }] : [{
        label: 'Toggle Full Screen',
        accelerator: 'Ctrl+Command+F',
        click() {
          mainWindow.setFullScreen(!mainWindow.isFullScreen());
        }
      }]
    }, {
      label: 'Window',
      submenu: [{
        label: 'Minimize',
        accelerator: 'Command+M',
        selector: 'performMiniaturize:'
      }, {
        label: 'Close',
        accelerator: 'Command+W',
        selector: 'performClose:'
      }, {
        type: 'separator'
      }, {
        label: 'Bring All to Front',
        selector: 'arrangeInFront:'
      }]
    }, {
      label: 'Help',
      submenu: [{
        label: 'Learn More',
        click() {
          shell.openExternal('http://electron.atom.io');
        }
      }, {
        label: 'Documentation',
        click() {
          shell.openExternal('https://github.com/atom/electron/tree/master/docs#readme');
        }
      }, {
        label: 'Community Discussions',
        click() {
          shell.openExternal('https://discuss.atom.io/c/electron');
        }
      }, {
        label: 'Search Issues',
        click() {
          shell.openExternal('https://github.com/atom/electron/issues');
        }
      }]
    }];

    menu = Menu.buildFromTemplate(template);
    Menu.setApplicationMenu(menu);
  } else {
    template = [{
      label: '&File',
      submenu: [{
        label: '&Open',
        accelerator: 'Ctrl+O'
      }, {
        label: '&Close',
        accelerator: 'Ctrl+W',
        click() {
          mainWindow.close();
        }
      }]
    }, {
      label: '&View',
      submenu: (process.env.NODE_ENV === 'development') ? [{
        label: '&Reload',
        accelerator: 'Ctrl+R',
        click() {
          mainWindow.restart();
        }
      }, {
        label: 'Toggle &Full Screen',
        accelerator: 'F11',
        click() {
          mainWindow.setFullScreen(!mainWindow.isFullScreen());
        }
      }, {
        label: 'Toggle &Developer Tools',
        accelerator: 'Alt+Ctrl+I',
        click() {
          mainWindow.toggleDevTools();
        }
      }] : [{
        label: 'Toggle &Full Screen',
        accelerator: 'F11',
        click() {
          mainWindow.setFullScreen(!mainWindow.isFullScreen());
        }
      }]
    }, {
      label: 'Help',
      submenu: [{
        label: 'Learn More',
        click() {
          shell.openExternal('http://electron.atom.io');
        }
      }, {
        label: 'Documentation',
        click() {
          shell.openExternal('https://github.com/atom/electron/tree/master/docs#readme');
        }
      }, {
        label: 'Community Discussions',
        click() {
          shell.openExternal('https://discuss.atom.io/c/electron');
        }
      }, {
        label: 'Search Issues',
        click() {
          shell.openExternal('https://github.com/atom/electron/issues');
        }
      }]
    }];
    menu = Menu.buildFromTemplate(template);
    mainWindow.setMenu(menu);
  }
});
<commit_msg>close window just hide it<commit_after>/* eslint strict: 0 */
'use strict';

process.env.NODE_ENV = process.env.NODE_ENV || 'production';

const electron = require('electron');
const storage = require('electron-json-storage');
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;
const Menu = electron.Menu;
const crashReporter = electron.crashReporter;
const shell = electron.shell;
const config = require('./config');
let menu;
let template;
let mainWindow = null;

crashReporter.start({
  productName: 'doubanFMac',
  companyName: 'darmody',
  submitURL: 'http://github.com/darmody/doubanFMac/issues'
});

if (process.env.NODE_ENV === 'development') {
  require('electron-debug')();
}

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') app.quit();
});

app.on('ready', () => {
  mainWindow = new BrowserWindow(config.window);

  const webContents = mainWindow.webContents;

  // manipulate cookies for douban
  const getDoubanCookies = (webContents) => {
    storage.get(config.electronStorageKey, (error, data) => {
      if (error) {
        return console.log('Electron storage read error.', error);
      }
      if (data.cookies && data.cookies.length > 0) {
        data.cookies.forEach((cookie) => {
          webContents.session.cookies.set({
            name: cookie[0],
            value: cookie[1],
            url: 'http://douban.fm',
          }, (error) => {
            if (error) console.log('Douban cookie set error.', error);
          });
        });
      }
    });

  };
  const setDoubanCookies = (webContents, originalURL, headers) => {
    if (originalURL !== 'http://douban.fm/j/login') return;

    const cookies = (headers['set-cookie'] || []).map((cookie) => {
      return cookie.split(';')[0].split('=');
    });

    storage.set(config.electronStorageKey, { cookies }, (error) => {
      if (error) console.log('Douban cookie save to storage error', error);
    });
  };

  webContents.on('did-get-response-details', (event, status, newURL, originalURL, code, method, referrer, headers) => {
    setDoubanCookies(webContents, originalURL, headers);
  });

  getDoubanCookies(webContents);

  mainWindow.loadURL(`file://${__dirname}/app/app.html`);

  mainWindow.on('closed', () => {
    mainWindow = null;
  });

  mainWindow.on('close', (event) => {
    if (mainWindow.forceClose) return;
    event.preventDefault();
    mainWindow.hide();
  });

  app.on('before-quit', () => {
    mainWindow.forceClose = true;
  });

  app.on('activate', () => {
    mainWindow.show();
  });

  if (process.env.NODE_ENV === 'development') {
    mainWindow.openDevTools();
  }

  if (process.platform === 'darwin') {
    template = [{
      label: '豆瓣FMac',
      submenu: [{
        label: 'Quit',
        accelerator: 'Command+Q',
        click() {
          app.quit();
        }
      }]
    }];

    menu = Menu.buildFromTemplate(template);
    Menu.setApplicationMenu(menu);
  }
});
<|endoftext|>


<commit_before>/**
 * @fileoverview Entry point for eslint-plugin-qunit. Exports rules and configs.
 * @author Kevin Partington
 */

/* eslint sort-keys: "error" */

"use strict";

module.exports = {
    rules: {
        "assert-args": require("./lib/rules/assert-args"),
        "literal-compare-order": require("./lib/rules/literal-compare-order"),
        "no-arrow-tests": require("./lib/rules/no-arrow-tests"),
        "no-assert-equal": require("./lib/rules/no-assert-equal"),
        "no-assert-logical-expression": require("./lib/rules/no-assert-logical-expression"),
        "no-async-in-loops": require("./lib/rules/no-async-in-loops"),
        "no-async-test": require("./lib/rules/no-async-test"),
        "no-commented-tests": require("./lib/rules/no-commented-tests"),
        "no-compare-relation-boolean": require("./lib/rules/no-compare-relation-boolean"),
        "no-conditional-assertions": require("./lib/rules/no-conditional-assertions"),
        "no-early-return": require("./lib/rules/no-early-return"),
        "no-global-assertions": require("./lib/rules/no-global-assertions"),
        "no-global-expect": require("./lib/rules/no-global-expect"),
        "no-global-module-test": require("./lib/rules/no-global-module-test"),
        "no-global-stop-start": require("./lib/rules/no-global-stop-start"),
        "no-identical-names": require("./lib/rules/no-identical-names"),
        "no-init": require("./lib/rules/no-init"),
        "no-jsdump": require("./lib/rules/no-jsdump"),
        "no-negated-ok": require("./lib/rules/no-negated-ok"),
        "no-ok-equality": require("./lib/rules/no-ok-equality"),
        "no-only": require("./lib/rules/no-only"),
        "no-qunit-push": require("./lib/rules/no-qunit-push"),
        "no-qunit-start-in-tests": require("./lib/rules/no-qunit-start-in-tests"),
        "no-qunit-stop": require("./lib/rules/no-qunit-stop"),
        "no-reassign-log-callbacks": require("./lib/rules/no-reassign-log-callbacks"),
        "no-reset": require("./lib/rules/no-reset"),
        "no-setup-teardown": require("./lib/rules/no-setup-teardown"),
        "no-test-expect-argument": require("./lib/rules/no-test-expect-argument"),
        "no-throws-string": require("./lib/rules/no-throws-string"),
        "require-expect": require("./lib/rules/require-expect"),
        "resolve-async": require("./lib/rules/resolve-async")
    },

    // eslint-disable-next-line sort-keys
    configs: {
        recommended: {
            rules: {
                "qunit/assert-args": "error",
                "qunit/literal-compare-order": "error",
                "qunit/no-async-in-loops": "error",
                "qunit/no-commented-tests": "error",
                "qunit/no-ok-equality": "error",
                "qunit/no-only": "error",
                "qunit/no-reassign-log-callbacks": "error",
                "qunit/no-reset": "error",
                "qunit/no-throws-string": "error",
                "qunit/require-expect": ["error", "except-simple"],
                "qunit/resolve-async": "error"
            }
        },
        two: {
            rules: {
                "qunit/no-async-test": "error",
                "qunit/no-global-assertions": "error",
                "qunit/no-global-expect": "error",
                "qunit/no-global-module-test": "error",
                "qunit/no-global-stop-start": "error",
                "qunit/no-init": "error",
                "qunit/no-jsdump": "error",
                "qunit/no-qunit-push": "error",
                "qunit/no-qunit-stop": "error",
                "qunit/no-reassign-log-callbacks": "error",
                "qunit/no-reset": "error",
                "qunit/no-setup-teardown": "error",
                "qunit/no-test-expect-argument": "error",
                "qunit/no-throws-string": "error"
            }
        }
    }
};
<commit_msg>Breaking: Updating exported configs (fixes #52, fixes #58)<commit_after>/**
 * @fileoverview Entry point for eslint-plugin-qunit. Exports rules and configs.
 * @author Kevin Partington
 */

/* eslint sort-keys: "error" */

"use strict";

module.exports = {
    rules: {
        "assert-args": require("./lib/rules/assert-args"),
        "literal-compare-order": require("./lib/rules/literal-compare-order"),
        "no-arrow-tests": require("./lib/rules/no-arrow-tests"),
        "no-assert-equal": require("./lib/rules/no-assert-equal"),
        "no-assert-logical-expression": require("./lib/rules/no-assert-logical-expression"),
        "no-async-in-loops": require("./lib/rules/no-async-in-loops"),
        "no-async-test": require("./lib/rules/no-async-test"),
        "no-commented-tests": require("./lib/rules/no-commented-tests"),
        "no-compare-relation-boolean": require("./lib/rules/no-compare-relation-boolean"),
        "no-conditional-assertions": require("./lib/rules/no-conditional-assertions"),
        "no-early-return": require("./lib/rules/no-early-return"),
        "no-global-assertions": require("./lib/rules/no-global-assertions"),
        "no-global-expect": require("./lib/rules/no-global-expect"),
        "no-global-module-test": require("./lib/rules/no-global-module-test"),
        "no-global-stop-start": require("./lib/rules/no-global-stop-start"),
        "no-identical-names": require("./lib/rules/no-identical-names"),
        "no-init": require("./lib/rules/no-init"),
        "no-jsdump": require("./lib/rules/no-jsdump"),
        "no-negated-ok": require("./lib/rules/no-negated-ok"),
        "no-ok-equality": require("./lib/rules/no-ok-equality"),
        "no-only": require("./lib/rules/no-only"),
        "no-qunit-push": require("./lib/rules/no-qunit-push"),
        "no-qunit-start-in-tests": require("./lib/rules/no-qunit-start-in-tests"),
        "no-qunit-stop": require("./lib/rules/no-qunit-stop"),
        "no-reassign-log-callbacks": require("./lib/rules/no-reassign-log-callbacks"),
        "no-reset": require("./lib/rules/no-reset"),
        "no-setup-teardown": require("./lib/rules/no-setup-teardown"),
        "no-test-expect-argument": require("./lib/rules/no-test-expect-argument"),
        "no-throws-string": require("./lib/rules/no-throws-string"),
        "require-expect": require("./lib/rules/require-expect"),
        "resolve-async": require("./lib/rules/resolve-async")
    },

    // eslint-disable-next-line sort-keys
    configs: {
        recommended: {
            rules: {
                "qunit/assert-args": "error",
                "qunit/literal-compare-order": "error",
                "qunit/no-async-in-loops": "error",
                "qunit/no-commented-tests": "error",
                "qunit/no-identical-names": "error",
                "qunit/no-ok-equality": "error",
                "qunit/no-only": "error",
                "qunit/no-reassign-log-callbacks": "error",
                "qunit/no-reset": "error",
                "qunit/no-throws-string": "error",
                "qunit/require-expect": ["error", "except-simple"],
                "qunit/resolve-async": "error"
            }
        },
        two: {
            rules: {
                "qunit/no-async-test": "error",
                "qunit/no-global-assertions": "error",
                "qunit/no-global-expect": "error",
                "qunit/no-global-module-test": "error",
                "qunit/no-global-stop-start": "error",
                "qunit/no-init": "error",
                "qunit/no-jsdump": "error",
                "qunit/no-qunit-push": "error",
                "qunit/no-qunit-start-in-tests": "error",
                "qunit/no-qunit-stop": "error",
                "qunit/no-reassign-log-callbacks": "error",
                "qunit/no-reset": "error",
                "qunit/no-setup-teardown": "error",
                "qunit/no-test-expect-argument": "error",
                "qunit/no-throws-string": "error"
            }
        }
    }
};
<|endoftext|>


<commit_before>'use strict';

var path = require('path');
var fs = require('fs');
var mkdirp = require('mkdirp');
var ncp = require('ncp');

var downloadDir = path.join(__dirname, 'bin');

module.exports = function(installDir) {
	if (!fs.existsSync(installDir)) {
		mkdirp(installDir);
	}

	if (fs.existsSync(installDir) && fs.statSync(installDir).isDirectory()) {
		ncp(downloadDir, installDir, function(err) {
			if(err){throw new Error('Failed to install the latest version of the Google Closure library to the folder: ' + installDir + '.\nError: ' + err);}
		});
	} else {
		throw new Error('Installation directory not found and could not be created.');
	}
};<commit_msg>Updating the setup script to use the synchronous version of mkdirp to ensure the directory exists before the setup continues.<commit_after>'use strict';

var path = require('path');
var fs = require('fs');
var mkdirp = require('mkdirp');
var ncp = require('ncp');

var downloadDir = path.join(__dirname, 'bin');

module.exports = function(installDir) {
	if (!fs.existsSync(installDir)) {
		mkdirp.sync(installDir);
	}

	if (fs.existsSync(installDir) && fs.statSync(installDir).isDirectory()) {
		ncp(downloadDir, installDir, function(err) {
			if(err){throw new Error('Failed to install the latest version of the Google Closure library to the folder: ' + installDir + '.\nError: ' + err);}
		});
	} else {
		throw new Error('Installation directory not found and could not be created.');
	}
};<|endoftext|>