<commit_before>// DOM handles
let DOM;
let state = {
	lastResult: {
		posts: [],
		url: '',
	},
	opts: {
		orderBy: 'score',
		desc: true,
	},
	oldReddit: true
};

$(document).ready(init);

function init() {
	DOM = fetchDomHandles();

	getOptions(popupDefaults)
		.then(opts => {
			registerHandlers(opts.popup);
			setSearchDefaults(opts.search);
			state.opts = opts.popup.results;
			state.oldReddit = opts.oldReddit;
		})
		.then(render)
		.catch(console.log);
}

function registerHandlers(opts) {
	// receive updated html from template.html
	window.addEventListener('message', e => {
		if (e.data.html) {
			DOM.resultsDiv.html(e.data.html);
		}
		$('.sort-options').change(function() {
			state.opts.orderBy = $(this).val();
			displayPosts(state.lastResult.posts, state.lastResult.url);
		});
		$('.sort-order').click(e => {
			e.stopPropagation();
			state.opts.desc = !state.opts.desc;
			displayPosts(state.lastResult.posts, state.lastResult.url);
		});
	});

	// open links in new tab - or not
	$('body').on('click', 'a', function(e) {
		let clickedUrl = $(this).attr('href');
		if (e.metaKey || e.shiftKey || e.altKey) {
			/* cmd/shift/alt + click:
			do not modify default browser behavior */
		}
		else if (e.ctrlKey) {
			/* Default open-in-new-tab behavior seems to have changed
			such that the popup gets closed after the click. This overwrites
			that behavior to ensure that:  */
			// (1) a new tab is created in the bg
			chrome.tabs.create({
				url: clickedUrl,
				active: false
			});
			// (2) the popup remains open (== preventDefault & stopPropagation)
			return false;
		}
		else if (opts.newtab) {
			chrome.tabs.create({
				url: clickedUrl,
				active: !opts.newtabInBg
			});
		}
		else {
			navigateTo(clickedUrl);
		}
	});

	DOM.opts.ytCheckbox.change(function(e) {
		if (this.checked) {
			setUiState('YT_VID');
		} else {
			setUiState('DEFAULT');
			DOM.ytChoice.removeClass('hidden');
		}
		render();
	});
	DOM.opts.exactCheckbox.change(render);
	DOM.opts.qsCheckbox.change(render);

	DOM.searchBtn.click(() => render(true));
}

function render(userClicked = false) {
	setUiState('SEARCH_BEGIN');
	let urlPromise = getUrl();
	let params = getSearchParams();
	let useCache = !userClicked;
	let originalUrl;
	let isYt, exactMatch;

	urlPromise
		.then(url => {
			originalUrl = url;
			updateUiBasedOnUrl(url, params);

			isYt = isYoutubeUrl(url) && params.ytHandling;
			exactMatch = params.exactMatch && !isYt;
			let urlToSearch = processUrl(url, params.ignoreQs, isYt);

			return findOnReddit(urlToSearch, useCache, exactMatch);
		})
		.then(posts => {
			state.lastResult.posts = posts;
			state.lastResult.url = originalUrl;
			displayPosts(posts, originalUrl);
			return posts.other;
		})
		.then(otherResults => {
			setUiState('SEARCH_END', {
				name: (!exactMatch ? 'exact' : 'non-exact'),
				num: otherResults
			});
		})
		.catch(e => onRequestError(e, userClicked));
}

function getSearchParams() {
	return {
		ignoreQs: DOM.opts.qsCheckbox.prop('checked'),
		exactMatch: DOM.opts.exactCheckbox.prop('checked'),
		ytHandling: DOM.opts.ytCheckbox.prop('checked')
	};
}

function getUrl() {
	let urlInput = DOM.urlInput.val();
	if (urlInput) {
		return Promise.resolve(urlInput);
	}
	else {
		let urlPromise = getCurrentTabUrl(url);
		urlPromise.then(url => DOM.urlInput.val(url));
		return urlPromise;
	}
}

const AJAX_RETRY_DELAY_SEC = 5;
let retry_countdown = AJAX_RETRY_DELAY_SEC;
function onRequestError(error, userClicked = false) {
	console.log(error);
	if (retry_countdown == 0) {
		retry_countdown = AJAX_RETRY_DELAY_SEC;
		render(userClicked);
		return;
	}
	retry_countdown -= 1;
	setUiState('AJAX_ERROR', {msg: error.statusText, delay: retry_countdown});
	setTimeout(() => onRequestError(error, userClicked), 1e3);
}

/* post age calculation */
const timeUnits = [
	{factor: 1/(1e3), name: 'seconds', decis: 0},
	{factor: 1/(1e3*60), name: 'minutes', decis: 0},
	{factor: 1/(1e3*60*60), name: 'hours', decis: 0},
	{factor: 1/(1e3*60*60*24), name: 'days', decis: 0},
	{factor: 1/(1e3*60*60*24*30), name: 'months', decis: 0},
	{factor: 1/(1e3*60*60*24*30*12), name: 'years', decis: 1}
];
function calcAge(timestampSeconds) {
	let diffMillis = Date.now() - (timestampSeconds * 1e3);
	let [n, unit] = timeUnits
		.map(t => [+(diffMillis * t.factor).toFixed(t.decis), t.name])
		.reverse()
		.find(([n, u]) => n >= 1);
	unit = (n === 1) ? unit.slice(0, -1) : unit; // singular/plural
	return `${n} ${unit}`;
}

/* UI */
let fieldMappings = Object.freeze({
	score: 'score',
	comments: 'num_comments',
	age: 'created_utc',
	subreddit: 'subreddit'
});

function sortPosts(posts, orderBy = 'score', desc = true) {
	if (orderBy == 'subreddit') {
		return posts.sort((a, b) =>
			a.data.subreddit.localeCompare(b.data.subreddit) * (2 * desc - 1)
		);
	}
	let field = fieldMappings[orderBy];
	let comparator = (a, b) =>
		(a.data[field] - b.data[field]) * (1 - 2 * desc);
	return posts.sort(comparator);
}

function displayPosts(posts, url = '') {
	if (!posts) {
		return;
	}
	if (posts.length) {
		posts.forEach(p => {
			try {
				p.data.age = calcAge(p.data.created_utc);
			}
			catch (e) {
				p.data.age = '?';
			}
		});
	}
	let sortedPosts = sortPosts(posts, state.opts.orderBy, state.opts.desc);
	let msg = {
		// context for Handlebars template
		context: {
			oldReddit: state.oldReddit,
			numPosts: posts.length,
			posts: sortedPosts,
			url: url,
			orderBy: state.opts.orderBy
		}
	};
	messageTemplate(msg);
}

function messageTemplate(msg) {
	if (document.readyState !== "complete") {
		setTimeout(() => messageTemplate(msg), 100);
		return;
	}
	document.getElementById('tFrame').contentWindow.postMessage(msg, '*');
}

function setSearchDefaults(opts) {
	DOM.opts.exactCheckbox.prop('checked', opts.exactMatch);
	DOM.opts.qsCheckbox.prop('checked', opts.ignoreQs);
	DOM.opts.ytCheckbox.prop('checked', opts.ytHandling);
}

function setUiState(state, params = null) {
	switch(state) {
		case 'SEARCH_BEGIN': {
			DOM.statusDiv.text('Searching ...'); break;
		}
		case 'SEARCH_END': {
			DOM.statusDiv.text('');
			if (typeof params.num === 'undefined') {
				DOM.otherResultsDiv.addClass('hidden');
			} else {
				DOM.otherResultsDiv.removeClass('hidden');
			}
			DOM.otherResultsNum.text(`${params.name} matches: ${params.num}`);
			break;
		}
		case 'AJAX_ERROR': {
			params.msg = params.msg || 'error';
			DOM.statusDiv.text(`${params.msg}, retrying in ${params.delay}s ...`);
			break;
		}
		case 'YT_VID': {
			DOM.qsChoice.addClass('hidden');
			DOM.exactChoice.addClass('hidden');
			DOM.ytChoice.removeClass('hidden');
			DOM.opts.qsCheckbox.prop('checked', false);
			if (params && params.id) {
				DOM.ytVidId.text(`'${params.id}'`);
			}
			break;
		}
		case 'YT_VID_HANDLING_OFF': {
			DOM.qsChoice.removeClass('hidden');
			DOM.exactChoice.removeClass('hidden');
			DOM.ytChoice.removeClass('hidden');
			if (params && params.id) {
				DOM.ytVidId.text(`'${params.id}'`);
			}
			break;
		}
		default: {
			DOM.ytChoice.addClass('hidden');
			DOM.exactChoice.removeClass('hidden');
			DOM.qsChoice.removeClass('hidden');
		}
	}
}

function updateUiBasedOnUrl(url, params) {
	if (isYoutubeUrl(url)) {
		let state = params.ytHandling ? 'YT_VID' : 'YT_VID_HANDLING_OFF';
		setUiState(state, { id: getYoutubeVideoId(url) });
	}
	else {
		setUiState('DEFAULT');
	}
}

function fetchDomHandles() {
	return {
		resultsDiv: $('#results'),
		otherResultsDiv: $('#other-results'),
		otherResultsNum: $('#other-results-num'),
		statusDiv: $('#status'),
		urlInput: $('#url'),
		searchBtn: $('#url-submit'),
		ytChoice: $('#yt-choice'),
		ytVidId: $('#yt-vid-id'),
		qsChoice: $('#qs-choice'),
		exactChoice: $('#exact-choice'),
		opts: {
			exactCheckbox: $('#exact'),
			qsCheckbox: $('#ignore-qs'),
			ytCheckbox: $('#yt'),
		}
	};
}

<commit_msg>formatting<commit_after>// DOM handles
let DOM;
let state = {
	lastResult: {
		posts: [],
		url: '',
	},
	opts: {
		orderBy: 'score',
		desc: true,
	},
	oldReddit: true
};

$(document).ready(init);

function init() {
	DOM = fetchDomHandles();

	getOptions(popupDefaults)
		.then(opts => {
			registerHandlers(opts.popup);
			setSearchDefaults(opts.search);
			state.opts = opts.popup.results;
			state.oldReddit = opts.oldReddit;
		})
		.then(render)
		.catch(console.log);
}

function registerHandlers(opts) {
	// receive updated html from template.html
	window.addEventListener('message', e => {
		if (e.data.html) {
			DOM.resultsDiv.html(e.data.html);
		}
		$('.sort-options').change(function() {
			state.opts.orderBy = $(this).val();
			displayPosts(state.lastResult.posts, state.lastResult.url);
		});
		$('.sort-order').click(e => {
			e.stopPropagation();
			state.opts.desc = !state.opts.desc;
			displayPosts(state.lastResult.posts, state.lastResult.url);
		});
	});

	// open links in new tab - or not
	$('body').on('click', 'a', function(e) {
		let clickedUrl = $(this).attr('href');
		if (e.metaKey || e.shiftKey || e.altKey) {
			/* cmd/shift/alt + click:
			do not modify default browser behavior */
		} else if (e.ctrlKey) {
			/* Default open-in-new-tab behavior seems to have changed
			such that the popup gets closed after the click. This overwrites
			that behavior to ensure that:  */
			// (1) a new tab is created in the bg
			chrome.tabs.create({
				url: clickedUrl,
				active: false
			});
			// (2) the popup remains open (== preventDefault & stopPropagation)
			return false;
		} else if (opts.newtab) {
			chrome.tabs.create({
				url: clickedUrl,
				active: !opts.newtabInBg
			});
		} else {
			navigateTo(clickedUrl);
		}
	});

	DOM.opts.ytCheckbox.change(function(e) {
		if (this.checked) {
			setUiState('YT_VID');
		} else {
			setUiState('DEFAULT');
			DOM.ytChoice.removeClass('hidden');
		}
		render();
	});
	DOM.opts.exactCheckbox.change(render);
	DOM.opts.qsCheckbox.change(render);

	DOM.searchBtn.click(() => render(true));
}

function render(userClicked = false) {
	setUiState('SEARCH_BEGIN');
	let urlPromise = getUrl();
	let params = getSearchParams();
	let useCache = !userClicked;
	let originalUrl;
	let isYt, exactMatch;

	urlPromise
		.then(url => {
			originalUrl = url;
			updateUiBasedOnUrl(url, params);

			isYt = isYoutubeUrl(url) && params.ytHandling;
			exactMatch = params.exactMatch && !isYt;
			let urlToSearch = processUrl(url, params.ignoreQs, isYt);

			return findOnReddit(urlToSearch, useCache, exactMatch);
		})
		.then(posts => {
			state.lastResult.posts = posts;
			state.lastResult.url = originalUrl;
			displayPosts(posts, originalUrl);
			return posts.other;
		})
		.then(otherResults => {
			setUiState('SEARCH_END', {
				name: (!exactMatch ? 'exact' : 'non-exact'),
				num: otherResults
			});
		})
		.catch(e => onRequestError(e, userClicked));
}

function getSearchParams() {
	return {
		ignoreQs: DOM.opts.qsCheckbox.prop('checked'),
		exactMatch: DOM.opts.exactCheckbox.prop('checked'),
		ytHandling: DOM.opts.ytCheckbox.prop('checked')
	};
}

function getUrl() {
	let urlInput = DOM.urlInput.val();
	if (urlInput) {
		return Promise.resolve(urlInput);
	} else {
		let urlPromise = getCurrentTabUrl(url);
		urlPromise.then(url => DOM.urlInput.val(url));
		return urlPromise;
	}
}

const AJAX_RETRY_DELAY_SEC = 5;
let retry_countdown = AJAX_RETRY_DELAY_SEC;
function onRequestError(error, userClicked = false) {
	console.log(error);
	if (retry_countdown == 0) {
		retry_countdown = AJAX_RETRY_DELAY_SEC;
		render(userClicked);
		return;
	}
	retry_countdown -= 1;
	setUiState('AJAX_ERROR', {msg: error.statusText, delay: retry_countdown});
	setTimeout(() => onRequestError(error, userClicked), 1e3);
}

/* post age calculation */
const timeUnits = [
	{factor: 1/(1e3), name: 'seconds', decis: 0},
	{factor: 1/(1e3*60), name: 'minutes', decis: 0},
	{factor: 1/(1e3*60*60), name: 'hours', decis: 0},
	{factor: 1/(1e3*60*60*24), name: 'days', decis: 0},
	{factor: 1/(1e3*60*60*24*30), name: 'months', decis: 0},
	{factor: 1/(1e3*60*60*24*30*12), name: 'years', decis: 1}
];
function calcAge(timestampSeconds) {
	let diffMillis = Date.now() - (timestampSeconds * 1e3);
	let [n, unit] = timeUnits
		.map(t => [+(diffMillis * t.factor).toFixed(t.decis), t.name])
		.reverse()
		.find(([n, u]) => n >= 1);
	unit = (n === 1) ? unit.slice(0, -1) : unit; // singular/plural
	return `${n} ${unit}`;
}

/* UI */
let fieldMappings = Object.freeze({
	score: 'score',
	comments: 'num_comments',
	age: 'created_utc',
	subreddit: 'subreddit'
});

function sortPosts(posts, orderBy = 'score', desc = true) {
	if (orderBy == 'subreddit') {
		return posts.sort((a, b) =>
			a.data.subreddit.localeCompare(b.data.subreddit) * (2 * desc - 1)
		);
	}
	let field = fieldMappings[orderBy];
	let comparator = (a, b) =>
		(a.data[field] - b.data[field]) * (1 - 2 * desc);
	return posts.sort(comparator);
}

function displayPosts(posts, url = '') {
	if (!posts) {
		return;
	}
	if (posts.length) {
		posts.forEach(p => {
			try {
				p.data.age = calcAge(p.data.created_utc);
			}
			catch (e) {
				p.data.age = '?';
			}
		});
	}
	let sortedPosts = sortPosts(posts, state.opts.orderBy, state.opts.desc);
	let msg = {
		// context for Handlebars template
		context: {
			oldReddit: state.oldReddit,
			numPosts: posts.length,
			posts: sortedPosts,
			url: url,
			orderBy: state.opts.orderBy
		}
	};
	messageTemplate(msg);
}

function messageTemplate(msg) {
	if (document.readyState !== "complete") {
		setTimeout(() => messageTemplate(msg), 100);
		return;
	}
	document.getElementById('tFrame').contentWindow.postMessage(msg, '*');
}

function setSearchDefaults(opts) {
	DOM.opts.exactCheckbox.prop('checked', opts.exactMatch);
	DOM.opts.qsCheckbox.prop('checked', opts.ignoreQs);
	DOM.opts.ytCheckbox.prop('checked', opts.ytHandling);
}

function setUiState(state, params = null) {
	switch(state) {
		case 'SEARCH_BEGIN': {
			DOM.statusDiv.text('Searching ...'); break;
		}
		case 'SEARCH_END': {
			DOM.statusDiv.text('');
			if (typeof params.num === 'undefined') {
				DOM.otherResultsDiv.addClass('hidden');
			} else {
				DOM.otherResultsDiv.removeClass('hidden');
			}
			DOM.otherResultsNum.text(`${params.name} matches: ${params.num}`);
			break;
		}
		case 'AJAX_ERROR': {
			params.msg = params.msg || 'error';
			DOM.statusDiv.text(`${params.msg}, retrying in ${params.delay}s ...`);
			break;
		}
		case 'YT_VID': {
			DOM.qsChoice.addClass('hidden');
			DOM.exactChoice.addClass('hidden');
			DOM.ytChoice.removeClass('hidden');
			DOM.opts.qsCheckbox.prop('checked', false);
			if (params && params.id) {
				DOM.ytVidId.text(`'${params.id}'`);
			}
			break;
		}
		case 'YT_VID_HANDLING_OFF': {
			DOM.qsChoice.removeClass('hidden');
			DOM.exactChoice.removeClass('hidden');
			DOM.ytChoice.removeClass('hidden');
			if (params && params.id) {
				DOM.ytVidId.text(`'${params.id}'`);
			}
			break;
		}
		default: {
			DOM.ytChoice.addClass('hidden');
			DOM.exactChoice.removeClass('hidden');
			DOM.qsChoice.removeClass('hidden');
		}
	}
}

function updateUiBasedOnUrl(url, params) {
	if (isYoutubeUrl(url)) {
		let state = params.ytHandling ? 'YT_VID' : 'YT_VID_HANDLING_OFF';
		setUiState(state, { id: getYoutubeVideoId(url) });
	} else {
		setUiState('DEFAULT');
	}
}

function fetchDomHandles() {
	return {
		resultsDiv: $('#results'),
		otherResultsDiv: $('#other-results'),
		otherResultsNum: $('#other-results-num'),
		statusDiv: $('#status'),
		urlInput: $('#url'),
		searchBtn: $('#url-submit'),
		ytChoice: $('#yt-choice'),
		ytVidId: $('#yt-vid-id'),
		qsChoice: $('#qs-choice'),
		exactChoice: $('#exact-choice'),
		opts: {
			exactCheckbox: $('#exact'),
			qsCheckbox: $('#ignore-qs'),
			ytCheckbox: $('#yt'),
		}
	};
}

<|endoftext|>


<commit_before>console.log('vdd');<commit_msg>Removi o popup.js que tava na raiz<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2012,2013 Peter Coles - http://mrcoles.com/ - All rights reserved.
// Copyright (c) 2015 Jean-Martin Archer
// Use of this source code is governed by the MIT License found in LICENSE

function $(id) { return document.getElementById(id); }
function show(id) { $(id).style.display = 'block'; }

function capturePage(data) {
	function createHiDPICanvas(w, h, ratio) {
		var canvas = document.createElement("canvas");
		canvas.width = w * ratio;
		canvas.height = h * ratio;
		canvas.style.width = w + "px";
		canvas.style.height = h + "px";
		canvas.getContext("2d").setTransform(ratio, 0, 0, ratio, 0, 0);
		return canvas;
	}

	var margins = data.margins;
	var canvas = createHiDPICanvas(data.totalWidth + margins.left + margins.right, data.totalHeight + margins.top + margins.bottom + data.titleBar.height, data.pixelRatio);
	var ctx = canvas.getContext('2d');

	chrome.tabs.captureVisibleTab(
		null, {format: 'png', quality: 100}, function(dataURI) {
			if (dataURI) {
				var image = new Image();
				var titleBarImage = new Image();
				titleBarImage.onload = function () {
					addTitleBar(ctx, titleBarImage, data);
				};
				titleBarImage.src = data.titleBar.data;
				image.onload = function() {
					ctx.drawImage(image, margins.left, margins.top + data.titleBar.height, data.totalWidth, data.totalHeight);
					openPage(canvas, data);
				};
				image.src = dataURI;
			}
		});

	function addTitleBar(ctx, titleBarImage, data) {
		var totalWidth = data.totalWidth + 12;
		var leftWidth = data.titleBar.leftWidth;
		var offset = data.titleBar.offset;
		addShadow(ctx, data);
		ctx.drawImage(titleBarImage, offset, 0, 5, leftWidth, data.margins.left + 5, data.margins.top, totalWidth - 20, leftWidth); // middle
		ctx.drawImage(titleBarImage, 0, 0, offset, leftWidth, data.margins.left, data.margins.top, offset, leftWidth); //leftSide
		ctx.drawImage(titleBarImage, offset, 0, offset, leftWidth, totalWidth, data.margins.top, offset, leftWidth); //rightSide
	}

	function addShadow(ctx, data) {
		ctx.save();
		ctx.rect(data.margins.left + data.shadowEdgeOffset, data.margins.top + data.shadowEdgeOffset, data.totalWidth - (data.shadowEdgeOffset * 2), data.totalHeight + data.titleBar.height - data.shadowEdgeOffset);
		ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
		ctx.shadowBlur = 20 * data.pixelRatio;
		ctx.shadowOffsetX = 0;
		ctx.shadowOffsetY = 5 * data.pixelRatio;
		ctx.fill();
		ctx.restore();
	}
}

function openPage(canvas, data) {
	// standard dataURI can be too big, let's blob instead
	// http://code.google.com/p/chromium/issues/detail?id=69227#c27

	var dataURI = canvas.toDataURL();
	var contentURL = '';
	var byteString = atob(dataURI.split(',')[1]);
	var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];

	var ab = new ArrayBuffer(byteString.length);
	var ia = new Uint8Array(ab);
	for (var i = 0; i < byteString.length; i++) {
		ia[i] = byteString.charCodeAt(i);
	}

	var blob = new Blob([ab], {type: mimeString});
	var size = blob.size + (1024/2);
	var name = contentURL.split('?')[0].split('#')[0];
	if (name) {
		name = name
			.replace(/^https?:\/\//, '')
			.replace(/[^A-z0-9]+/g, '-')
			.replace(/-+/g, '-')
			.replace(/^[_\-]+/, '')
			.replace(/[_\-]+$/, '');
		name = '-' + name;
	} else {
		name = '';
	}
	name = 'screenshot' + name + '-' + Date.now() + '.png';

	function onwriteend() {
		// open the file that now contains the blob
		window.open('filesystem:chrome-extension://' + chrome.i18n.getMessage('@@extension_id') + '/temporary/' + name);
		chrome.windows.update(chrome.windows.WINDOW_ID_CURRENT, {width: data.originalWidth});
	}

	function errorHandler() {
		show('uh-oh');
	}

	// create a blob for writing to a file
	window.webkitRequestFileSystem(window.TEMPORARY, size, function(fs){
		fs.root.getFile(name, {create: true}, function(fileEntry) {
			fileEntry.createWriter(function(fileWriter) {
				fileWriter.onwriteend = onwriteend;
				fileWriter.write(blob);
			}, errorHandler);
		}, errorHandler);
	}, errorHandler);
}

(function () {
	chrome.tabs.getSelected(null, function(tab) {
		var loaded = false;
		var PIXEL_RATIO = (function () {
			var ctx = document.createElement("canvas").getContext("2d"),
				dpr = window.devicePixelRatio || 1,
				bsr = ctx.webkitBackingStorePixelRatio ||
					ctx.backingStorePixelRatio || 1;

			return dpr / bsr;
		})();

		var data = {
			targetWidth: 1280,
			totalWidth: null,
			totalHeight: null,
			pixelRatio: PIXEL_RATIO,
			originalWidth: tab.width,
			margins: {top: 15, bottom: 25, left: 25, right: 25},
			titleBar: {height: 36, leftWidth: 60, offset: 70, data: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFMAAAAkCAYAAAD1lQZ5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAArdJREFUeNrsmM9uElEUxj9grmSgYJWoWFpS3ftnQZG4aKMm6kJ9Ak30ATSpuqvLutSFvoALn0BdqImadqFIXfhnb5sRaNWgLQpEB4L3DKPpgty54BC6OF9yNvd+czL55c7lOwQsy4Krs7JmZU3JGgHLSz9lLcm6LesRLQTdjXlZD2QdY5DaGnF5PXT5ISBP5hl3gfV/Okcn8ypz8EWzBDPDHHxRhmDGmIMvigWZgX9imAyTYTJMFsMciox+Hwy0WogsvYb54R3E5zVnzd6TROPAIdSnjqAdCun3ajcR3XgOs5qH+F3s9No2jkY8h9r242gHenvNpuz3pLaIxUYBll1y1tIihWkzi1PRaRgBYyAwaZxs9/pQqFrFzvv3INZWu+7byb34dv4iWvG4d6/mdyRKtyB+Wd17hdOopK6hZezQerdKax03K3exbH/qur9PTGAucRmJ0OjwP3M6kSqQJNojT6DZ9DyRKpBOL7lHHvLqnEgVSBLtzVfuwNboN3CY9GmrQG4GGnlTUHqiGy+UIDcDJa+X6NNWgfyrFbuIp9I7dJh0R/rlNauv9HtpeOmO1FUv3oHBFOWSvne17HHiVvR7aXg/2pZ2v+UevFsjGgV9bO/zL3AIoeHDtMdS+l4ZlZT74Un9XjIqeWm/SGv3o6g0dJiUI/3yUo7U7qXhpRypq168A4NZz2SdHKlzKsmrEgVyypGevcITjtdLJ2UgnxTeJ5g85B06zLZhOIFcBdQJ7RcuOV5lL3kPUiBXAe2E9utaU5CQnhuJK04wV4EkjxjAFNTXBPRvnCzkEXn/FsbXL53QvGs36gcPo57N9T5Orj+D+eOlHCfL7h05hkbsKGqjJ/oaJx/XFrDQyKNod0bdcZHEjJnD6ejM1honWfyvEcNkmAyTxTAZJsNkMUyGyTAZJss3/RFgAH76+ziLxwJqAAAAAElFTkSuQmCC'},
			shadowEdgeOffset: 3
		};

		chrome.windows.update(chrome.windows.WINDOW_ID_CURRENT, {width: data.targetWidth});
		// getting the tab again to get the new tab size.
		chrome.tabs.get(tab.id, function(tab) {
			data.totalWidth = tab.width;
			data.totalHeight = tab.height;
			capturePage(data);
		});

		window.setTimeout(function() {
			if (!loaded) {
				show('uh-oh');
			}
		}, 1000);
	});
})();
<commit_msg>[popup] cleaner topBar def<commit_after>// Copyright (c) 2012,2013 Peter Coles - http://mrcoles.com/ - All rights reserved.
// Copyright (c) 2015 Jean-Martin Archer
// Use of this source code is governed by the MIT License found in LICENSE

function $(id) { return document.getElementById(id); }
function show(id) { $(id).style.display = 'block'; }

function capturePage(data) {
	function createHiDPICanvas(w, h, ratio) {
		var canvas = document.createElement("canvas");
		canvas.width = w * ratio;
		canvas.height = h * ratio;
		canvas.style.width = w + "px";
		canvas.style.height = h + "px";
		canvas.getContext("2d").setTransform(ratio, 0, 0, ratio, 0, 0);
		return canvas;
	}

	var margins = data.margins;
	var canvas = createHiDPICanvas(data.totalWidth + margins.left + margins.right, data.totalHeight + margins.top + margins.bottom + data.titleBar.height, data.pixelRatio);
	var ctx = canvas.getContext('2d');

	chrome.tabs.captureVisibleTab(
		null, {format: 'png', quality: 100}, function(dataURI) {
			if (dataURI) {
				var image = new Image();
				var titleBarImage = new Image();
				titleBarImage.onload = function () {
					addTitleBar(ctx, titleBarImage, data);
				};
				titleBarImage.src = data.titleBar.data;
				image.onload = function() {
					ctx.drawImage(image, margins.left, margins.top + data.titleBar.height, data.totalWidth, data.totalHeight);
					openPage(canvas, data);
				};
				image.src = dataURI;
			}
		});

	function addTitleBar(ctx, titleBarImage, data) {
		var totalBarWidth = data.totalWidth + 12;
		var leftWidth = data.titleBar.leftWidth;
		var offset = data.titleBar.offset;

		var middleBar = {
			sx: offset, sy: 0,
			sw: 5, sh: leftWidth,
			dx: data.margins.left + 5, dy: data.margins.top,
			dw: totalBarWidth - 20, dh: leftWidth
		};
		var leftBar = {
			sx: 0, sy: 0,
			sw: offset, sh: leftWidth,
			dx: data.margins.left, dy: data.margins.top,
			dw: offset, dh: leftWidth
		};
		var rigthBar = {
			sx: offset, sy: 0,
			sw: offset, sh: leftWidth,
			dx: totalBarWidth, dy: data.margins.top,
			dw: offset, dh: leftWidth
		};

		addShadow(ctx, data);
		drawBar(ctx, titleBarImage, middleBar);
		drawBar(ctx, titleBarImage, leftBar);
		drawBar(ctx, titleBarImage, rigthBar);
	}

	function drawBar(ctx, image, coords) {
		ctx.drawImage(image, coords.sx, coords.sy, coords.sw, coords.sh, coords.dx, coords.dy, coords.dw, coords.dh);
	}

	function addShadow(ctx, data) {
		ctx.save();
		var rect = {
			x: data.margins.left + data.shadow.edgeOffset,
			y: data.margins.top + data.shadow.edgeOffset,
			w: data.totalWidth - (data.shadow.edgeOffset * 2),
			h: data.totalHeight + data.titleBar.height - data.shadow.edgeOffset
		};
		ctx.rect(rect.x, rect.y, rect.w, rect.h);
		ctx.shadowColor = data.shadow.color;
		ctx.shadowBlur = data.shadow.blur;
		ctx.shadowOffsetX = data.shadow.offsetX;
		ctx.shadowOffsetY = data.shadow.offsetY;
		ctx.fill();
		ctx.restore();
	}
}

function openPage(canvas, data) {
	// standard dataURI can be too big, let's blob instead
	// http://code.google.com/p/chromium/issues/detail?id=69227#c27

	var dataURI = canvas.toDataURL();
	var contentURL = '';
	var byteString = atob(dataURI.split(',')[1]);
	var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];

	var ab = new ArrayBuffer(byteString.length);
	var ia = new Uint8Array(ab);
	for (var i = 0; i < byteString.length; i++) {
		ia[i] = byteString.charCodeAt(i);
	}

	var blob = new Blob([ab], {type: mimeString});
	var size = blob.size + (1024/2);
	var name = contentURL.split('?')[0].split('#')[0];
	if (name) {
		name = name
			.replace(/^https?:\/\//, '')
			.replace(/[^A-z0-9]+/g, '-')
			.replace(/-+/g, '-')
			.replace(/^[_\-]+/, '')
			.replace(/[_\-]+$/, '');
		name = '-' + name;
	} else {
		name = '';
	}
	name = 'screenshot' + name + '-' + Date.now() + '.png';

	function onwriteend() {
		// open the file that now contains the blob
		window.open('filesystem:chrome-extension://' + chrome.i18n.getMessage('@@extension_id') + '/temporary/' + name);
		chrome.windows.update(chrome.windows.WINDOW_ID_CURRENT, {width: data.originalWidth});
	}

	function errorHandler() {
		show('uh-oh');
	}

	// create a blob for writing to a file
	window.webkitRequestFileSystem(window.TEMPORARY, size, function(fs){
		fs.root.getFile(name, {create: true}, function(fileEntry) {
			fileEntry.createWriter(function(fileWriter) {
				fileWriter.onwriteend = onwriteend;
				fileWriter.write(blob);
			}, errorHandler);
		}, errorHandler);
	}, errorHandler);
}

(function () {
	chrome.tabs.getSelected(null, function(tab) {
		var loaded = false;
		var PIXEL_RATIO = (function () {
			var ctx = document.createElement("canvas").getContext("2d"),
				dpr = window.devicePixelRatio || 1,
				bsr = ctx.webkitBackingStorePixelRatio ||
					ctx.backingStorePixelRatio || 1;

			return dpr / bsr;
		})();

		var data = {
			targetWidth: 1280,
			totalWidth: null,
			totalHeight: null,
			pixelRatio: PIXEL_RATIO,
			originalWidth: tab.width,
			margins: {top: 15, bottom: 25, left: 25, right: 25},
			titleBar: {height: 36, leftWidth: 60, offset: 70, data: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFMAAAAkCAYAAAD1lQZ5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAArdJREFUeNrsmM9uElEUxj9grmSgYJWoWFpS3ftnQZG4aKMm6kJ9Ak30ATSpuqvLutSFvoALn0BdqImadqFIXfhnb5sRaNWgLQpEB4L3DKPpgty54BC6OF9yNvd+czL55c7lOwQsy4Krs7JmZU3JGgHLSz9lLcm6LesRLQTdjXlZD2QdY5DaGnF5PXT5ISBP5hl3gfV/Okcn8ypz8EWzBDPDHHxRhmDGmIMvigWZgX9imAyTYTJMFsMciox+Hwy0WogsvYb54R3E5zVnzd6TROPAIdSnjqAdCun3ajcR3XgOs5qH+F3s9No2jkY8h9r242gHenvNpuz3pLaIxUYBll1y1tIihWkzi1PRaRgBYyAwaZxs9/pQqFrFzvv3INZWu+7byb34dv4iWvG4d6/mdyRKtyB+Wd17hdOopK6hZezQerdKax03K3exbH/qur9PTGAucRmJ0OjwP3M6kSqQJNojT6DZ9DyRKpBOL7lHHvLqnEgVSBLtzVfuwNboN3CY9GmrQG4GGnlTUHqiGy+UIDcDJa+X6NNWgfyrFbuIp9I7dJh0R/rlNauv9HtpeOmO1FUv3oHBFOWSvne17HHiVvR7aXg/2pZ2v+UevFsjGgV9bO/zL3AIoeHDtMdS+l4ZlZT74Un9XjIqeWm/SGv3o6g0dJiUI/3yUo7U7qXhpRypq168A4NZz2SdHKlzKsmrEgVyypGevcITjtdLJ2UgnxTeJ5g85B06zLZhOIFcBdQJ7RcuOV5lL3kPUiBXAe2E9utaU5CQnhuJK04wV4EkjxjAFNTXBPRvnCzkEXn/FsbXL53QvGs36gcPo57N9T5Orj+D+eOlHCfL7h05hkbsKGqjJ/oaJx/XFrDQyKNod0bdcZHEjJnD6ejM1honWfyvEcNkmAyTxTAZJsNkMUyGyTAZJss3/RFgAH76+ziLxwJqAAAAAElFTkSuQmCC'},
			shadow: {
				color: 'rgba(0, 0, 0, 0.5)',
				blur: 20 * PIXEL_RATIO,
				offsetX: 0,
				offsetY: 5 * PIXEL_RATIO,
				edgeOffset: 3
			}
		};

		chrome.windows.update(chrome.windows.WINDOW_ID_CURRENT, {width: data.targetWidth});
		// getting the tab again to get the new tab size.
		chrome.tabs.get(tab.id, function(tab) {
			data.totalWidth = tab.width;
			data.totalHeight = tab.height;
			capturePage(data);
		});

		window.setTimeout(function() {
			if (!loaded) {
				show('uh-oh');
			}
		}, 1000);
	});
})();
<|endoftext|>


<commit_before>document.addEventListener('DOMContentLoaded', function () {
  initialize();

  var elements = document.querySelectorAll('.menu-item');
  for(var n = 0; n < elements.length; n++) {
    elements[n].addEventListener('click', onClick);
  }
});

function onClick(event) {
  // Clear currently selected entry
  var selected = document.querySelector('.selected');
  if(selected !== null) {
    selected.classList.remove('selected');
  }

  // Set CH based on selected node
  var element = event.currentTarget;
  element.classList.add('selected');

  var title = element.querySelector('.title').innerText;
  setCH(defaults.filter(function(v) {
    return v.title === title;
  })[0]);
}

function serialize(obj) {
  var description =  '';
  for (var hint in obj) {
    description += (hint + ": " + obj[hint]);
  }

  return description;
}

function initialize() {
  // Add current device to list of possible CHs
  defaults.push(getDeviceHints());

  // Get current CH choice
  var currentCH = getCH();

  // Build the menu
  var menu = document.getElementById('menu');
  if(menu !== undefined) {
    for (var idx in defaults) {
      element = defaults[idx];

      var node = document.createElement('div');
      node.classList.add('menu-item');

      if (element.title == currentCH.title) {
        node.classList.add('selected');
      };

      var html = '
' + serialize(element.ch) + '
' +
                 '
' + element.title + '
';

      node.innerHTML = html;
      menu.appendChild(node);
    }
  }
}
<commit_msg>fix missing space in menu<commit_after>document.addEventListener('DOMContentLoaded', function () {
  initialize();

  var elements = document.querySelectorAll('.menu-item');
  for(var n = 0; n < elements.length; n++) {
    elements[n].addEventListener('click', onClick);
  }
});

function onClick(event) {
  // Clear currently selected entry
  var selected = document.querySelector('.selected');
  if(selected !== null) {
    selected.classList.remove('selected');
  }

  // Set CH based on selected node
  var element = event.currentTarget;
  element.classList.add('selected');

  var title = element.querySelector('.title').innerText;
  setCH(defaults.filter(function(v) {
    return v.title === title;
  })[0]);
}

function serialize(obj) {
  var description =  '';
  for (var hint in obj) {
    description += (hint + ": " + obj[hint] + " ");
  }

  return description;
}

function initialize() {
  // Add current device to list of possible CHs
  defaults.push(getDeviceHints());

  // Get current CH choice
  var currentCH = getCH();

  // Build the menu
  var menu = document.getElementById('menu');
  if(menu !== undefined) {
    for (var idx in defaults) {
      element = defaults[idx];

      var node = document.createElement('div');
      node.classList.add('menu-item');

      if (element.title == currentCH.title) {
        node.classList.add('selected');
      };

      var html = '
' + serialize(element.ch) + '
' +
                 '
' + element.title + '
';

      node.innerHTML = html;
      menu.appendChild(node);
    }
  }
}
<|endoftext|>


<commit_before>var totalHeight = 0; //Total height of the body of the popup

//Gets windows from storage
function getStorage(callback){
	chrome.storage.local.get("windows",callback);
}

function getWindows(windowList,windows,callback){
	if (typeof windows==="function"){
		callback = windows;
		getStorage(function(data){
			if (data!=null){
				setupWindows(windowList,data.windows,callback);
			}
			else{
				throw "Windows is null, this hsould never happen.";
			}
		});
	}
	else{
		setupWindows(windowList,windows, callback);
	}
}

function setupWindows(windowList,windows,callback){
	debugger;
	windows.forEach(function(currentWindow){
		setupWindowElement(currentWindow, function(windowLi){
			setupTabs(currentWindow.tabs, function(tabElements){
				tabElements.forEach(function(currentTab){
					windowLi.querySelector('ul.tabs').appendChild(currentTab);
				});
				windowList.appendChild(windowLi);
				callback();
			});
		});
	});
}

//Sets up all tabs to be in their window elements
function setupWindowElement(currentWindow,callback){
	var li = document.createElement("li");
	var ul = document.createElement("ul");
	var windowName = document.createElement("span");
	var seperator = document.createElement("span");
	var tabCount = document.createElement("span");
	var tabWord = document.createElement("span");
	li.classList.add("window");
	li.classList.add("noselect");
	ul.classList.add("tabs");
	ul.setAttribute("windowId", currentWindow.id);
	windowName.classList.add("windowName");
	windowName.textContent = currentWindow.name;
	seperator.textContent=" - "
	tabCount.classList.add("tabCount");
	tabCount.textContent = currentWindow.tabs.length.toString();
	tabWord.classList.add("tabWord");
	tabWord.textContent = (currentWindow.tabs.length>1 ? " tabs":" tab");
	li.appendChild(windowName);
	li.appendChild(seperator)
	li.appendChild(tabCount);
	li.appendChild(tabWord);
	li.appendChild(ul);
	callback(li);
}

function setupTabs(tabs,callback){
	var tabElements = [];
	tabs.forEach(function(currentTab){
		var li = document.createElement("li");
		var textSpan = document.createElement("span");
		var closeButton = document.createElement("i");
		var pinButton = document.createElement("i");
		li.setAttribute('tabId', currentTab.id);
		closeButton.classList.add("fa");
		closeButton.classList.add("fa-remove");
		closeButton.classList.add("close");
		closeButton.classList.add("noselect");
		closeButton.classList.add("pointer");
		pinButton.classList.add("fa");
		pinButton.classList.add("fa-thumb-tack");
		pinButton.classList.add("pin");
		pinButton.classList.add("noselect");
		closeButton.classList.add("pointer");
		if (currentTab.pinned){
			pinButton.classList.add("pinned");
		}
		li.classList.add("tab");
		li.classList.add("noselect");
		li.classList.add("pointer");
		//Setup favicon
		li.style.backgroundImage = "url(\'"+(currentTab.favIconUrl!==undefined && currentTab.favIconUrl!==null ? currentTab.favIconUrl:"img/default-favicon.png")+"\')";
		textSpan.classList.add("tabName");
		textSpan.textContent=currentTab.title;
		if (textSpan.textContent==""){
			textSpan.textContent="Untitled";
		}

		closeButton.onclick = function(event){
			event.preventDefault();
			event.stopPropagation();
			chrome.tabs.remove(currentTab.id);
			decrementTabCount(li);
			li.parentNode.removeChild(li);
			setHeights();
		}
		pinButton.onclick = function(event){
			event.preventDefault();
			event.stopPropagation();
			if (currentTab.pinned || pinButton.classList.contains('pinned')){
				pinButton.classList.remove("pinned");
				chrome.tabs.update(currentTab.id, {'pinned':false});
			}
			else{
				pinButton.classList.add("pinned");
				chrome.tabs.update(currentTab.id, {'pinned':true});
			}
		}
		//Switches to the tab clicked
		li.onclick = function(event){
			event.stopPropagation();
			chrome.windows.getCurrent(function(resultWindow){
				if (currentTab.id!=resultWindow.id){
					chrome.windows.update(currentTab.windowId,{'focused':true});
				}
				chrome.tabs.update(currentTab.id,{'highlighted':true,'active':true});
			});
		}

		li.appendChild(textSpan);
		textSpan.appendChild(pinButton);
		textSpan.appendChild(closeButton);
		tabElements.push(li);
	});
	callback(tabElements);
}

function decrementTabCount(tabLi){
	var ul = tabLi.parentNode;
	if (ul.tagName.toLowerCase()!='ul' || !ul.classList.contains("tabs")){
		throw "Not a tab li";
	}
	var li = ul.parentNode;
	if (li.tagName.toLowerCase()!='li' || !li.classList.contains("window")){
		throw "Not a tab li";
	}
	var tabCount = li.querySelector('span.tabCount');
	var num = parseInt(tabCount.textContent)-1;
	tabCount.textContent=num.toString();
	var windows = li.parentNode;
	if (windows.tagName.toLowerCase()!='ul' || windows.id!="windows"){
		throw "Not a tab li";
	}
	if (num===0){
		windows.removeChild(li);
	}
	setHeights();
}

function removeChildren(element){
	Array.prototype.slice.call(element.childNodes).forEach(function(child){
		element.removeChild(child);
	});
}
function search(query,callback){
	getStorage(function(windows){
		windows = windows.windows;
		windows.forEach(function(currentWindow){
			currentWindow.tabs = currentWindow.tabs.filter(function(currentTab){
				return currentTab.title.toLowerCase().indexOf(query)>-1;
			});
		});
		callback(windows);
	});
}
function createTabList(mainList,windowKeyIndex){
	return mainList.querySelectorAll('li.window')[windowKeyIndex].querySelector('ul.tabs').childNodes;
}
function setHeights(){
	var windows = document.getElementById("windows");
	var body = document.querySelector("body");
	var html = document.querySelector("html");
	var height = windows.offsetHeight+"px";
	if (windows.offsetHeight>=600){
		height = "600px";
	}
	html.style.height = height;
	body.style.height = height;
}
document.addEventListener('DOMContentLoaded', function() {
	var mainList = document.getElementById("windows");
	var filterInput = document.getElementById("search");
	var windowKeyIndex = 0;
	var tabKeyIndex = 0;
	getWindows(mainList,setHeights);
	filterInput.addEventListener('input', function(event){
		search(filterInput.value,function(windows){
			removeChildren(mainList);
			getWindows(mainList,windows,setHeights);
		});
	});
	window.addEventListener('keydown', function(event){
		var tabList = createTabList(mainList,windowKeyIndex);
		if (event.keyCode===40){
			event.preventDefault();
			event.stopPropagation();
			if (document.activeElement===filterInput){
				filterInput.blur();
			}
			else{
				tabList[tabKeyIndex].classList.remove('keyHover');
				tabKeyIndex+=1;
				if (tabKeyIndex===tabList.length){
					windowKeyIndex+=(windowKeyIndex+1<mainList.querySelectorAll('li.window').length ? 1 : 0);
					tabKeyIndex = 0;
					tabList = createTabList(mainList, windowKeyIndex);
				}
			}
			tabList[tabKeyIndex].classList.add('keyHover');
		}
		else if (event.keyCode===38){
			event.preventDefault();
			event.stopPropagation();
			if (tabList[tabKeyIndex].classList.contains('keyHover')){
				tabList[tabKeyIndex].classList.remove('keyHover');
				tabKeyIndex-=1;
				if (tabKeyIndex===-1){
					windowKeyIndex-=1;
					if (windowKeyIndex==-1){
						windowKeyIndex=0;
						tabKeyIndex = 0;
						tabList[tabKeyIndex].classList.remove('keyHover');
						filterInput.focus();
					}
					else{
						tabList = createTabList(mainList, windowKeyIndex);
						tabKeyIndex = tabList.length-1;
						tabList[tabKeyIndex].classList.add('keyHover');
					}
				}
				else{
					tabList[tabKeyIndex].classList.add('keyHover');
				}
			}
		}
		else if (event.keyCode===13){
			tabList[tabKeyIndex].click();
		}
	});
});<commit_msg>Add various comments<commit_after>var totalHeight = 0; //Total height of the body of the popup

//Gets windows from storage
function getStorage(callback){
	chrome.storage.local.get("windows",callback);
}

function getWindows(windowList,windows,callback){
	if (typeof windows==="function"){
		callback = windows;
		getStorage(function(data){
			if (data!=null){
				setupWindows(windowList,data.windows,callback);
			}
			else{
				throw "Windows is null, this hsould never happen.";
			}
		});
	}
	else{
		setupWindows(windowList,windows, callback);
	}
}

function setupWindows(windowList,windows,callback){
	debugger;
	windows.forEach(function(currentWindow){
		setupWindowElement(currentWindow, function(windowLi){
			setupTabs(currentWindow.tabs, function(tabElements){
				tabElements.forEach(function(currentTab){
					windowLi.querySelector('ul.tabs').appendChild(currentTab);
				});
				windowList.appendChild(windowLi);
				callback();
			});
		});
	});
}

//Sets up all tabs to be in their window elements
function setupWindowElement(currentWindow,callback){
	var li = document.createElement("li");
	var ul = document.createElement("ul");
	var windowName = document.createElement("span");
	var seperator = document.createElement("span");
	var tabCount = document.createElement("span");
	var tabWord = document.createElement("span");
	li.classList.add("window");
	li.classList.add("noselect");
	ul.classList.add("tabs");
	ul.setAttribute("windowId", currentWindow.id);
	windowName.classList.add("windowName");
	windowName.textContent = currentWindow.name;
	seperator.textContent=" - "
	tabCount.classList.add("tabCount");
	tabCount.textContent = currentWindow.tabs.length.toString();
	tabWord.classList.add("tabWord");
	tabWord.textContent = (currentWindow.tabs.length>1 ? " tabs":" tab");
	li.appendChild(windowName);
	li.appendChild(seperator)
	li.appendChild(tabCount);
	li.appendChild(tabWord);
	li.appendChild(ul);
	callback(li);
}

function setupTabs(tabs,callback){
	var tabElements = [];
	tabs.forEach(function(currentTab){
		var li = document.createElement("li");
		var textSpan = document.createElement("span");
		var closeButton = document.createElement("i");
		var pinButton = document.createElement("i");
		li.setAttribute('tabId', currentTab.id);
		closeButton.classList.add("fa");
		closeButton.classList.add("fa-remove");
		closeButton.classList.add("close");
		closeButton.classList.add("noselect");
		closeButton.classList.add("pointer");
		pinButton.classList.add("fa");
		pinButton.classList.add("fa-thumb-tack");
		pinButton.classList.add("pin");
		pinButton.classList.add("noselect");
		closeButton.classList.add("pointer");
		if (currentTab.pinned){
			pinButton.classList.add("pinned");
		}
		li.classList.add("tab");
		li.classList.add("noselect");
		li.classList.add("pointer");
		//Setup favicon
		li.style.backgroundImage = "url(\'"+(currentTab.favIconUrl!==undefined && currentTab.favIconUrl!==null ? currentTab.favIconUrl:"img/default-favicon.png")+"\')";
		textSpan.classList.add("tabName");
		textSpan.textContent=currentTab.title;
		if (textSpan.textContent==""){
			textSpan.textContent="Untitled";
		}

		closeButton.onclick = function(event){
			event.preventDefault();
			event.stopPropagation();
			chrome.tabs.remove(currentTab.id);
			decrementTabCount(li);
			li.parentNode.removeChild(li);
			setHeights();
		}
		pinButton.onclick = function(event){
			event.preventDefault();
			event.stopPropagation();
			if (currentTab.pinned || pinButton.classList.contains('pinned')){
				pinButton.classList.remove("pinned");
				chrome.tabs.update(currentTab.id, {'pinned':false});
			}
			else{
				pinButton.classList.add("pinned");
				chrome.tabs.update(currentTab.id, {'pinned':true});
			}
		}
		//Switches to the tab clicked
		li.onclick = function(event){
			event.stopPropagation();
			chrome.windows.getCurrent(function(resultWindow){
				if (currentTab.id!=resultWindow.id){
					chrome.windows.update(currentTab.windowId,{'focused':true});
				}
				chrome.tabs.update(currentTab.id,{'highlighted':true,'active':true});
			});
		}

		li.appendChild(textSpan);
		textSpan.appendChild(pinButton);
		textSpan.appendChild(closeButton);
		tabElements.push(li);
	});
	callback(tabElements);
}

function decrementTabCount(tabLi){
	var ul = tabLi.parentNode;
	if (ul.tagName.toLowerCase()!='ul' || !ul.classList.contains("tabs")){
		throw "Not a tab li";
	}
	var li = ul.parentNode;
	if (li.tagName.toLowerCase()!='li' || !li.classList.contains("window")){
		throw "Not a tab li";
	}
	var tabCount = li.querySelector('span.tabCount');
	var num = parseInt(tabCount.textContent)-1;
	tabCount.textContent=num.toString();
	var windows = li.parentNode;
	if (windows.tagName.toLowerCase()!='ul' || windows.id!="windows"){
		throw "Not a tab li";
	}
	if (num===0){
		windows.removeChild(li);
	}
	setHeights();
}

function removeChildren(element){
	Array.prototype.slice.call(element.childNodes).forEach(function(child){
		element.removeChild(child);
	});
}
function search(query,callback){
	getStorage(function(windows){
		windows = windows.windows;
		windows.forEach(function(currentWindow){
			currentWindow.tabs = currentWindow.tabs.filter(function(currentTab){
				return currentTab.title.toLowerCase().indexOf(query)>-1;
			});
		});
		callback(windows);
	});
}
function createTabList(mainList,windowKeyIndex){
	return mainList.querySelectorAll('li.window')[windowKeyIndex].querySelector('ul.tabs').childNodes;
}
function setHeights(){
	var windows = document.getElementById("windows");
	var body = document.querySelector("body");
	var html = document.querySelector("html");
	var height = windows.offsetHeight+"px";
	if (windows.offsetHeight>=600){
		height = "600px";
	}
	html.style.height = height;
	body.style.height = height;
}
document.addEventListener('DOMContentLoaded', function() {
	var mainList = document.getElementById("windows");
	var filterInput = document.getElementById("search");
	var windowKeyIndex = 0;
	var tabKeyIndex = 0;
	getWindows(mainList,setHeights);
	filterInput.addEventListener('input', function(event){
		search(filterInput.value,function(windows){
			removeChildren(mainList);
			getWindows(mainList,windows,setHeights);
		});
	});
	window.addEventListener('keydown', function(event){
		var tabList = createTabList(mainList,windowKeyIndex);

		//If down is pressed, traverse through tabs.
		if (event.keyCode===40){
			event.preventDefault();
			event.stopPropagation();
			if (document.activeElement===filterInput){
				filterInput.blur();
			}
			else{
				tabList[tabKeyIndex].classList.remove('keyHover');
				tabKeyIndex+=1;
				//If we're going below the last tab, change windows;
				if (tabKeyIndex===tabList.length){
					windowKeyIndex+=(windowKeyIndex+1<mainList.querySelectorAll('li.window').length ? 1 : 0);
					tabKeyIndex = 0;
					tabList = createTabList(mainList, windowKeyIndex);
				}
			}
			tabList[tabKeyIndex].classList.add('keyHover');
		}
		//If up is pressed, traverse through tabs
		else if (event.keyCode===38){
			event.preventDefault();
			event.stopPropagation();
			if (tabList[tabKeyIndex].classList.contains('keyHover')){
				tabList[tabKeyIndex].classList.remove('keyHover');
				tabKeyIndex-=1;
				//If we're going above the first tab, change windows.
				if (tabKeyIndex===-1){
					windowKeyIndex-=1;
					if (windowKeyIndex==-1){
						windowKeyIndex=0;
						tabKeyIndex = 0;
						tabList[tabKeyIndex].classList.remove('keyHover');
						filterInput.focus();
					}
					else{
						tabList = createTabList(mainList, windowKeyIndex);
						tabKeyIndex = tabList.length-1;
						tabList[tabKeyIndex].classList.add('keyHover');
					}
				}
				else{
					tabList[tabKeyIndex].classList.add('keyHover');
				}
			}
		}
		//If enter is pressed, switch to the tab.
		else if (event.keyCode===13){
			tabList[tabKeyIndex].click();
		}
	});
});<|endoftext|>


<commit_before>/*
 Preferences Library

 Usage:
   var value = window['piro.sakura.ne.jp'].prefs.getPref('my.extension.pref');
   window['piro.sakura.ne.jp'].prefs.setPref('my.extension.pref', true);
   window['piro.sakura.ne.jp'].prefs.clearPref('my.extension.pref');
   var listener = {
         domains : [
           'browser.tabs',
           'extensions.someextension'
         ],
         observe : function(aSubject, aTopic, aData)
         {
           if (aTopic != 'nsPref:changed') return;
           var value = window['piro.sakura.ne.jp'].prefs.getPref(aData);
         }
       };
   window['piro.sakura.ne.jp'].prefs.addPrefListener(listener);
   window['piro.sakura.ne.jp'].prefs.removePrefListener(listener);

 lisence: The MIT License, Copyright (c) 2009-2010 SHIMODA "Piro" Hiroshi
   http://www.cozmixng.org/repos/piro/fx3-compatibility-lib/trunk/license.txt
 original:
   http://www.cozmixng.org/repos/piro/fx3-compatibility-lib/trunk/prefs.js
   http://www.cozmixng.org/repos/piro/fx3-compatibility-lib/trunk/prefs.test.js
*/

/* To work as a JS Code Module (*require namespace.jsm)
   http://www.cozmixng.org/repos/piro/fx3-compatibility-lib/trunk/namespace.jsm */
if (typeof window == 'undefined') {
	this.EXPORTED_SYMBOLS = ['prefs'];

	let ns = {};
	Components.utils.import('resource://my-modules/namespace.jsm', ns);
	/* var */ window = ns.getNamespaceFor('piro.sakura.ne.jp');
}

(function() {
	const currentRevision = 6;

	if (!('piro.sakura.ne.jp' in window)) window['piro.sakura.ne.jp'] = {};

	var loadedRevision = 'prefs' in window['piro.sakura.ne.jp'] ?
			window['piro.sakura.ne.jp'].prefs.revision :
			0 ;
	if (loadedRevision && loadedRevision > currentRevision) {
		return;
	}

	const Cc = Components.classes;
	const Ci = Components.interfaces;

	window['piro.sakura.ne.jp'].prefs = {
		revision : currentRevision,

		Prefs : Cc['@mozilla.org/preferences;1']
					.getService(Ci.nsIPrefBranch)
					.QueryInterface(Ci.nsIPrefBranch2),

		DefaultPrefs : Cc['@mozilla.org/preferences-service;1']
					.getService(Ci.nsIPrefService)
					.getDefaultBranch(null),

		getPref : function(aPrefstring, aInterface, aBranch)
		{
			if (!aInterface || aInterface instanceof Ci.nsIPrefBranch)
				[aBranch, aInterface] = [aInterface, aBranch];

			aBranch = aBranch || this.Prefs;

			if (aInterface)
				return (aBranch.getPrefType(aPrefstring) == aBranch.PREF_INVALID) ?
						null :
						aBranch.getComplexValue(aPrefstring, aInterface);

			switch (aBranch.getPrefType(aPrefstring))
			{
				case aBranch.PREF_STRING:
					return decodeURIComponent(escape(aBranch.getCharPref(aPrefstring)));

				case aBranch.PREF_INT:
					return aBranch.getIntPref(aPrefstring);

				case aBranch.PREF_BOOL:
					return aBranch.getBoolPref(aPrefstring);

				case aBranch.PREF_INVALID:
				default:
					return null;
			}
		},

		getDefaultPref : function(aPrefstring, aInterface)
		{
			return this.getPref(aPrefstring, this.DefaultPrefs, aInterface);
		},

		setPref : function(aPrefstring, aNewValue, aBranch)
		{
			aBranch = aBranch || this.Prefs;
			switch (typeof aNewValue)
			{
				case 'string':
					return aBranch.setCharPref(aPrefstring, unescape(encodeURIComponent(aNewValue)));

				case 'number':
					return aBranch.setIntPref(aPrefstring, parseInt(aNewValue));

				default:
					return aBranch.setBoolPref(aPrefstring, aNewValue);
			}
		},

		setDefaultPref : function(aPrefstring, aNewValue)
		{
			return this.setPref(aPrefstring, aNewValue, this.DefaultPrefs);
		},

		clearPref : function(aPrefstring)
		{
			if (this.Prefs.prefHasUserValue(aPrefstring))
				this.Prefs.clearUserPref(aPrefstring);
		},

		getDescendant : function(aRoot, aBranch)
		{
			aBranch = aBranch || this.Prefs;
			return aBranch.getChildList(aRoot, {}).sort();
		},

		getChildren : function(aRoot, aBranch)
		{
			return this.getDescendant(aRoot, aBranch)
					.filter(function(aPrefstring) {
						var name = aPrefstring.replace(aRoot, '');
						if (name.charAt(0) == '.')
							name = name.substring(1);
						return name.indexOf('.') < 0;
					});
		},

		addPrefListener : function(aObserver)
		{
			var domains = ('domains' in aObserver) ? aObserver.domains : [aObserver.domain] ;
			try {
				for each (var domain in domains)
					this.Prefs.addObserver(domain, aObserver, false);
			}
			catch(e) {
			}
		},

		removePrefListener : function(aObserver)
		{
			var domains = ('domains' in aObserver) ? aObserver.domains : [aObserver.domain] ;
			try {
				for each (var domain in domains)
					this.Prefs.removeObserver(domain, aObserver, false);
			}
			catch(e) {
			}
		}
	};
})();

if (this.prefs = window['piro.sakura.ne.jp'].prefs;
}
<commit_msg>syntax error<commit_after>/*
 Preferences Library

 Usage:
   var value = window['piro.sakura.ne.jp'].prefs.getPref('my.extension.pref');
   window['piro.sakura.ne.jp'].prefs.setPref('my.extension.pref', true);
   window['piro.sakura.ne.jp'].prefs.clearPref('my.extension.pref');
   var listener = {
         domains : [
           'browser.tabs',
           'extensions.someextension'
         ],
         observe : function(aSubject, aTopic, aData)
         {
           if (aTopic != 'nsPref:changed') return;
           var value = window['piro.sakura.ne.jp'].prefs.getPref(aData);
         }
       };
   window['piro.sakura.ne.jp'].prefs.addPrefListener(listener);
   window['piro.sakura.ne.jp'].prefs.removePrefListener(listener);

 lisence: The MIT License, Copyright (c) 2009-2010 SHIMODA "Piro" Hiroshi
   http://www.cozmixng.org/repos/piro/fx3-compatibility-lib/trunk/license.txt
 original:
   http://www.cozmixng.org/repos/piro/fx3-compatibility-lib/trunk/prefs.js
   http://www.cozmixng.org/repos/piro/fx3-compatibility-lib/trunk/prefs.test.js
*/

/* To work as a JS Code Module (*require namespace.jsm)
   http://www.cozmixng.org/repos/piro/fx3-compatibility-lib/trunk/namespace.jsm */
if (typeof window == 'undefined') {
	this.EXPORTED_SYMBOLS = ['prefs'];

	let ns = {};
	Components.utils.import('resource://my-modules/namespace.jsm', ns);
	/* var */ window = ns.getNamespaceFor('piro.sakura.ne.jp');
}

(function() {
	const currentRevision = 6;

	if (!('piro.sakura.ne.jp' in window)) window['piro.sakura.ne.jp'] = {};

	var loadedRevision = 'prefs' in window['piro.sakura.ne.jp'] ?
			window['piro.sakura.ne.jp'].prefs.revision :
			0 ;
	if (loadedRevision && loadedRevision > currentRevision) {
		return;
	}

	const Cc = Components.classes;
	const Ci = Components.interfaces;

	window['piro.sakura.ne.jp'].prefs = {
		revision : currentRevision,

		Prefs : Cc['@mozilla.org/preferences;1']
					.getService(Ci.nsIPrefBranch)
					.QueryInterface(Ci.nsIPrefBranch2),

		DefaultPrefs : Cc['@mozilla.org/preferences-service;1']
					.getService(Ci.nsIPrefService)
					.getDefaultBranch(null),

		getPref : function(aPrefstring, aInterface, aBranch)
		{
			if (!aInterface || aInterface instanceof Ci.nsIPrefBranch)
				[aBranch, aInterface] = [aInterface, aBranch];

			aBranch = aBranch || this.Prefs;

			if (aInterface)
				return (aBranch.getPrefType(aPrefstring) == aBranch.PREF_INVALID) ?
						null :
						aBranch.getComplexValue(aPrefstring, aInterface);

			switch (aBranch.getPrefType(aPrefstring))
			{
				case aBranch.PREF_STRING:
					return decodeURIComponent(escape(aBranch.getCharPref(aPrefstring)));

				case aBranch.PREF_INT:
					return aBranch.getIntPref(aPrefstring);

				case aBranch.PREF_BOOL:
					return aBranch.getBoolPref(aPrefstring);

				case aBranch.PREF_INVALID:
				default:
					return null;
			}
		},

		getDefaultPref : function(aPrefstring, aInterface)
		{
			return this.getPref(aPrefstring, this.DefaultPrefs, aInterface);
		},

		setPref : function(aPrefstring, aNewValue, aBranch)
		{
			aBranch = aBranch || this.Prefs;
			switch (typeof aNewValue)
			{
				case 'string':
					return aBranch.setCharPref(aPrefstring, unescape(encodeURIComponent(aNewValue)));

				case 'number':
					return aBranch.setIntPref(aPrefstring, parseInt(aNewValue));

				default:
					return aBranch.setBoolPref(aPrefstring, aNewValue);
			}
		},

		setDefaultPref : function(aPrefstring, aNewValue)
		{
			return this.setPref(aPrefstring, aNewValue, this.DefaultPrefs);
		},

		clearPref : function(aPrefstring)
		{
			if (this.Prefs.prefHasUserValue(aPrefstring))
				this.Prefs.clearUserPref(aPrefstring);
		},

		getDescendant : function(aRoot, aBranch)
		{
			aBranch = aBranch || this.Prefs;
			return aBranch.getChildList(aRoot, {}).sort();
		},

		getChildren : function(aRoot, aBranch)
		{
			return this.getDescendant(aRoot, aBranch)
					.filter(function(aPrefstring) {
						var name = aPrefstring.replace(aRoot, '');
						if (name.charAt(0) == '.')
							name = name.substring(1);
						return name.indexOf('.') < 0;
					});
		},

		addPrefListener : function(aObserver)
		{
			var domains = ('domains' in aObserver) ? aObserver.domains : [aObserver.domain] ;
			try {
				for each (var domain in domains)
					this.Prefs.addObserver(domain, aObserver, false);
			}
			catch(e) {
			}
		},

		removePrefListener : function(aObserver)
		{
			var domains = ('domains' in aObserver) ? aObserver.domains : [aObserver.domain] ;
			try {
				for each (var domain in domains)
					this.Prefs.removeObserver(domain, aObserver, false);
			}
			catch(e) {
			}
		}
	};
})();

if (window != this) { // work as a JS Code Module
	this.prefs = window['piro.sakura.ne.jp'].prefs;
}
<|endoftext|>


<commit_before>'use strict';
/*global unescape: true */
/**
 * Local proxy (load balancing for development)
 * node proxy [n] -> Run proxy over 443 try to find nodes, from BasePort + 1 to BasePort + n
 */
// This example demonstrates using sticky session
// support
var httpProxy   = require('http-proxy');
var fs = require('fs');
var http = require('http');
var https = require('https');
var logger = require('./log.js').getLog('proxy');

var sport = process.env.LOOWID_HTTPS_PORT || 443;
var port = process.env.LOOWID_HTTP_PORT || 80;
var basePort = Number(process.env.LOOWID_BASE_PORT || 8000);

var isRunningTests = function() {
	return (process.argv[2] && process.argv[2].indexOf('jasmine_node:')===0) || process.argv[3]==='test';
};

//
//Create the HTTPS proxy server in front of a HTTP server
//

var targets = [];

var parseCookies = function(request) {
    var list = {}, rc = request.headers.cookie;
    if (rc) {
    	rc.split(';').forEach(function( cookie ) {
    		var parts = cookie.split('=');
    		list[parts.shift().trim()] = decodeURI(parts.join('='));
    	});
    }
    return list;
};

var findStickyServer = function(req) {
	var sid = unescape(parseCookies(req).stickyid);
	var id = targets.indexOf(sid);
	if (id<0) {
		sid = targets[Math.floor(Math.random()*targets.length)];
		req.headers.stickyid = sid;
	}
	logger.debug(sid+req.url);
	return sid;
};

var addBackend = function(srv) {
	var i = targets.indexOf(srv);
	if (i<0) {
		logger.info('Add backend '+srv);
		targets.push(srv);
	}
};

var removeBackend = function(srv) {
	var i = targets.indexOf(srv);
	if (i>=0) {
		logger.info('Remove backend '+srv);
		targets.splice(i,1);
	}
};

var validateBackend = function(h,p) {
	var options = {
		host: h,
		path: '/img/icons/favicon.ico',
		port: p
	};
	var req = http.get(options,function(response){
		addBackend('http://'+h+':'+p);
	});
	req.on('error',function(err){
		removeBackend('http://'+h+':'+p);
	});
};

var backends = isNaN(process.argv[2])?Number(process.env.JASMINE_NODES || 2):(process.argv[2]-0);

var checkServers = function() {
	for (var j=1; j<=backends; j+=1) {
		validateBackend('localhost',basePort+j);
	}
	// Check new servers every 5 seconds !!
	setTimeout(checkServers,5000);
};

var proxy = null;
var httpServer = null;

try {

	var prvf = process.env.PRIVATE_KEY || 'private.pem';
	var pubf = process.env.PUBLIC_KEY || 'public.pem';

	if (!isRunningTests()) {

		proxy = httpProxy.createProxyServer({
			target: 'http://localhost',
			ssl: {
			 key: fs.readFileSync(prvf, 'utf8'),
			 cert: fs.readFileSync(pubf, 'utf8')
			},
			ws:true,
			secure:true
		});

		httpServer = https.createServer({
			key: fs.readFileSync(prvf, 'utf8'),
			cert: fs.readFileSync(pubf, 'utf8')
		}, function(req, res){
			var tg = findStickyServer(req);
			proxy.web(req, res, {target:tg}, function(){
				removeBackend(tg);
			});
		}).listen(sport, '0.0.0.0');

		var server = http.createServer(function (req, res) {
		  // optional, for HSTS
		  // see https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security
		  res.setHeader('Strict-Transport-Security', 'max-age=8640000; includeSubDomains');

		  if (req.headers['x-forwarded-proto'] !== 'https') {
		    var url = 'https://' + req.headers.host + (sport!==443?':'+sport:'') + '/';
		    res.writeHead(301, {'location': url});
		    return res.end('Redirecting to ' + url + '.');
		  }
		});

		server.listen(port);
		logger.info('Listen for redirect on port ' + port);

	} else {
		// Test is always running under http
		proxy = httpProxy.createProxyServer({
			target: 'http://localhost',
			ws:true
		});

		httpServer = http.createServer(function(req, res){
			var tg = findStickyServer(req);
			proxy.web(req, res, {target:tg}, function(){
				removeBackend(tg);
			});
		}).listen(sport, '0.0.0.0');

	}

} catch (ex) {

	logger.warn(ex.message);

}

process.on('uncaughtException', function (err) {
	if (err.errno === 'ECONNRESET') {
		// Backend server fail !!
		checkServers();
	} else {
		logger.error(err);
	}
});

httpServer.on('upgrade', function (req, socket, head) {
	var tg = findStickyServer(req);
    proxy.ws(req, socket, head, {target:tg}, function(){
		removeBackend(tg);
	});
});

logger.info('Running load balancer in port '+sport);
// Look for backends !!
setTimeout(checkServers,5000);

exports.isReady = function() {
	return targets.length===backends;
};
<commit_msg>Check if certificate is available in proxy. Fixes #195<commit_after>'use strict';
/*global unescape: true */
/**
 * Local proxy (load balancing for development)
 * node proxy [n] -> Run proxy over 443 try to find nodes, from BasePort + 1 to BasePort + n
 */
// This example demonstrates using sticky session
// support
var httpProxy   = require('http-proxy');
var fs = require('fs');
var http = require('http');
var https = require('https');
var logger = require('./log.js').getLog('proxy');

var sport = process.env.LOOWID_HTTPS_PORT || 443;
var port = process.env.LOOWID_HTTP_PORT || 80;
var basePort = Number(process.env.LOOWID_BASE_PORT || 8000);

var isRunningTests = function() {
	return (process.argv[2] && process.argv[2].indexOf('jasmine_node:')===0) || process.argv[3]==='test';
};

//
//Create the HTTPS proxy server in front of a HTTP server
//

var targets = [];

var parseCookies = function(request) {
    var list = {}, rc = request.headers.cookie;
    if (rc) {
    	rc.split(';').forEach(function( cookie ) {
    		var parts = cookie.split('=');
    		list[parts.shift().trim()] = decodeURI(parts.join('='));
    	});
    }
    return list;
};

var findStickyServer = function(req) {
	var sid = unescape(parseCookies(req).stickyid);
	var id = targets.indexOf(sid);
	if (id<0) {
		sid = targets[Math.floor(Math.random()*targets.length)];
		req.headers.stickyid = sid;
	}
	logger.debug(sid+req.url);
	return sid;
};

var addBackend = function(srv) {
	var i = targets.indexOf(srv);
	if (i<0) {
		logger.info('Add backend '+srv);
		targets.push(srv);
	}
};

var removeBackend = function(srv) {
	var i = targets.indexOf(srv);
	if (i>=0) {
		logger.info('Remove backend '+srv);
		targets.splice(i,1);
	}
};

var validateBackend = function(h,p) {
	var options = {
		host: h,
		path: '/img/icons/favicon.ico',
		port: p
	};
	var req = http.get(options,function(response){
		addBackend('http://'+h+':'+p);
	});
	req.on('error',function(err){
		removeBackend('http://'+h+':'+p);
	});
};

var backends = isNaN(process.argv[2])?Number(process.env.JASMINE_NODES || 2):(process.argv[2]-0);

var checkServers = function() {
	for (var j=1; j<=backends; j+=1) {
		validateBackend('localhost',basePort+j);
	}
	// Check new servers every 5 seconds !!
	setTimeout(checkServers,5000);
};

var proxy = null;
var httpServer = null;

try {

	var credentials = {};
	var certificateAvailable = true;

	try {
		var fs = require('fs');
		// Generado con http://www.cert-depot.com/
		var privateKey = fs.readFileSync(process.env.PRIVATE_KEY || 'private.pem','utf-8');
		var certificate = fs.readFileSync(process.env.PUBLIC_KEY || 'public.pem','utf-8');
		var credentials = {
			key : privateKey,
			cert : certificate
		};
	} catch (ex) {
		logger.warn(ex.message);
		certificateAvailable = false;
	}

	if (!isRunningTests() && certificateAvailable) {

		proxy = httpProxy.createProxyServer({
			target: 'http://localhost',
			ssl: credentials,
			ws:true,
			secure:true
		});

		httpServer = https.createServer(credentials, function(req, res){
			var tg = findStickyServer(req);
			proxy.web(req, res, {target:tg}, function(){
				removeBackend(tg);
			});
		}).listen(sport, '0.0.0.0');

		var server = http.createServer(function (req, res) {
		  // optional, for HSTS
		  // see https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security
		  res.setHeader('Strict-Transport-Security', 'max-age=8640000; includeSubDomains');

		  if (req.headers['x-forwarded-proto'] !== 'https') {
		    var url = 'https://' + req.headers.host + (sport!==443?':'+sport:'') + '/';
		    res.writeHead(301, {'location': url});
		    return res.end('Redirecting to ' + url + '.');
		  }
		});

		server.listen(port);
		logger.info('Listen for redirect on port ' + port);

	} else {
		// Test is always running under http
		proxy = httpProxy.createProxyServer({
			target: 'http://localhost',
			ws:true
		});

		httpServer = http.createServer(function(req, res){
			var tg = findStickyServer(req);
			proxy.web(req, res, {target:tg}, function(){
				removeBackend(tg);
			});
		}).listen(sport, '0.0.0.0');

	}

} catch (ex) {

	logger.warn(ex.message);

}

process.on('uncaughtException', function (err) {
	if (err.errno === 'ECONNRESET') {
		// Backend server fail !!
		checkServers();
	} else {
		logger.error(err);
	}
});

httpServer.on('upgrade', function (req, socket, head) {
	var tg = findStickyServer(req);
    proxy.ws(req, socket, head, {target:tg}, function(){
		removeBackend(tg);
	});
});

logger.info('Running load balancer in port '+sport);
// Look for backends !!
setTimeout(checkServers,5000);

exports.isReady = function() {
	return targets.length===backends;
};
<|endoftext|>


<commit_before>'use strict';

var express = require('express'),
    request = require('superagent'),
    app     = express(),
    config  = require('./config');

app.get('*', function(req, res){
  var endpoint = config[req.url];

  if (req.url === '/') {
    res.redirect('http://redhat.com/events');
    return;
  }

  if (req.url === '/forum') {
    res.redirect('http://www.redhat.com/en/about/events?f0=field_event_type%3A8101&rset1_format=list&f0=field_event_type%3A8101');
    return;
  }

  if (endpoint === undefined) {
    res.redirect('/forum');
    return;
  }

  res.writeHead(200, { 'Content-Type' : 'text/html' });

  request
    .get(endpoint)
    .pipe(res);
});

app.listen(8000);

<commit_msg>Add missing [] from url<commit_after>'use strict';

var express = require('express'),
    request = require('superagent'),
    app     = express(),
    config  = require('./config');

app.get('*', function(req, res){
  var endpoint = config[req.url];

  if (req.url === '/') {
    res.redirect('http://redhat.com/events');
    return;
  }

  if (req.url === '/forum') {
    res.redirect('http://www.redhat.com/en/about/events?f[0]=field_event_type%3A8101&rset1_format=list');
    return;
  }

  if (endpoint === undefined) {
    res.redirect('/forum');
    return;
  }

  res.writeHead(200, { 'Content-Type' : 'text/html' });

  request
    .get(endpoint)
    .pipe(res);
});

app.listen(8000);

<|endoftext|>


<commit_before>#!/usr/bin/node

<commit_msg>htttttteeeeeeeppp<commit_after>#!/usr/bin/node

var http = require('http');
var httpProxy = require('http-proxy');

var net = require('net');

setInterval(function() {
  console.log('hi')
  },5000);

http.createServer(function(req, res) {
  res.end('hello world\n');
  }).listen(8080);
<|endoftext|>


<commit_before>//==UserScript==
// @name Purge
// @namespace https://csgolounge.com/
// @author Saša Marjanović <sasa.marjanovic1994@gmail.com>
// @description Automated userscript which removes comments from CSGOLounge trades.
// @version 2.0
// @include https://csgolounge.com/mytrades
// @include http://csgolounge.com/mytrades
// @include https://csgolounge.com/trade?t=*
// @include http://csgolounge.com/trade?t=*
// @grant none
// ==/UserScript==

var url = [
    "https://csgolounge.com/mytrades",
    "http://csgolounge.com/mytrades",
    "https://www.csgolounge.com/mytrades",
    "http://www.csgolounge.com/mytrades"
];

function save(arr) {
    var str = JSON.stringify(arr);
    sessionStorage.setItem('KEY', str);
}

if (window.location.href.match(url[0] || url[1] || url[2] || url[3])) {
    purgeBtn = document.createElement("a");
    purgeBtn.id = "menu";
    document.querySelector("#menu").appendChild(purgeBtn);
    purgeBtn.innerHTML = "PURGE";
    purgeBtn.addEventListener("click", function () {
        linksArr = [];
        var prg = "#purge";
        var trades = document.querySelectorAll('.tradeheader');
        for (i = 0; i < trades.length; i++) {
            if (!trades[i].children[0].href) linksArr.push(trades[i].children[1].href + prg);
            else linksArr.push(trades[i].children[0].href + prg);
        }
        var init = linksArr.shift();
        save(linksArr);
        window.location.replace(init);
    });
} else if (window.location.href.match(/https:\/\/csgolounge\.com\/trade\?t=[0-9]*#purge/)) {
    var trashCan = document.querySelectorAll('.opts');
    var clean = document.querySelectorAll('.half')[1].children[0];
    var msg = document.querySelectorAll('.message');
    var linksArr2 = JSON.parse(sessionStorage.KEY);
    var link = linksArr2.shift();

    if (msg.length > 2) {
        trashCan.forEach(function (val) {
            var remove = val.children[0];
            var block = val.children[1];
            if (val.parentElement.children[2].innerText.match(/http/i)) {
                block.click();
                remove.click();
            } else remove.click();
        });

        setTimeout(function () {
            clean.click();
        }, 1000);
    } else {
        save(linksArr2);
        if (!link) {
            sessionStorage.removeItem('KEY');
            window.location.replace('https://csgolounge.com/mytrades');
        } else window.location.replace(link);
    }
}
<commit_msg>add few statements to properly select buttons<commit_after>//==UserScript==
// @name Purge
// @namespace https://csgolounge.com/
// @author Saša Marjanović <sasa.marjanovic1994@gmail.com>
// @description Automated userscript which removes comments from CSGOLounge trades.
// @version 2.1
// @include https://csgolounge.com/mytrades
// @include http://csgolounge.com/mytrades
// @include https://csgolounge.com/trade?t=*
// @include http://csgolounge.com/trade?t=*
// @grant none
// ==/UserScript==

var url = [
    "https://csgolounge.com/mytrades",
    "http://csgolounge.com/mytrades",
    "https://www.csgolounge.com/mytrades",
    "http://www.csgolounge.com/mytrades",
    "http://csgolounge.com/img/trash.png",
    "http://csgolounge.com/img/ban.png"
];

function save(arr) {
    var str = JSON.stringify(arr);
    sessionStorage.setItem('KEY', str);
}

if (window.location.href.match(url[0] || url[1] || url[2] || url[3])) {
    purgeBtn = document.createElement("a");
    purgeBtn.id = "menu";
    document.querySelector("#menu").appendChild(purgeBtn);
    purgeBtn.innerHTML = "PURGE";
    purgeBtn.addEventListener("click", function () {
        linksArr = [];
        var prg = "#purge";
        var trades = document.querySelectorAll('.tradeheader');
        for (i = 0; i < trades.length; i++) {
            if (!trades[i].children[0].href) linksArr.push(trades[i].children[1].href + prg);
            else linksArr.push(trades[i].children[0].href + prg);
        }
        var init = linksArr.shift();
        save(linksArr);
        window.location.replace(init);
    });
} else if (window.location.href.match(/https:\/\/csgolounge\.com\/trade\?t=[0-9]*#purge/)) {
    var msgOpts = document.querySelectorAll('.opts');
    var clean = document.querySelectorAll('.half')[1].children[0];
    var msg = document.querySelectorAll('.message');
    var linksArr2 = JSON.parse(sessionStorage.KEY);
    var link = linksArr2.shift();

    if (msg.length > 2) {
        msgOpts.forEach(function (val) {
            var remove = val.children[0];
            var block = val.children[1];
            if (val.parentElement.children[2].innerText.match(/http/i)) {
                if ((remove.firstChild.src == url[4]) && (block.firstChild.src == url[5])) {
                    block.click();
                    remove.click();
                } else if (remove.firstChild.src == url[5]) remove.click();
            } else remove.click();
        });
        setTimeout(function () {
            clean.click();
        }, 1000);
    } else {
        save(linksArr2);
        if (!link) {
            sessionStorage.removeItem('KEY');
            window.location.replace('https://csgolounge.com/mytrades');
        } else window.location.replace(link);
    }
}
<|endoftext|>


<commit_before>(function(exports) {

    aight.d3 = {};

    if (aight.browser.ie8) {
        function mapped(property, format, parse) {
            var read = function(p) {
                    var value = this.node().style[property];
                    return parse
                        ? parse.call(this, value, p)
                        : value;
                },
                write = function(p, value) {
                    return this.each(function() {
                        var v = (typeof value === "function")
                            ? value.apply(this, arguments)
                            : value;
                        this.style[property] = format
                            ? format.call(this, v, p)
                            : v;
                    });
                };
            return function() {
                return arguments.length > 1
                    ? write.apply(this, arguments)
                    : read.call(this);
            };
        }

        var aight_d3_style = {
            "background-image":         mapped("backgroundImage"),
            "background-repeat":        mapped("backgroundRepeat"),
            "background-position":      mapped("backgroundPosition"),
            "background-color":         mapped("backgroundColor"),

            "opacity":                  mapped("filter",
                function opacity_to_filter(opacity) {
                    return ["alpha(opacity=", Math.round(opacity * 100), ")"].join("");
                },
                function filter_to_opacity(filter) {
                    var opacity = (filter || "").match(/opacity=(\d+)/)[1] || 100;
                    return opacity / 100;
                })
        };

        aight.d3.style = aight_d3_style;

        var d3_style = d3.selection.prototype.style;
        d3.selection.prototype.style = function(prop) {
            var style = aight_d3_style.hasOwnProperty(prop)
                ? aight_d3_style[prop]
                : d3_style;
            return style.apply(this, arguments);
        };
    }

})(this);
<commit_msg>better opacity shim, null values remove mapped CSS properties<commit_after>(function(exports) {

  aight.d3 = {};

  if (aight.browser.ie8) {
    function mappedProperty(property, format, parse) {
      var read = function(p) {
          var value = this.node().style[property];
          return parse
            ? parse.call(this, value, p)
            : value;
        },
        write = function(p, value) {
          if (value === null) {
            return this.style(property, null);
          }
          return this.each(function() {
            var v = (typeof value === "function")
              ? value.apply(this, arguments)
              : value;
            if (v === null) {
              this.style.removeProperty(property);
            } else {
              this.style[property] = format
                ? format.call(this, v, p)
                : v;
            }
          });
        };
      return function() {
        return arguments.length > 1
          ? write.apply(this, arguments)
          : read.call(this);
      };
    }

    var aight_d3_style = {
      // background styles need to be mapped explicitly
      "background-image":     mappedProperty("backgroundImage"),
      "background-repeat":    mappedProperty("backgroundRepeat"),
      "background-position":  mappedProperty("backgroundPosition"),
      "background-color":     mappedProperty("backgroundColor"),

      "opacity": mappedProperty("filter",
        function opacity_to_filter(opacity) {
          return isNaN(opacity)
            ? null
            : ["alpha(opacity=", Math.round(opacity * 100), ")"].join("");
        },
        function filter_to_opacity(filter) {
          var match = (filter || "").match(/alpha\(opacity=(\d+)\)/);
          return match ? match[1] / 100 : 1;
        })
    };

    aight.d3.style = aight_d3_style;

    var d3_style = d3.selection.prototype.style;
    d3.selection.prototype.style = function(prop) {
      var style = aight_d3_style.hasOwnProperty(prop)
        ? aight_d3_style[prop]
        : d3_style;
      return style.apply(this, arguments);
    };

  }

})(this);
<|endoftext|>