<commit_before>"use strict";

(function (context) {

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

const nsTransferable = CC("@mozilla.org/widget/transferable;1",
							  "nsITransferable");

/**
 * A wrapper around nsITransferable that sets the source in order to respect
 * Private Browsing Mode.
 */
function Transferable(win) {
	let xfer = nsTransferable();
	if ("init" in xfer) {
		if (win instanceof Ci.nsIDOMWindow) {
			win = win.QueryInterface(Ci.nsIInterfaceRequestor)
				.getInterface(Ci.nsIWebNavigation);
		}
		xfer.init(win);
	}
	return xfer;
}

/*
 * Proxy for a Google Kix editor to pose as an ordinary HTML <textarea>.
 *
 * @param evt		{object}	The keyPress event.
 */
function KixProxy(evt) {
	if (evt.keyCode == evt.DOM_VK_BACK_SPACE && !evt.shiftKey) {
		throw "Backspace.";
	}

	let doc = evt.originalTarget.ownerDocument;
	if (!doc || !doc.body) throw "No document body to copy from.";

	let win = doc.defaultView;
	let winUtils = win.QueryInterface(Ci.nsIInterfaceRequestor)
		.getInterface(Ci.nsIDOMWindowUtils);
	if (!winUtils || !("sendKeyEvent" in winUtils &&
					   "sendCompositionEvent" in winUtils &&
					   "sendContentCommandEvent" in winUtils)) {
		// Parts of the API are only available starting in Gecko 1.9 or 2.0.
		throw "Can't issue native events."
	}

	let frame = win.frameElement;
	if (!frame) throw "Not in iframe.";
	let frameDoc = frame.ownerDocument;

	const overlaySelector = ".kix-selection-overlay,.sketchy-text-selection-overlay";
	const presItemType = "http://schema.org/CreativeWork/PresentationObject";
	const drawingItemType = "http://schema.org/CreativeWork/DrawingObject";

	/**
	 * Returns whether text is currently selected in the editor, as indicated by
	 * the presence of a selection rectangle overlay.
	 */
	this.hasSelection = function() {
		return frameDoc.querySelectorAll(overlaySelector).length;
	};

	const isMac = win.navigator.platform == "MacPPC" ||
		win.navigator.platform == "MacIntel";

	const tablePropsSel = "[role='menuitem'][aria-disabled='false'] " +
		"[aria-label^='Table properties']";
	const altTextSel = "[role='menuitem'][aria-disabled='false'] " +
		"[aria-label^='Alt text']";

	/**
	 * Returns whether the caret is currently in a table.
	 *
	 * The caret is in a table if the Table | Table Properties menu item is
	 * enabled.
	 *
	 * @returns {boolean}	True if the caret is in a table; false otherwise.
	 */
	this.isInTable = function() {
		return frameDoc.querySelector(tablePropsSel);
	};

	let itemType = frame.ownerDocument.body.getAttribute("itemtype");

	/**
	 * Returns whether a resizable (i.e., non-text) object is selected.
	 */
	this.isObjectSelected = function () {
		return itemType != drawingItemType && itemType != presItemType &&
			frameDoc.querySelector(altTextSel);
	};

	/**
	 * Generates a key event that selects the previous word or optionally to
	 * to beginning of the line.
	 *
	 * Mozilla observes the following platform-specific bindings for
	 * cmd_selectWordPrevious:
	 * 	/content/xbl/builtin/unix/platformHTMLBindings.xml	VK_LEFT	control,shift
	 * 	/content/xbl/builtin/mac/platformHTMLBindings.xml	VK_LEFT	alt,shift
	 * 	/content/xbl/builtin/emacs/platformHTMLBindings.xml	VK_LEFT	control,shift
	 * 	/content/xbl/builtin/win/platformHTMLBindings.xml	VK_LEFT	control,shift
	 * and for cmd_selectBeginLine:
	 * 	/content/xbl/builtin/unix/platformHTMLBindings.xml	VK_HOME	shift
	 * 	/content/xbl/builtin/mac/platformHTMLBindings.xml	VK_LEFT	accel,shift
	 * 	/content/xbl/builtin/emacs/platformHTMLBindings.xml	VK_HOME	shift
	 * 	/content/xbl/builtin/win/platformHTMLBindings.xml	VK_HOME	shift
	 *
	 * @param toLineStart	{boolean}	True to extend the selection to the
	 * 									start of the line; false otherwise.
	 */
	this.selectPrecedingWord = function(toLineStart) {
//		dump("KixProxy.selectPrecedingWord()\n");								// debug
		let key = (isMac || !toLineStart) ?
			evt.DOM_VK_LEFT : evt.DOM_VK_HOME;
		let modifiers = (isMac || toLineStart) ?
			evt.SHIFT_MASK : (evt.CONTROL_MASK | evt.SHIFT_MASK);
		if (isMac) modifiers |= toLineStart ? evt.META_MASK : evt.ALT_MASK;
		winUtils.sendKeyEvent("keypress", key, 0, modifiers);
	};

	const board = Cc["@mozilla.org/widget/clipboard;1"]
		.getService(Ci.nsIClipboard);

	/**
	 * Returns the contents of the clipboard.
	 */
	this.getClipboardData = function () {
		if (!board.hasDataMatchingFlavors(["text/unicode"], 1,
										  board.kGlobalClipboard)) {
			return false;
		}
		let xfer = Transferable(frameDoc.defaultView);
		// TODO: Use the text/html flavor to retain formatting.
		xfer.addDataFlavor("text/unicode");
		board.getData(xfer, board.kGlobalClipboard);
		return xfer;
	};

	/**
	 * Returns the text contents of the clipboard.
	 */
	this.getClipboardText = function() {
		let xfer = this.getClipboardData();
		if (!xfer) return "";

		// https://developer.mozilla.org/en/Using_the_Clipboard
		let str = new Object(), len = new Object();
		try {
			xfer.getTransferData("text/unicode", str, len);
		}
		catch (exc) {
			// At the beginning of a new line (but not the beginning of the
			// document), the previous line break has been selected.
			return "\n";
		}
		str = str && str.value.QueryInterface(Ci.nsISupportsString);
		// text/unicode is apparently stored as UTF-16.
		str = str && str.data.substring(0, len.value / 2);
		// BOM can occur at the beginning of the document.
		return str != "\ufeff" && str;
	};

	/**
	 * Generates a right-arrow key event that returns the selection to where it
	 * was before KixProxy started modifying it.
	 */
	this.revertSelection = function() {
//		dump("KixProxy.revertSelection()\n");									// debug
		winUtils.sendKeyEvent("keypress", evt.DOM_VK_RIGHT, 0, 0);
	};

	/**
	 * Generates a shift-right-arrow key event that removes the leftmost
	 * character from the selection.
	 */
	this.trimLeftSelection = function() {
		winUtils.sendKeyEvent("keypress", evt.DOM_VK_RIGHT, 0,
							  Event.SHIFT_MASK);
	};

	/**
	 * Copies and retrieves the selected text. Callers are responsible for
	 * reverting the clipboard contents.
	 *
	 * @throws {string}	when there was no selection, or the selection was
	 * 					nothing but spaces, in which case the selection is
	 * 					reverted.
	 */
	this.getSelectedText = function(isInTable) {
		// Clear the clipboard.
		board.emptyClipboard(board.kGlobalClipboard);

		// Copy the word.
		winUtils.sendContentCommandEvent("copy");

		// Retrieve the text from the clipboard.
		let value = this.getClipboardText();
		if (!value) {
			// Objects may not be copied as text, but they may be selected.
			if (this.hasSelection()) this.revertSelection();
			return "";
		}
		// Probably the beginning of a line (or the line has just spaces).
		if (!value.trim()) {
			this.revertSelection();
			return "";
		}
		return value;
	};

	// Abort if there is a selection. The selection rectangle is an overlay
	// element that can be identified by its (platform-specific) class.
	if (this.hasSelection()) throw "Non-empty selection.";

	// Select the previous word.
	let wasInTable = this.isInTable();
//	if (wasInTable) dump("KixProxy -- Caret in table.\n");						// debug
	this.selectPrecedingWord(wasInTable);
	if ((!wasInTable && this.isInTable()) || this.isObjectSelected()) {
		// The selection now lies in the table, so the caret was right after
		// the table.
		this.trimLeftSelection();
		throw "Right after table or resizable object.";
	}
	if (this.hasSelection() > 1) {
//		dump("KixProxy -- More than one line selected.\n");						// debug
		// A horizontal line may have been included in the selection, or the
		// word spans more than one line.
		this.revertSelection();
		// There will only be one word in this selection.
		this.selectPrecedingWord(true);
	}

	// Get the selected text.
	let value = this.getSelectedText();
	if (wasInTable && value) {
		//dump("KixProxy -- Reselecting text in table.\n");					// debug
		// Unselect the text, unless the cell and selection are empty.
		this.revertSelection();
		// Reselect the text, this time just the preceding word.
		this.selectPrecedingWord(false);
		value = this.getSelectedText();
	}
	if (!value) throw "No text.";
	if (!context.lastWordInString(value)) {
		this.revertSelection();
		throw "No word.";
	}
//	dump("KixProxy -- value: <" + value + ">\n");								// debug

	this.value = this.oldValue = value;
	this.selectionStart = this.selectionEnd = this.value.length;

	/**
	 * Updates the Kix editor represented by this proxy to reflect any changes
	 * made to the proxy.
	 *
	 * @returns {boolean}	True if anything was changed; false otherwise.
	 */
	this.commit = function() {
//		dump("KixProxy.commit -- value: <" + this.value + ">; oldValue: <" + this.oldValue + ">\n");	// debug
		if (this.value == this.oldValue) {
			if (this.value) this.revertSelection();
			return false;
		}

		// Paste the updated string into the editor.
		// In Kix 3790525131, which sends events to
		// "docs-texteventtarget-iframe", wrapping the paste operation in a
		// composition prevents the selection from flashing.
		// In Kix 3491395419, "kix-clipboard-iframe" inserts a newline after the
		// composition ends, breaking editing.
		// kix_2014.35-Tue_c handles pastes asynchronously, so insert one
		// character at a time.
		winUtils.sendKeyEvent("keypress", evt.DOM_VK_BACK_SPACE, 0, 0);
		winUtils.sendCompositionEvent("compositionstart", "", "");
		try {
			for (let i = 0; i < this.value.length; i++) {
				winUtils.sendKeyEvent("keypress", 0, this.value.charCodeAt(i),
									  0);
			}
		}
		finally {
			winUtils.sendCompositionEvent("compositionend", "", "");
		}

		return true;
	};
}

context.lazyHandlers.kix = function (evt) {
	let elt = evt.originalTarget;
	let doc = elt.ownerDocument;
	if ("_avim_isBeingHandled" in elt || !("querySelector" in doc)) {
		return false;
	}
	let frame = doc.defaultView.frameElement;
	if (!frame || !("classList" in frame) ||
		!(frame.classList.contains("docs-texteventtarget-iframe") ||
		  frame.classList.contains("kix-clipboard-iframe"))) {
		return false;
	}

	// Prevent reentrancy due to keypress events being sent by commit(). (#85)
	elt._avim_isBeingHandled = true;
//	dump("AVIM.handleKix\n");													// debug

	// Get the existing clipboard data in as many formats as the application
	// would likely recognize. Unfortunately, everything else will be lost.
	// TODO: Implement nsIClipboardDragDropHooks to override the clipboard, to
	// avoid dropping any clipboard data.
	const board = Cc["@mozilla.org/widget/clipboard;1"]
		.getService(Ci.nsIClipboard);
	let xfer = Transferable(doc.defaultView);
	let flavors = [
		// /widget/public/nsITransferable.idl
		"text/plain",				// kTextMime
		"text/unicode",				// kUnicodeMime
		"text/x-moz-text-internal",	// kMozTextInternal
		"text/html",				// kHTMLMime
		"AOLMAIL",					// kAOLMailMime
		"image/png",				// kPNGImageMime
		"image/jpeg",				// kJPEGImageMime
		"image/jpg",				// kJPGImageMime
		"image/gif",				// kGIFImageMime
		"application/x-moz-file",	// kFileMime
		// Registering "text/x-moz-url" and its variants cause the
		// application to crash.
		//"text/x-moz-url",			// kURLMime
		//"text/x-moz-url-data",		// kURLDataMime
		//"text/x-moz-url-desc",		// kURLDescriptionMime
		//"text/x-moz-url-priv",		// kURLPrivateMime
		"application/x-moz-nativeimage",// kNativeImageMime
		"application/x-moz-nativehtml",	// kNativeHTMLMime
		//"application/x-moz-file-promise-url",	// kFilePromiseURLMime
		//"application/x-moz-file-promise-dest-filename",	// kFilePromiseDestFilename
		//"application/x-moz-file-promise",	// kFilePromiseMime
		//"application/x-moz-file-promise-dir",	// kFilePromiseDirectoryMime

		// /widget/src/xpwidgets/nsClipboardPrivacyHandler.cpp
		"application/x-moz-private-browsing"	// NS_MOZ_DATA_FROM_PRIVATEBROWSING
	];
	for (let i = 0; i < flavors.length; i++) xfer.addDataFlavor(flavors[i]);
	board.getData(xfer, board.kGlobalClipboard);

	let result = {};
	try {
		// Fake a native textbox.
		let proxy = new KixProxy(evt);

		result = proxy.value && context.applyKey(proxy.value, evt);
		if (result && result.value) proxy.value = result.value;

		proxy.commit();
		proxy = null;
	}
	finally {
		delete elt._avim_isBeingHandled;

		// Revert the clipboard to the preexisting contents.
		board.setData(xfer, null, board.kGlobalClipboard);

		// Clear the clipboard.
		//let xfer = Transferable(doc.defaultView);
		//let board = Cc["@mozilla.org/widget/clipboard;1"]
		//	.getService(Ci.nsIClipboard);
		//board.setData(xfer, null, board.kGlobalClipboard);
		//board.emptyClipboard(board.kGlobalClipboard);
	}

	if (result && result.changed) {
		evt.handled = true;
		evt.stopPropagation();
		evt.preventDefault();
	}
	return true;
};

})(this);
<commit_msg>Fixed stuck caret in Google Docs<commit_after>"use strict";

(function (context) {

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

const nsTransferable = CC("@mozilla.org/widget/transferable;1",
							  "nsITransferable");

/**
 * A wrapper around nsITransferable that sets the source in order to respect
 * Private Browsing Mode.
 */
function Transferable(win) {
	let xfer = nsTransferable();
	if ("init" in xfer) {
		if (win instanceof Ci.nsIDOMWindow) {
			win = win.QueryInterface(Ci.nsIInterfaceRequestor)
				.getInterface(Ci.nsIWebNavigation);
		}
		xfer.init(win);
	}
	return xfer;
}

/*
 * Proxy for a Google Kix editor to pose as an ordinary HTML <textarea>.
 *
 * @param evt		{object}	The keyPress event.
 */
function KixProxy(evt) {
	if (evt.keyCode == evt.DOM_VK_BACK_SPACE && !evt.shiftKey) {
		throw "Backspace.";
	}

	let doc = evt.originalTarget.ownerDocument;
	if (!doc || !doc.body) throw "No document body to copy from.";

	let win = doc.defaultView;
	let winUtils = win.QueryInterface(Ci.nsIInterfaceRequestor)
		.getInterface(Ci.nsIDOMWindowUtils);
	if (!winUtils || !("sendKeyEvent" in winUtils &&
					   "sendCompositionEvent" in winUtils &&
					   "sendContentCommandEvent" in winUtils)) {
		// Parts of the API are only available starting in Gecko 1.9 or 2.0.
		throw "Can't issue native events."
	}

	let frame = win.frameElement;
	if (!frame) throw "Not in iframe.";
	let frameDoc = frame.ownerDocument;

	const overlaySelector = ".kix-selection-overlay,.sketchy-text-selection-overlay";
	const presItemType = "http://schema.org/CreativeWork/PresentationObject";
	const drawingItemType = "http://schema.org/CreativeWork/DrawingObject";

	/**
	 * Returns whether text is currently selected in the editor, as indicated by
	 * the presence of a selection rectangle overlay.
	 */
	this.hasSelection = function() {
		return frameDoc.querySelectorAll(overlaySelector).length;
	};

	const isMac = win.navigator.platform == "MacPPC" ||
		win.navigator.platform == "MacIntel";

	const tablePropsSel = "[role='menuitem'][aria-disabled='false'] " +
		"[aria-label^='Table properties']";
	const altTextSel = "[role='menuitem'][aria-disabled='false'] " +
		"[aria-label^='Alt text']";

	/**
	 * Returns whether the caret is currently in a table.
	 *
	 * The caret is in a table if the Table | Table Properties menu item is
	 * enabled.
	 *
	 * @returns {boolean}	True if the caret is in a table; false otherwise.
	 */
	this.isInTable = function() {
		return frameDoc.querySelector(tablePropsSel);
	};

	let itemType = frame.ownerDocument.body.getAttribute("itemtype");

	/**
	 * Returns whether a resizable (i.e., non-text) object is selected.
	 */
	this.isObjectSelected = function () {
		return itemType != drawingItemType && itemType != presItemType &&
			frameDoc.querySelector(altTextSel);
	};

	/**
	 * Generates a key event that selects the previous word or optionally to
	 * to beginning of the line.
	 *
	 * Mozilla observes the following platform-specific bindings for
	 * cmd_selectWordPrevious:
	 * 	/content/xbl/builtin/unix/platformHTMLBindings.xml	VK_LEFT	control,shift
	 * 	/content/xbl/builtin/mac/platformHTMLBindings.xml	VK_LEFT	alt,shift
	 * 	/content/xbl/builtin/emacs/platformHTMLBindings.xml	VK_LEFT	control,shift
	 * 	/content/xbl/builtin/win/platformHTMLBindings.xml	VK_LEFT	control,shift
	 * and for cmd_selectBeginLine:
	 * 	/content/xbl/builtin/unix/platformHTMLBindings.xml	VK_HOME	shift
	 * 	/content/xbl/builtin/mac/platformHTMLBindings.xml	VK_LEFT	accel,shift
	 * 	/content/xbl/builtin/emacs/platformHTMLBindings.xml	VK_HOME	shift
	 * 	/content/xbl/builtin/win/platformHTMLBindings.xml	VK_HOME	shift
	 *
	 * @param toLineStart	{boolean}	True to extend the selection to the
	 * 									start of the line; false otherwise.
	 */
	this.selectPrecedingWord = function(toLineStart) {
//		dump("KixProxy.selectPrecedingWord()\n");								// debug
		let key = (isMac || !toLineStart) ?
			evt.DOM_VK_LEFT : evt.DOM_VK_HOME;
		let modifiers = (isMac || toLineStart) ?
			evt.SHIFT_MASK : (evt.CONTROL_MASK | evt.SHIFT_MASK);
		if (isMac) modifiers |= toLineStart ? evt.META_MASK : evt.ALT_MASK;
		winUtils.sendKeyEvent("keypress", key, 0, modifiers);
	};

	const board = Cc["@mozilla.org/widget/clipboard;1"]
		.getService(Ci.nsIClipboard);

	/**
	 * Returns the contents of the clipboard.
	 */
	this.getClipboardData = function () {
		if (!board.hasDataMatchingFlavors(["text/unicode"], 1,
										  board.kGlobalClipboard)) {
			return false;
		}
		let xfer = Transferable(frameDoc.defaultView);
		// TODO: Use the text/html flavor to retain formatting.
		xfer.addDataFlavor("text/unicode");
		board.getData(xfer, board.kGlobalClipboard);
		return xfer;
	};

	/**
	 * Returns the text contents of the clipboard.
	 */
	this.getClipboardText = function() {
		let xfer = this.getClipboardData();
		if (!xfer) return "";

		// https://developer.mozilla.org/en/Using_the_Clipboard
		let str = new Object(), len = new Object();
		try {
			xfer.getTransferData("text/unicode", str, len);
		}
		catch (exc) {
			// At the beginning of a new line (but not the beginning of the
			// document), the previous line break has been selected.
			return "\n";
		}
		str = str && str.value.QueryInterface(Ci.nsISupportsString);
		// text/unicode is apparently stored as UTF-16.
		str = str && str.data.substring(0, len.value / 2);
		// BOM can occur at the beginning of the document.
		return str != "\ufeff" && str;
	};

	/**
	 * Generates a right-arrow key event that returns the selection to where it
	 * was before KixProxy started modifying it.
	 */
	this.revertSelection = function() {
//		dump("KixProxy.revertSelection()\n");									// debug
		winUtils.sendKeyEvent("keypress", evt.DOM_VK_RIGHT, 0, 0);
	};

	/**
	 * Generates a shift-right-arrow key event that removes the leftmost
	 * character from the selection.
	 */
	this.trimLeftSelection = function() {
		winUtils.sendKeyEvent("keypress", evt.DOM_VK_RIGHT, 0,
							  Event.SHIFT_MASK);
	};

	/**
	 * Copies and retrieves the selected text. Callers are responsible for
	 * reverting the clipboard contents.
	 *
	 * @throws {string}	when there was no selection, or the selection was
	 * 					nothing but spaces, in which case the selection is
	 * 					reverted.
	 */
	this.getSelectedText = function(isInTable) {
		// Clear the clipboard.
		board.emptyClipboard(board.kGlobalClipboard);

		// Copy the word.
		winUtils.sendContentCommandEvent("copy");

		// Retrieve the text from the clipboard.
		let value = this.getClipboardText();
		if (!value) {
			// Objects may not be copied as text, but they may be selected.
			if (this.hasSelection()) this.revertSelection();
			return "";
		}
		// Probably the beginning of a line (or the line has just spaces).
		if (!value.trim()) {
			this.revertSelection();
			return "";
		}
		return value;
	};

	// Abort if there is a selection. The selection rectangle is an overlay
	// element that can be identified by its (platform-specific) class.
	if (this.hasSelection()) throw "Non-empty selection.";

	// Select the previous word.
	let wasInTable = this.isInTable();
//	if (wasInTable) dump("KixProxy -- Caret in table.\n");						// debug
	this.selectPrecedingWord(wasInTable);
	if ((!wasInTable && this.isInTable()) || this.isObjectSelected()) {
		// The selection now lies in the table, so the caret was right after
		// the table.
		this.trimLeftSelection();
		throw "Right after table or resizable object.";
	}
	if (this.hasSelection() > 1) {
//		dump("KixProxy -- More than one line selected.\n");						// debug
		// A horizontal line may have been included in the selection, or the
		// word spans more than one line.
		this.revertSelection();
		// There will only be one word in this selection.
		this.selectPrecedingWord(true);
	}

	// Get the selected text.
	let value = this.getSelectedText();
	if (wasInTable && value) {
		//dump("KixProxy -- Reselecting text in table.\n");					// debug
		// Unselect the text, unless the cell and selection are empty.
		this.revertSelection();
		// Reselect the text, this time just the preceding word.
		this.selectPrecedingWord(false);
		value = this.getSelectedText();
	}
	if (!value) throw "No text.";
	if (!context.lastWordInString(value)) {
		this.revertSelection();
		throw "No word.";
	}
//	dump("KixProxy -- value: <" + value + ">\n");								// debug

	this.value = this.oldValue = value;
	this.selectionStart = this.selectionEnd = this.value.length;

	/**
	 * Updates the Kix editor represented by this proxy to reflect any changes
	 * made to the proxy.
	 *
	 * @returns {boolean}	True if anything was changed; false otherwise.
	 */
	this.commit = function() {
//		dump("KixProxy.commit -- value: <" + this.value + ">; oldValue: <" + this.oldValue + ">\n");	// debug
		if (this.value == this.oldValue) {
			if (this.value) this.revertSelection();
			return false;
		}

		// Paste the updated string into the editor.
		// In Kix 3790525131, which sends events to
		// "docs-texteventtarget-iframe", wrapping the paste operation in a
		// composition prevents the selection from flashing.
		// In Kix 3491395419, "kix-clipboard-iframe" inserts a newline after the
		// composition ends, breaking editing.
		// kix_2014.35-Tue_c handles pastes asynchronously, so insert one
		// character at a time.
		// In kix_2014.50-Tue_e, the caret gets stuck in a weird position if we
		// synthesize composition events.
		//winUtils.sendKeyEvent("keypress", evt.DOM_VK_BACK_SPACE, 0, 0);
		//winUtils.sendCompositionEvent("compositionstart", "", "");
		//try {
			for (let i = 0; i < this.value.length; i++) {
				winUtils.sendKeyEvent("keypress", 0, this.value.charCodeAt(i),
									  0);
			}
		//}
		//finally {
			//winUtils.sendCompositionEvent("compositionend", "", "");
		//}

		return true;
	};
}

context.lazyHandlers.kix = function (evt) {
	let elt = evt.originalTarget;
	let doc = elt.ownerDocument;
	if ("_avim_isBeingHandled" in elt || !("querySelector" in doc)) {
		return false;
	}
	let frame = doc.defaultView.frameElement;
	if (!frame || !("classList" in frame) ||
		!(frame.classList.contains("docs-texteventtarget-iframe") ||
		  frame.classList.contains("kix-clipboard-iframe"))) {
		return false;
	}

	// Prevent reentrancy due to keypress events being sent by commit(). (#85)
	elt._avim_isBeingHandled = true;
//	dump("AVIM.handleKix\n");													// debug

	// Get the existing clipboard data in as many formats as the application
	// would likely recognize. Unfortunately, everything else will be lost.
	// TODO: Implement nsIClipboardDragDropHooks to override the clipboard, to
	// avoid dropping any clipboard data.
	const board = Cc["@mozilla.org/widget/clipboard;1"]
		.getService(Ci.nsIClipboard);
	let xfer = Transferable(doc.defaultView);
	let flavors = [
		// /widget/public/nsITransferable.idl
		"text/plain",				// kTextMime
		"text/unicode",				// kUnicodeMime
		"text/x-moz-text-internal",	// kMozTextInternal
		"text/html",				// kHTMLMime
		"AOLMAIL",					// kAOLMailMime
		"image/png",				// kPNGImageMime
		"image/jpeg",				// kJPEGImageMime
		"image/jpg",				// kJPGImageMime
		"image/gif",				// kGIFImageMime
		"application/x-moz-file",	// kFileMime
		// Registering "text/x-moz-url" and its variants cause the
		// application to crash.
		//"text/x-moz-url",			// kURLMime
		//"text/x-moz-url-data",		// kURLDataMime
		//"text/x-moz-url-desc",		// kURLDescriptionMime
		//"text/x-moz-url-priv",		// kURLPrivateMime
		"application/x-moz-nativeimage",// kNativeImageMime
		"application/x-moz-nativehtml",	// kNativeHTMLMime
		//"application/x-moz-file-promise-url",	// kFilePromiseURLMime
		//"application/x-moz-file-promise-dest-filename",	// kFilePromiseDestFilename
		//"application/x-moz-file-promise",	// kFilePromiseMime
		//"application/x-moz-file-promise-dir",	// kFilePromiseDirectoryMime

		// /widget/src/xpwidgets/nsClipboardPrivacyHandler.cpp
		"application/x-moz-private-browsing"	// NS_MOZ_DATA_FROM_PRIVATEBROWSING
	];
	for (let i = 0; i < flavors.length; i++) xfer.addDataFlavor(flavors[i]);
	board.getData(xfer, board.kGlobalClipboard);

	let result = {};
	try {
		// Fake a native textbox.
		let proxy = new KixProxy(evt);

		result = proxy.value && context.applyKey(proxy.value, evt);
		if (result && result.value) proxy.value = result.value;

		proxy.commit();
		proxy = null;
	}
	finally {
		delete elt._avim_isBeingHandled;

		// Revert the clipboard to the preexisting contents.
		board.setData(xfer, null, board.kGlobalClipboard);

		// Clear the clipboard.
		//let xfer = Transferable(doc.defaultView);
		//let board = Cc["@mozilla.org/widget/clipboard;1"]
		//	.getService(Ci.nsIClipboard);
		//board.setData(xfer, null, board.kGlobalClipboard);
		//board.emptyClipboard(board.kGlobalClipboard);
	}

	if (result && result.changed) {
		evt.handled = true;
		evt.stopPropagation();
		evt.preventDefault();
	}
	return true;
};

})(this);
<|endoftext|>


<commit_before><commit_msg>fb menu<commit_after><|endoftext|>


<commit_before>var cdb = require('cartodb.js');
var CategoryColors = require('./category-colors');
var AutoStyler = cdb.core.Model.extend({
  initialize: function (dataviewModel) {
    this.dataviewModel = dataviewModel;
    this.colors = new CategoryColors();
    this.layer = this.dataviewModel.layer;
  },

  _getLayerHeader: function (symbol) {
    return '#' + this.dataviewModel.layer.get('layer_name').replace(/\s*/g, '') + '[mapnik-geometry-type=' + AutoStyler.MAPNIK_MAPPING[symbol] + ']{';
  }

});

AutoStyler.STYLE_TEMPLATE = {
  polygon: ['{{layername}}',
            '  polygon-fill: {{defaultColor}};',
            '  polygon-opacity: 0.6;  ',
            '  line-color: #FFF;',
            '  line-width: 0.3;',
            '  line-opacity: 0.3;',
            '  {{ramp}}',
            '}'].join('\n'),
  marker: ['{{layername}}',
         '  marker-width: {{markerWidth}};',
         '  marker-fill-opacity: 0.8;  ',
         '  marker-fill: {{defaultColor}};  ',
         '  marker-line-color: #fff;',
         '  marker-allow-overlap: true;',
         '  marker-line-width: 0.3;',
         '  marker-line-opacity: 0.8;',
         '  {{ramp}}',
         '}'].join('\n'),
  line: ['{{layername}}',
          '  line-color: {{defaultColor}};',
          '  line-width: 0.3;',
          '  line-opacity: 0.3;',
          '  {{ramp}}',
          '}'].join('\n')
};

AutoStyler.MAPNIK_MAPPING = {
  polygon: 'polygon',
  marker: 'point',
  line: 'linestring'
};

module.exports = AutoStyler;
<commit_msg>uses geometry type indices instead of names<commit_after>var cdb = require('cartodb.js');
var CategoryColors = require('./category-colors');
var AutoStyler = cdb.core.Model.extend({
  initialize: function (dataviewModel) {
    this.dataviewModel = dataviewModel;
    this.colors = new CategoryColors();
    this.layer = this.dataviewModel.layer;
  },

  _getLayerHeader: function (symbol) {
    return '#' + this.dataviewModel.layer.get('layer_name').replace(/\s*/g, '') + '[mapnik-geometry-type=' + AutoStyler.MAPNIK_MAPPING[symbol] + ']{';
  }

});

AutoStyler.STYLE_TEMPLATE = {
  polygon: ['{{layername}}',
            '  polygon-fill: {{defaultColor}};',
            '  polygon-opacity: 0.6;  ',
            '  line-color: #FFF;',
            '  line-width: 0.3;',
            '  line-opacity: 0.3;',
            '  {{ramp}}',
            '}'].join('\n'),
  marker: ['{{layername}}',
         '  marker-width: {{markerWidth}};',
         '  marker-fill-opacity: 0.8;  ',
         '  marker-fill: {{defaultColor}};  ',
         '  marker-line-color: #fff;',
         '  marker-allow-overlap: true;',
         '  marker-line-width: 0.3;',
         '  marker-line-opacity: 0.8;',
         '  {{ramp}}',
         '}'].join('\n'),
  line: ['{{layername}}',
          '  line-color: {{defaultColor}};',
          '  line-width: 0.3;',
          '  line-opacity: 0.3;',
          '  {{ramp}}',
          '}'].join('\n')
};

AutoStyler.MAPNIK_MAPPING = {
  polygon: 3,
  marker: 1,
  line: 2
};

module.exports = AutoStyler;
<|endoftext|>


<commit_before>#!/bin/env node
//  OpenShift sample Node application
var express = require('express');
var fs      = require('fs');
var url     = require('url');
var http    = require('http');
var im      = require('imagemagick');

var ip_address = process.env.OPENSHIFT_NODEJS_IP;
var port       = process.env.OPENSHIFT_NODEJS_PORT || 8080;

var app = express();
var server = http.createServer(app);

app.configure(function(){
    app.use(express.bodyParser());
    app.use(app.router);
});

app.get('/test', function(req, res){
    im.convert(['images/7lRgXhS3Alc.png', '-resize', '25x120', 'kittens-small.jpg'],function(err, stdout){
        if (err) throw err;
        console.log('stdout:', stdout);
    });
    console.log(req.body);
    console.log(req.params);
    console.log(req.query);
    res.send('Hello World');
});

server.listen(port, ip_address);
<commit_msg>trying imgmagic<commit_after>#!/bin/env node
//  OpenShift sample Node application
var express = require('express');
var fs      = require('fs');
var url     = require('url');
var http    = require('http');
var im      = require('imagemagick');

var ip_address = process.env.OPENSHIFT_NODEJS_IP;
var port       = process.env.OPENSHIFT_NODEJS_PORT || 8080;

var app = express();
var server = http.createServer(app);

app.configure(function(){
    app.use(express.bodyParser());
    app.use(app.router);
});

app.get('/test', function(req, res){
    var img = (appRoot + '/images/7lRgXhS3Alc.png');
    console.log(img);
    im.convert(['images/7lRgXhS3Alc.png', '-resize', '25x120', 'kittens-small.jpg'],function(err, stdout){
        if (err) throw err;
        console.log('stdout:', stdout);
    });
    console.log(req.body);
    console.log(req.params);
    console.log(req.query);
    res.send('Hello World');
});

server.listen(port, ip_address);
<|endoftext|>


<commit_before>var util = require('../util.test');

module.exports = function() {
  util.request('http://test.local.whistlejs.com/index.html?doNotParseJson', function(res, body) {
    body.should.equal('uiServer');
  });

  util.request('http://plugin.whistlejs.com:1234/index.html', function(res, data) {
    data.should.have.property('type', 'server');
  });

  util.request('wss://321.whistlejs.com/index.html', function(data) {
    data.ruleValue.should.equal('abc');
  });

  util.request('wss://321.ws1.whistlejs.com:2222/index.html', function(data) {
    data.host.should.equal('127.0.0.1');
    data.port.should.equal('9999');
  });
};
<commit_msg>test: websocket<commit_after>var util = require('../util.test');

module.exports = function() {
  util.request('http://test.local.whistlejs.com/index.html?doNotParseJson', function(res, body) {
    body.should.equal('uiServer');
  });

  util.request('http://plugin.whistlejs.com:1234/index.html', function(res, data) {
    data.should.have.property('type', 'server');
  });

  util.request('wss://321.whistlejs.com/index.html', function(data) {
    data.ruleValue.should.equal('abc');
  });

  util.request('wss://321.ws1.whistlejs.com:2222/index.html', function(data) {
    data.host.should.equal('127.0.0.1:9999');
  });
};
<|endoftext|>


<commit_before>/**
 * Ventolone.charts Module
 *
 *
 */
angular.module('Ventolone.charts', ['ngGoogleCharts'])
  .factory('TimeChartsData', function($q, chartReady) {
    return function(data, tooltipTmpl) {
      return $q.all({
        chartReady: chartReady,
        data: data
      }).then(function(ready) {
        var dt = new google.visualization.DataTable()
        dtBattery = new google.visualization.DataTable()

        dt.addColumn('date', 'Date')
        dt.addColumn('number', 'Speed (m/s)')
        dt.addColumn({
          type: 'string',
          role: 'tooltip',
          p: {
            html: true
          }
        })

        dtBattery.addColumn('date', 'Date')
        dtBattery.addColumn('number', 'Battery %')
        dtBattery.addColumn({
          type: 'string',
          role: 'tooltip',
          p: {
            html: true
          }
        })

        angular.forEach(ready.data, function(value, key) {
          var date = new Date(value.key[value.key.length - 1])

          dt.addRow([
            date,
            value.value.speed,
            tooltipTmpl({
              date: date,
              label: 'Speed (m/s)',
              value: value.value.speed
            })
          ])
          dtBattery.addRow([
            date,
            value.value.battery * 100,
            tooltipTmpl({
              date: date,
              label: 'Battery %',
              value: value.value.battery * 100
            })
          ])
        });

        return {
          speed: dt,
          battery: dtBattery
        }
      })
    }
  })
  .factory('FrequencyChartsData', function($q, chartReady, byValue) {
    return function(data, tooltipTmpl, group_level, total) {
      return $q.all({
        chartReady: chartReady,
        data: data
      }).then(function(ready) {
        var dt = new google.visualization.DataTable()

        dt.addColumn('number', 'Speed (m/s)')
        dt.addColumn('number', '%')

        var d = {}

        angular.forEach(data, function(value, key) {
          d[value.key[group_level - 1]] = (d[value.key[group_level - 1]] || 0) + value.value
        });

        angular.forEach(Object.keys(d).map(parseFloat).sort(byValue), function(key) {
          dt.addRow([parseFloat(key), parseInt(d[key]) / total * 100])
        });
        return dt
      })
    }
  })
  .factory('StatisticsChart', function(chartReady, $q, $filter){
    return function (statistics,anemometer){
      return $q.all([statistics, chartReady]).then(function (statistics) {
        var stats = statistics[0]

        var airDensity = 1.225 * Math.pow(1 - 0.000026 * anemometer.altitudine, 4.256)
        stats.maxPowerExtractable  = 0.593 * 0.5 * airDensity * (stats.speed.sum / stats.count)

        return {
          battery: google.visualization.arrayToDataTable([
            ['Label', 'Value'],
            ['Battery', parseInt((stats.battery.sum / stats.count)*100)]
          ]),
          speed: google.visualization.arrayToDataTable([
            ['Label', 'Value'],
            ['Speed', parseInt((stats.speed.sum / stats.count) * 100)/100]
          ]),
          maxPowerExtractable: google.visualization.arrayToDataTable([
            ['Label', 'Value'],
            ['Potenziale', parseInt((stats.maxPowerExtractable) * 100)/100]
          ]),
        }
      })
    }
  })
  .constant('byValue', function byValue(a, b) {
    return a - b
  })
  .constant('timeFilter', function timeFilter(dataFrequency, date) {
    if (date) {
      var d = new Date(date),
        filter = [new Date(d.getUTCFullYear(), d.getMonth(), 1)]

      for (var i = 1; i < dataFrequency - 1; i++) {
        filter.push(new Date(date))
      }
      return filter
    }
    return []
  })
  .constant('frequencyTimeFilter', function frequencyTimeFilter(dataFrequency, date, val) {
    if (date) {
      var d = new Date(date),
        filter = [new Date(d.getUTCFullYear(), d.getMonth(), 1), val]

      for (var i = 1; i < dataFrequency - 1; i++) {
        filter.push(new Date(date))
        filter.push(val)
      }
      return filter
    }
    return []
  })
<commit_msg>corrected cubic sum<commit_after>/**
 * Ventolone.charts Module
 *
 *
 */
angular.module('Ventolone.charts', ['ngGoogleCharts'])
  .factory('TimeChartsData', function($q, chartReady) {
    return function(data, tooltipTmpl) {
      return $q.all({
        chartReady: chartReady,
        data: data
      }).then(function(ready) {
        var dt = new google.visualization.DataTable()
        dtBattery = new google.visualization.DataTable()

        dt.addColumn('date', 'Date')
        dt.addColumn('number', 'Speed (m/s)')
        dt.addColumn({
          type: 'string',
          role: 'tooltip',
          p: {
            html: true
          }
        })

        dtBattery.addColumn('date', 'Date')
        dtBattery.addColumn('number', 'Battery %')
        dtBattery.addColumn({
          type: 'string',
          role: 'tooltip',
          p: {
            html: true
          }
        })

        angular.forEach(ready.data, function(value, key) {
          var date = new Date(value.key[value.key.length - 1])

          dt.addRow([
            date,
            value.value.speed,
            tooltipTmpl({
              date: date,
              label: 'Speed (m/s)',
              value: value.value.speed
            })
          ])
          dtBattery.addRow([
            date,
            value.value.battery * 100,
            tooltipTmpl({
              date: date,
              label: 'Battery %',
              value: value.value.battery * 100
            })
          ])
        });

        return {
          speed: dt,
          battery: dtBattery
        }
      })
    }
  })
  .factory('FrequencyChartsData', function($q, chartReady, byValue) {
    return function(data, tooltipTmpl, group_level, total) {
      return $q.all({
        chartReady: chartReady,
        data: data
      }).then(function(ready) {
        var dt = new google.visualization.DataTable()

        dt.addColumn('number', 'Speed (m/s)')
        dt.addColumn('number', '%')

        var d = {}

        angular.forEach(data, function(value, key) {
          d[value.key[group_level - 1]] = (d[value.key[group_level - 1]] || 0) + value.value
        });

        angular.forEach(Object.keys(d).map(parseFloat).sort(byValue), function(key) {
          dt.addRow([parseFloat(key), parseInt(d[key]) / total * 100])
        });
        return dt
      })
    }
  })
  .factory('StatisticsChart', function(chartReady, $q, $filter){
    return function (statistics,anemometer){
      return $q.all([statistics, chartReady]).then(function (statistics) {
        var stats = statistics[0]

        var airDensity = 1.225 * Math.pow(1 - 0.000026 * anemometer.altitudine, 4.256)
        stats.maxPowerExtractable  = 0.593 * 0.5 * airDensity * Math.pow(stats.speed.cubicSum / stats.count, 1/3)

        return {
          battery: google.visualization.arrayToDataTable([
            ['Label', 'Value'],
            ['Battery', parseInt((stats.battery.sum / stats.count)*100)]
          ]),
          speed: google.visualization.arrayToDataTable([
            ['Label', 'Value'],
            ['Speed', parseInt((stats.speed.sum / stats.count) * 100)/100]
          ]),
          maxPowerExtractable: google.visualization.arrayToDataTable([
            ['Label', 'Value'],
            ['Potenziale', parseInt((stats.maxPowerExtractable) * 100)/100]
          ]),
        }
      })
    }
  })
  .constant('byValue', function byValue(a, b) {
    return a - b
  })
  .constant('timeFilter', function timeFilter(dataFrequency, date) {
    if (date) {
      var d = new Date(date),
        filter = [new Date(d.getUTCFullYear(), d.getMonth(), 1)]

      for (var i = 1; i < dataFrequency - 1; i++) {
        filter.push(new Date(date))
      }
      return filter
    }
    return []
  })
  .constant('frequencyTimeFilter', function frequencyTimeFilter(dataFrequency, date, val) {
    if (date) {
      var d = new Date(date),
        filter = [new Date(d.getUTCFullYear(), d.getMonth(), 1), val]

      for (var i = 1; i < dataFrequency - 1; i++) {
        filter.push(new Date(date))
        filter.push(val)
      }
      return filter
    }
    return []
  })
<|endoftext|>


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

/**
 * @fileoverview Basic externs for the Web Animations API. This is not
 * intended to be exhaustive.
 * @externs
 */

/**
 * @param {!Array<!Object>} frames
 * @param {(number|AnimationEffectTimingProperties)=} opt_options
 * @return {!Animation}
 */
Element.prototype.animate = function(frames, opt_options) {};

/**
 * @interface
 * @extends {EventTarget}
 */
var Animation = function() {};

/**
 * @return {undefined}
 */
Animation.prototype.cancel = function() {};

/** @type {AnimationEffectReadOnly|undefined} */
Animation.prototype.effect;

/** @type {number} */
Animation.prototype.currentTime;

/** @type {string} */
Animation.prototype.playState;

/**
 * @typedef {{
 *   delay: (number|undefined),
 *   endDelay: (number|undefined),
 *   fillMode: (string|undefined),
 *   iterationStart: (number|undefined),
 *   iterations: (number|undefined),
 *   duration: (number|string|undefined),
 *   direction: (string|undefined),
 *   easing: (string|undefined)
 * }}
 */
var AnimationEffectTimingProperties;

/**
 * @interface
 */
var AnimationEffectTiming = function() {};

/** @type {number} */
AnimationEffectTiming.prototype.delay;

/** @type {number} */
AnimationEffectTiming.prototype.endDelay;

/** @type {string} */
AnimationEffectTiming.prototype.fillMode;

/** @type {number} */
AnimationEffectTiming.prototype.iterationStart;

/** @type {number} */
AnimationEffectTiming.prototype.iterations;

/** @type {number|string} */
AnimationEffectTiming.prototype.duration;

/** @type {string} */
AnimationEffectTiming.prototype.direction;

/** @type {string} */
AnimationEffectTiming.prototype.easing;
<commit_msg>added playbackRate<commit_after>/*
 * Copyright 2015 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

/**
 * @fileoverview Basic externs for the Web Animations API. This is not
 * intended to be exhaustive.
 * @externs
 */

/**
 * @param {!Array<!Object>} frames
 * @param {(number|AnimationEffectTimingProperties)=} opt_options
 * @return {!Animation}
 */
Element.prototype.animate = function(frames, opt_options) {};

/**
 * @interface
 * @extends {EventTarget}
 */
var Animation = function() {};

/**
 * @return {undefined}
 */
Animation.prototype.cancel = function() {};

/** @type {AnimationEffectReadOnly|undefined} */
Animation.prototype.effect;

/** @type {number} */
Animation.prototype.currentTime;

/** @type {number} */
Animation.prototype.playbackRate;

/** @type {string} */
Animation.prototype.playState;

/**
 * @typedef {{
 *   delay: (number|undefined),
 *   endDelay: (number|undefined),
 *   fillMode: (string|undefined),
 *   iterationStart: (number|undefined),
 *   iterations: (number|undefined),
 *   duration: (number|string|undefined),
 *   direction: (string|undefined),
 *   easing: (string|undefined)
 * }}
 */
var AnimationEffectTimingProperties;

/**
 * @interface
 */
var AnimationEffectTiming = function() {};

/** @type {number} */
AnimationEffectTiming.prototype.delay;

/** @type {number} */
AnimationEffectTiming.prototype.endDelay;

/** @type {string} */
AnimationEffectTiming.prototype.fillMode;

/** @type {number} */
AnimationEffectTiming.prototype.iterationStart;

/** @type {number} */
AnimationEffectTiming.prototype.iterations;

/** @type {number|string} */
AnimationEffectTiming.prototype.duration;

/** @type {string} */
AnimationEffectTiming.prototype.direction;

/** @type {string} */
AnimationEffectTiming.prototype.easing;
<|endoftext|>


<commit_before>import * as Fields from '../bookmark/fields';

export default class FormCtrl {
  constructor (BookmarksService, SelectService, events) {
    this.service = BookmarksService;
    this.select = SelectService;

    events.$on(SelectService.selectedSubject, (ev, selected) => {
      this.selected = selected;
      this.bookmark = (selected === undefined) ? {} : selected.fields.toObject();
    });
  }

  submit (form) {
    if (!form.$valid) {
      return;
    }

    let result;
    let fields = Fields.fromObject(this.bookmark);
    if (this.selected) {
      result = this.service.update(this.selected.id, fields);
    } else {
      result = this.service.create(fields);
    }

    result.then(() => this.cancel(form));
  }

  cancel (form) {
    this.select.deselect();
    this.bookmark = {};
    form.$setPristine();
  }

}
<commit_msg>Rename instance variables in form controller<commit_after>import * as Fields from '../bookmark/fields';

export default class FormCtrl {
  constructor (bookmarksService, selectService, events) {
    this.bookmarkService = bookmarksService;
    this.selectService = selectService;

    events.$on(selectService.selectedSubject, (ev, selected) => {
      this.selected = selected;
      this.bookmark = (selected === undefined) ? {} : selected.fields.toObject();
    });
  }

  submit (form) {
    if (!form.$valid) {
      return;
    }

    let result;
    let fields = Fields.fromObject(this.bookmark);
    if (this.selected) {
      result = this.bookmarkService.update(this.selected.id, fields);
    } else {
      result = this.bookmarkService.create(fields);
    }

    result.then(() => this.cancel(form));
  }

  cancel (form) {
    this.selectService.deselect();
    this.bookmark = {};
    form.$setPristine();
  }

}
<|endoftext|>


<commit_before>var t0  = new Image();  t0.src  = "0.png";
var t1  = new Image();  t1.src  = "2.png";
var t2  = new Image();  t2.src  = "4.png";
var t3  = new Image();  t3.src  = "8.png";
var t4  = new Image();  t4.src  = "16.png";
var t5  = new Image();  t5.src  = "32.png";
var t6  = new Image();  t6.src  = "64.png";
var t7  = new Image();  t7.src  = "128.png";
var t8  = new Image();  t8.src  = "256.png";
var t9  = new Image();  t9.src  = "512.png";
var t10 = new Image();  t10.src = "1024.png";
var t11 = new Image();  t11.src = "2048.png";

document.addEventListener('keydown', function(event) {
	if(event.keyCode == 37) {
		moveLeft();
	}
	else if(event.keyCode == 38) {
		moveUp();
	}
	else if(event.keyCode == 39) {
		moveRight();
	}
	else if(event.keyCode == 40) {
		moveDown();
	}

});

function draw() {
	if (changed = true) {
		var canvas = document.getElementById("window");
		var ctx = canvas.getContext('2d');

		ctx.fillStyle = "rgb(150,150,150)";
		ctx.fillRect(0,0,400,400);

		changed = false;

		var xpos = 5;
		var ypos = 5;
		for (i=0; i<4; i++) {
			for (x=0; x<4; x++) {
				ctx.drawImage(grid[4 * i + x], xpos, ypos);
				xpos += 100;
			}
			xpos = 5;
			ypos += 100;
		}
	}
}

var score = 0;
var over = false;
var TILES = [t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11];
var grid = [TILES[0], TILES[0], TILES[0], TILES[0],
			TILES[0], TILES[0], TILES[0], TILES[0],
			TILES[0], TILES[0], TILES[0], TILES[0],
			TILES[0], TILES[0], TILES[0], TILES[0] ];
function moveUp() {
	move = -4;
	edge = [0, 1, 2, 3];
	for (i = 0; i < 16; i++) {
		moveTile(i, move, edge);
	}
	for (i = 0; i < 16; i++) {
		combine(i, move, edge);
	}
	for (i = 0; i < 16; i++) {
		moveTile(i, move, edge);
	}
	newTile();
	draw();

}
function moveLeft() {
	move = -1;
	edge = [0, 4, 8, 12];
	for (i = 0; i < 16; i++) {
		moveTile(i, move, edge);
	}
	for (i = 0; i < 16; i++) {
		combine(i, move, edge);
	}
	for (i = 0; i < 16; i++) {
		moveTile(i, move, edge);
	}
	newTile();
	draw();
}
function moveDown() {
	move = 4;
	edge = [12, 13, 14, 15];
	for (i = 15; i >= 0; i--) {
		moveTile(i, move, edge);
	}
	for (i = 15; i >= 0; i--) {
		combine(i, move, edge);
	}
	for (i = 15; i >= 0; i--) {
		moveTile(i, move, edge);
	}
	newTile();
	draw();
}
function moveRight() {
	move = 1;
	edge = [3, 7, 11, 15];
	for (i = 15; i >= 0; i--) {
		moveTile(i, move, edge);
	}
	for (i = 15; i >= 0; i--) {
		combine(i, move, edge);
	}
	for (i = 15; i >= 0; i--) {
		moveTile(i, move, edge);
	}
	newTile();
	draw();
}
function newTile() {
	var whichTile = Math.random();
	if (whichTile > .9) {
		var n = TILES[2];
	}
	else {
		var n = TILES[1];
	}
	var empty = [];
	for (i = 0; i <= 16; i++) {
		if (grid[i] == TILES[0]) {
			empty.push(i);
		}
	}
	if (empty == []) {
		return 0;
	}
	var newPos = Math.round(Math.random() * empty.length);
	grid[empty[newPos]] = n;
}
function combine(i, move, edge) {
	if (grid[i] != TILES[0] && i != edge[0] && i != edge[1] && i != edge[2] && i != edge[3]) {
		if (grid[i + move] == grid[i]) {
			for (x = 0; x < 11; x++) {
				if (grid[i] == TILES[x]) {
					grid[i + move] = TILES[x + 1];
					grid[i] = TILES[0];
					score += Math.pow(2, x+1);
					changed = true;
					if (x + 1 >= 11) {
						console.log("You Win!");
					}
				}
			}
		}
	}
}
function moveTile(i, move, edge) {
	if (grid[i] != TILES[0] && i != edge[0] && i != edge[1] && i != edge[2] && i != edge[3]) {
		if (grid[i + move] == TILES[0]) {
			grid[i + move] = grid[i];
			grid[i] = TILES[0];
			moveTile(i + move, move, edge);
			changed = true;
		}
	}
}

newTile();
newTile();

<commit_msg>doesn't allow moves where nothing happens<commit_after>var score = 0;

var t0  = new Image();  t0.src  = "0.png";
var t1  = new Image();  t1.src  = "2.png";
var t2  = new Image();  t2.src  = "4.png";
var t3  = new Image();  t3.src  = "8.png";
var t4  = new Image();  t4.src  = "16.png";
var t5  = new Image();  t5.src  = "32.png";
var t6  = new Image();  t6.src  = "64.png";
var t7  = new Image();  t7.src  = "128.png";
var t8  = new Image();  t8.src  = "256.png";
var t9  = new Image();  t9.src  = "512.png";
var t10 = new Image();  t10.src = "1024.png";
var t11 = new Image();  t11.src = "2048.png";

document.addEventListener('keydown', function(event) {
	if(event.keyCode == 37) {
		moveLeft();
	}
	else if(event.keyCode == 38) {
		moveUp();
	}
	else if(event.keyCode == 39) {
		moveRight();
	}
	else if(event.keyCode == 40) {
		moveDown();
	}
	document.getElementById("score").innerHTML = "Score: "+score;
});

function draw() {
	var canvas = document.getElementById("window");
	var ctx = canvas.getContext('2d');

	ctx.fillStyle = "rgb(150,150,150)";
	ctx.fillRect(0,0,400,400);

	var xpos = 5;
	var ypos = 5;
	for (i=0; i<4; i++) {
		for (x=0; x<4; x++) {
			ctx.drawImage(grid[4 * i + x], xpos, ypos);
			xpos += 100;
		}
		xpos = 5;
		ypos += 100;
	}
}

var over = false;
var TILES = [t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11];
var grid = [TILES[0], TILES[0], TILES[0], TILES[0],
			TILES[0], TILES[0], TILES[0], TILES[0],
			TILES[0], TILES[0], TILES[0], TILES[0],
			TILES[0], TILES[0], TILES[0], TILES[0] ];
function moveUp() {
	move = -4;
	edge = [0, 1, 2, 3];
	for (i = 0; i < 16; i++) {
		moveTile(i, move, edge);
	}
	for (i = 0; i < 16; i++) {
		combine(i, move, edge);
	}
	for (i = 0; i < 16; i++) {
		moveTile(i, move, edge);
	}
	if (changed == true) {
		newTile();
		draw();
		changed = false;
	}
}
function moveLeft() {
	move = -1;
	edge = [0, 4, 8, 12];
	for (i = 0; i < 16; i++) {
		moveTile(i, move, edge);
	}
	for (i = 0; i < 16; i++) {
		combine(i, move, edge);
	}
	for (i = 0; i < 16; i++) {
		moveTile(i, move, edge);
	}
	if (changed == true) {
		newTile();
		draw();
		changed = false;
	}
}
function moveDown() {
	move = 4;
	edge = [12, 13, 14, 15];
	for (i = 15; i >= 0; i--) {
		moveTile(i, move, edge);
	}
	for (i = 15; i >= 0; i--) {
		combine(i, move, edge);
	}
	for (i = 15; i >= 0; i--) {
		moveTile(i, move, edge);
	}
	if (changed == true) {
		newTile();
		draw();
		changed = false;
	}
}
function moveRight() {
	move = 1;
	edge = [3, 7, 11, 15];
	for (i = 15; i >= 0; i--) {
		moveTile(i, move, edge);
	}
	for (i = 15; i >= 0; i--) {
		combine(i, move, edge);
	}
	for (i = 15; i >= 0; i--) {
		moveTile(i, move, edge);
	}
	if (changed == true) {
		newTile();
		draw();
		changed = false;
	}
}
function newTile() {
	var whichTile = Math.random();
	if (whichTile > .9) {
		var n = TILES[2];
	}
	else {
		var n = TILES[1];
	}
	var empty = [];
	for (i = 0; i <= 16; i++) {
		if (grid[i] == TILES[0]) {
			empty.push(i);
		}
	}
	if (empty == []) {
		return 0;
	}
	var newPos = Math.round(Math.random() * empty.length);
	grid[empty[newPos]] = n;
}
function combine(i, move, edge) {
	if (grid[i] != TILES[0] && i != edge[0] && i != edge[1] && i != edge[2] && i != edge[3]) {
		if (grid[i + move] == grid[i]) {
			for (x = 0; x < 11; x++) {
				if (grid[i] == TILES[x]) {
					grid[i + move] = TILES[x + 1];
					grid[i] = TILES[0];
					score += Math.pow(2, x+1);
					changed = true;
					if (x + 1 >= 11) {
						console.log("You Win!");
					}
				}
			}
		}
	}
}
function moveTile(i, move, edge) {
	if (grid[i] != TILES[0] && i != edge[0] && i != edge[1] && i != edge[2] && i != edge[3]) {
		if (grid[i + move] == TILES[0]) {
			grid[i + move] = grid[i];
			grid[i] = TILES[0];
			moveTile(i + move, move, edge);
			changed = true;
		}
	}
}

newTile();
newTile();

<|endoftext|>


<commit_before>'use strict';

var querystring = require('querystring');
var config = require('../config');

/**
 * Get a response that bootstraps the clientside rendering of search results
 */
exports.clientSideResult = function(req, res) {
  res.render('search', {
    req,
    isSearching: true,
    filters: {
      q: req.params.q || ''
    },
    result: {
      isSearch: true
    }
  });
};

exports.redirect = function(req, res, next) {
  var doRedirect = false;

  // Replace a path param on catalog, with a query param
  if(req.params.catalog && req.params.catalog !== config.search.path) {
    req.query.catalog = req.params.catalog;
    delete req.params.catalog;
    doRedirect = true;
  }
  // If the query parameter 'q' is set and the user is requesting the frontpage
  if((req.query.q || req.query.q === '') && req.path === '/') {
    doRedirect = true;
  }
  // Redirect to the new search page.
  if(doRedirect) {
    var qs = querystring.stringify(req.query);
    res.redirect('/' + config.search.path + '?' + qs);
  } else {
    next();
  }
};

// Retrieve the main menu async & render server side
exports.mainmenu = function(req, res) {
  // Grab categories, i.e. second level in the menu
  var categories = req.app.get('categories');

  // Grab the catalogs, i.e. first level in the menu
  var catalogs = req.app.get('catalogs');
  var catalogsToRender = [];

  catalogs = catalogs.sort(function(x, y) {
    return x.name.localeCompare(y.name);
  });

  for (var c in catalogs) {
    var catalog = catalogs[c];
    if (catalog.alias === undefined) {
      continue;
    }
    // If fetching the catalogs categories failed.
    if (!categories[catalog.alias] || !categories[catalog.alias].tree) {
      continue;
    }

    // The count of assets in a catalog is the sum of assets in it's categories.
    var count = categories[catalog.alias].tree.children.reduce(function(r, c) {
      return r + c.count;
    }, 0);

    catalogsToRender.push({
      name: catalog.name,
      alias: catalog.alias,
      categoryRoot: categories[catalog.alias].tree,
      count: count
    });
  }
  // res.json(results);
  res.render('main-menu', {
    catalogs: catalogsToRender
  });
};
<commit_msg>Let's not show catalogs if they are not loaded<commit_after>'use strict';

var querystring = require('querystring');
var config = require('../config');

/**
 * Get a response that bootstraps the clientside rendering of search results
 */
exports.clientSideResult = function(req, res) {
  res.render('search', {
    req,
    isSearching: true,
    filters: {
      q: req.params.q || ''
    },
    result: {
      isSearch: true
    }
  });
};

exports.redirect = function(req, res, next) {
  var doRedirect = false;

  // Replace a path param on catalog, with a query param
  if(req.params.catalog && req.params.catalog !== config.search.path) {
    req.query.catalog = req.params.catalog;
    delete req.params.catalog;
    doRedirect = true;
  }
  // If the query parameter 'q' is set and the user is requesting the frontpage
  if((req.query.q || req.query.q === '') && req.path === '/') {
    doRedirect = true;
  }
  // Redirect to the new search page.
  if(doRedirect) {
    var qs = querystring.stringify(req.query);
    res.redirect('/' + config.search.path + '?' + qs);
  } else {
    next();
  }
};

// Retrieve the main menu async & render server side
exports.mainmenu = function(req, res) {
  // Grab categories, i.e. second level in the menu
  var categories = req.app.get('categories');

  // Grab the catalogs, i.e. first level in the menu
  var catalogs = req.app.get('catalogs');
  var catalogsToRender = [];

  if(catalogs) {
    catalogs = catalogs.sort(function(x, y) {
      return x.name.localeCompare(y.name);
    });

    for (var c in catalogs) {
      var catalog = catalogs[c];
      if (catalog.alias === undefined) {
        continue;
      }
      // If fetching the catalogs categories failed.
      if (!categories[catalog.alias] || !categories[catalog.alias].tree) {
        continue;
      }

      // The count of assets in a catalog is the sum of assets in it's categories.
      var count = categories[catalog.alias].tree.children.reduce(function(r, c) {
        return r + c.count;
      }, 0);

      catalogsToRender.push({
        name: catalog.name,
        alias: catalog.alias,
        categoryRoot: categories[catalog.alias].tree,
        count: count
      });
    }
  }
  // res.json(results);
  res.render('main-menu', {
    catalogs: catalogsToRender
  });
};
<|endoftext|>


<commit_before>// @flow
import React, { Component } from 'react'
import { observer } from 'mobx-react'
import { Link } from 'react-router-dom'
// import ReactList from 'react-list';

import { PostStore } from '../../store'

import SearchBar from './components/SearchBar'

/**
 * @export
 * @class List
 * @extends {Component}
 */
@observer
export default class List extends Component {
  props: {
    postStore: PostStore
  };
  state = {
    keyword: ''
  };
  componentDidMount () {
    this.props.postStore.fetchList()
  }
  handleKeywordChange = (keyword: string) => {
    this.setState({ keyword })
  };
  /* renderPost = (index: number, key: number) => {
    const post = this.props.postStore.posts.filter(post =>
      post.title.match(this.state.keyword)
    )[index];
    return (

        <Link to={`post/${post.sha}`}>{post.title}</Link>

    );
  }; */
  render () {
    const posts = this.props.postStore.posts.filter(post =>
      post.title
        .toLowerCase()
        .replace(' ', '')
        .match(this.state.keyword.toLowerCase().replace(' ', ''))
    )
    return (

        <SearchBar onKeywordChange={this.handleKeywordChange} />

          {/* <ReactList
            pageSize={5}
            itemRenderer={this.renderPost}
            length={
              posts.filter(post =>
                post.title.toLowerCase().match(this.state.keyword.toLowerCase())
              ).length
            }
          /> */}
          {posts.map(post => (

              <Link to={`post/${post.sha}`}>{post.title}</Link>

          ))}

    )
  }
}
<commit_msg>add loading screen to post<commit_after>// @flow
import React, { Component } from 'react'
import { observer } from 'mobx-react'
import { Link } from 'react-router-dom'
// import ReactList from 'react-list';

import { PostStore } from '../../store'

import SearchBar from './components/SearchBar'

/**
 * @export
 * @class List
 * @extends {Component}
 */
@observer
export default class List extends Component {
  props: {
    postStore: PostStore
  };
  state = {
    keyword: ''
  };
  componentDidMount () {
    this.props.postStore.fetchList()
  }
  handleKeywordChange = (keyword: string) => {
    this.setState({ keyword })
  };
  render () {
    const posts = this.props.postStore.posts.filter(post =>
      post.title
        .toLowerCase()
        .replace(' ', '')
        .match(this.state.keyword.toLowerCase().replace(' ', ''))
    )
    return (

        <SearchBar onKeywordChange={this.handleKeywordChange} />

          {posts
            ? posts.map(post => (

                  <Link to={`post/${post.sha}`}>
                    {post.title}
                  </Link>

                  {/* {post.date} */}

              ))
            :

Loading...

}

    )
  }
}
<|endoftext|>


<commit_before>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var App = require('app');

module.exports = Em.Route.extend({
  route: '/highAvailability/enable',

  enter: function (router) {
    Em.run.next(function () {
      var highAvailabilityWizardController = router.get('highAvailabilityWizardController');
      App.router.get('updateController').set('isWorking', false);
      var popup = App.ModalPopup.show({
        classNames: ['full-width-modal'],
        header: Em.I18n.t('admin.highAvailability.wizard.header'),
        bodyClass: App.HighAvailabilityWizardView.extend({
          controller: highAvailabilityWizardController
        }),
        primary: Em.I18n.t('form.cancel'),
        showFooter: false,
        secondary: null,
        hideCloseButton: function () {
          var currStep = App.router.get('highAvailabilityWizardController.currentStep');
          switch (currStep) {
            case "5" :
            case "7" :
            case "9" :
              if(App.supports.autoRollbackHA){
                this.set('showCloseButton', false);
              }else{
                this.set('showCloseButton', true);
              }
              break;
            default :
              this.set('showCloseButton', true);
          }
        }.observes('App.router.highAvailabilityWizardController.currentStep'),

        onClose: function () {
          var currStep = App.router.get('highAvailabilityWizardController.currentStep');
          var highAvailabilityProgressPageController = App.router.get('highAvailabilityProgressPageController');
          if (currStep == "6" && App.supports.autoRollbackHA){
            highAvailabilityProgressPageController.tasks.push({
              command: "startZooKeeperServers",
              status: "FAILED"
            })
            highAvailabilityProgressPageController.rollback();
          }else if(currStep == "8" && App.supports.autoRollbackHA){
            highAvailabilityProgressPageController.tasks.push({
              command: "startSecondNameNode",
              status: "FAILED"
            })
            highAvailabilityProgressPageController.rollback();
          }else{
            if(parseInt(currStep) > 4 && !App.supports.autoRollbackHA){
              highAvailabilityProgressPageController.manualRollback();
            }else {
              this.hide();
              App.router.get('highAvailabilityWizardController').setCurrentStep('1');
              App.router.get('updateController').set('isWorking', true);
              App.router.transitionTo('main.admin.adminHighAvailability');
            }
          }
        },
        didInsertElement: function () {
          this.fitHeight();
        }
      });
      highAvailabilityWizardController.set('popup', popup);
      App.clusterStatus.updateFromServer();
      var currentClusterStatus = App.clusterStatus.get('value');
      if (currentClusterStatus) {
        switch (currentClusterStatus.clusterState) {
          case 'HIGH_AVAILABILITY_DEPLOY' :
            App.db.data = currentClusterStatus.localdb;
            highAvailabilityWizardController.setCurrentStep(currentClusterStatus.localdb.HighAvailabilityWizard.currentStep);
            break;
          default:
            var currStep = App.router.get('highAvailabilityWizardController.currentStep');
            highAvailabilityWizardController.setCurrentStep(currStep);
            break;
        }
      }
      router.transitionTo('step' + highAvailabilityWizardController.get('currentStep'));
    });
  },

  step1: Em.Route.extend({
    route: '/step1',
    connectOutlets: function (router) {
      var controller = router.get('highAvailabilityWizardController');
      controller.setCurrentStep('1');
      controller.dataLoading().done(function () {
        controller.loadAllPriorSteps();
        controller.connectOutlet('highAvailabilityWizardStep1', controller.get('content'));
      })
    },
    unroutePath: function () {
      return false;
    },
    next: function (router) {
      var controller = router.get('highAvailabilityWizardController');
      controller.saveNameServiceId(router.get('highAvailabilityWizardStep1Controller.content.nameServiceId'));
      router.transitionTo('step2');
    }
  }),

  step2: Em.Route.extend({
    route: '/step2',
    connectOutlets: function (router) {
      var controller = router.get('highAvailabilityWizardController');
      controller.setCurrentStep('2');
      controller.dataLoading().done(function () {
        controller.loadAllPriorSteps();
        controller.connectOutlet('highAvailabilityWizardStep2', controller.get('content'));
      })
    },
    unroutePath: function () {
      return false;
    },
    next: function (router) {
      var controller = router.get('highAvailabilityWizardController');
      var highAvailabilityWizardStep2Controller = router.get('highAvailabilityWizardStep2Controller');
      controller.saveMasterComponentHosts(highAvailabilityWizardStep2Controller);
      router.transitionTo('step3');
    },
    back: function (router) {
      router.transitionTo('step1');
    }
  }),

  step3: Em.Route.extend({
    route: '/step3',
    connectOutlets: function (router) {
      var controller = router.get('highAvailabilityWizardController');
      controller.setCurrentStep('3');
      controller.dataLoading().done(function () {
        controller.loadAllPriorSteps();
        controller.connectOutlet('highAvailabilityWizardStep3',  controller.get('content'));
      })
    },
    unroutePath: function () {
      return false;
    },
    next: function (router) {
      router.transitionTo('step4');
    },
    back: function (router) {
      router.transitionTo('step2');
    }
  }),

  step4: Em.Route.extend({
    route: '/step4',
    connectOutlets: function (router) {
      var controller = router.get('highAvailabilityWizardController');
      controller.setCurrentStep('4');
      controller.setLowerStepsDisable(4);
      controller.dataLoading().done(function () {
        controller.loadAllPriorSteps();
        controller.connectOutlet('highAvailabilityWizardStep4',  controller.get('content'));
      })
    },
    unroutePath: function () {
      return false;
    },
    next: function (router) {
      var controller = router.get('highAvailabilityWizardController');
      controller.clearTasksData();
      router.transitionTo('step5');
    }
  }),

  step5: Em.Route.extend({
    route: '/step5',
    connectOutlets: function (router) {
      var controller = router.get('highAvailabilityWizardController');
      controller.setCurrentStep('5');
      controller.setLowerStepsDisable(5);
      controller.dataLoading().done(function () {
        controller.loadAllPriorSteps();
        controller.connectOutlet('highAvailabilityWizardStep5',  controller.get('content'));
      })
    },
    unroutePath: function () {
      return false;
    },
    next: function (router) {
      var controller = router.get('highAvailabilityWizardController');
      controller.clearTasksData();
      router.transitionTo('step6');
    }
  }),

  step6: Em.Route.extend({
    route: '/step6',
    connectOutlets: function (router) {
      var controller = router.get('highAvailabilityWizardController');
      controller.setCurrentStep('6');
      controller.setLowerStepsDisable(6);
      controller.dataLoading().done(function () {
        controller.loadAllPriorSteps();
        controller.connectOutlet('highAvailabilityWizardStep6',  controller.get('content'));
      })
    },
    unroutePath: function () {
      return false;
    },
    next: function (router) {
      router.transitionTo('step7');
    }
  }),

  step7: Em.Route.extend({
    route: '/step7',
    connectOutlets: function (router) {
      var controller = router.get('highAvailabilityWizardController');
      controller.setCurrentStep('7');
      controller.setLowerStepsDisable(7);
      controller.dataLoading().done(function () {
        controller.loadAllPriorSteps();
        controller.connectOutlet('highAvailabilityWizardStep7',  controller.get('content'));
      })
    },
    unroutePath: function () {
      return false;
    },
    next: function (router) {
      var controller = router.get('highAvailabilityWizardController');
      controller.clearTasksData();
      router.transitionTo('step8');
    }
  }),

  step8: Em.Route.extend({
    route: '/step8',
    connectOutlets: function (router) {
      var controller = router.get('highAvailabilityWizardController');
      controller.setCurrentStep('8');
      controller.setLowerStepsDisable(8);
      controller.dataLoading().done(function () {
        controller.loadAllPriorSteps();
        controller.connectOutlet('highAvailabilityWizardStep8',  controller.get('content'));
      })
    },
    unroutePath: function () {
      return false;
    },
    next: function (router) {
      App.showConfirmationPopup(function() {
        router.transitionTo('step9');
      }, Em.I18n.t('admin.highAvailability.wizard.step8.confirmPopup.body'));
    }
  }),

  step9: Em.Route.extend({
    route: '/step9',
    connectOutlets: function (router) {
      var controller = router.get('highAvailabilityWizardController');
      controller.setCurrentStep('9');
      controller.setLowerStepsDisable(9);
      controller.dataLoading().done(function () {
        controller.loadAllPriorSteps();
        controller.connectOutlet('highAvailabilityWizardStep9',  controller.get('content'));
      })
    },
    unroutePath: function () {
      return false;
    },
    next: function (router) {
      var controller = router.get('highAvailabilityWizardController');
      controller.clearTasksData();
      controller.finish();
      controller.clearStorageData();
      controller.get('popup').hide();
      App.clusterStatus.setClusterStatus({
        clusterName: controller.get('content.cluster.name'),
        clusterState: 'HIGH_AVAILABILITY_COMPLETED',
        wizardControllerName: 'highAvailabilityWizardController',
        localdb: App.db.data
      });
      router.transitionTo('main.index');
      location.reload();
    }
  }),

  gotoStep1: Em.Router.transitionTo('step1'),

  gotoStep2: Em.Router.transitionTo('step2'),

  gotoStep3: Em.Router.transitionTo('step3'),

  gotoStep4: Em.Router.transitionTo('step4'),

  gotoStep5: Em.Router.transitionTo('step5'),

  gotoStep6: Em.Router.transitionTo('step6'),

  gotoStep7: Em.Router.transitionTo('step7'),

  gotoStep8: Em.Router.transitionTo('step8'),

  gotoStep9: Em.Router.transitionTo('step9')
});
<commit_msg>AMBARI-3444. Refreshing page on steps "Initialize JournalNodes"/"Initialize Metadata" of HA wizard returns to previous step with all steps completed. (alexantonenko)<commit_after>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var App = require('app');

module.exports = Em.Route.extend({
  route: '/highAvailability/enable',

  enter: function (router) {
    Em.run.next(function () {
      var highAvailabilityWizardController = router.get('highAvailabilityWizardController');
      App.router.get('updateController').set('isWorking', false);
      var popup = App.ModalPopup.show({
        classNames: ['full-width-modal'],
        header: Em.I18n.t('admin.highAvailability.wizard.header'),
        bodyClass: App.HighAvailabilityWizardView.extend({
          controller: highAvailabilityWizardController
        }),
        primary: Em.I18n.t('form.cancel'),
        showFooter: false,
        secondary: null,
        hideCloseButton: function () {
          var currStep = App.router.get('highAvailabilityWizardController.currentStep');
          switch (currStep) {
            case "5" :
            case "7" :
            case "9" :
              if(App.supports.autoRollbackHA){
                this.set('showCloseButton', false);
              }else{
                this.set('showCloseButton', true);
              }
              break;
            default :
              this.set('showCloseButton', true);
          }
        }.observes('App.router.highAvailabilityWizardController.currentStep'),

        onClose: function () {
          var currStep = App.router.get('highAvailabilityWizardController.currentStep');
          var highAvailabilityProgressPageController = App.router.get('highAvailabilityProgressPageController');
          if (currStep == "6" && App.supports.autoRollbackHA){
            highAvailabilityProgressPageController.tasks.push({
              command: "startZooKeeperServers",
              status: "FAILED"
            })
            highAvailabilityProgressPageController.rollback();
          }else if(currStep == "8" && App.supports.autoRollbackHA){
            highAvailabilityProgressPageController.tasks.push({
              command: "startSecondNameNode",
              status: "FAILED"
            })
            highAvailabilityProgressPageController.rollback();
          }else{
            if(parseInt(currStep) > 4 && !App.supports.autoRollbackHA){
              highAvailabilityProgressPageController.manualRollback();
            }else {
              this.hide();
              App.router.get('highAvailabilityWizardController').setCurrentStep('1');
              App.router.get('updateController').set('isWorking', true);
              App.router.transitionTo('main.admin.adminHighAvailability');
            }
          }
        },
        didInsertElement: function () {
          this.fitHeight();
        }
      });
      highAvailabilityWizardController.set('popup', popup);
      App.clusterStatus.updateFromServer();
      var currentClusterStatus = App.clusterStatus.get('value');
      if (currentClusterStatus) {
        switch (currentClusterStatus.clusterState) {
          case 'HIGH_AVAILABILITY_DEPLOY' :
            App.db.data = currentClusterStatus.localdb;
            highAvailabilityWizardController.setCurrentStep(currentClusterStatus.localdb.HighAvailabilityWizard.currentStep);
            break;
          default:
            var currStep = App.router.get('highAvailabilityWizardController.currentStep');
            highAvailabilityWizardController.setCurrentStep(currStep);
            break;
        }
      }
      router.transitionTo('step' + highAvailabilityWizardController.get('currentStep'));
    });
  },

  step1: Em.Route.extend({
    route: '/step1',
    connectOutlets: function (router) {
      var controller = router.get('highAvailabilityWizardController');
      controller.setCurrentStep('1');
      controller.dataLoading().done(function () {
        controller.loadAllPriorSteps();
        controller.connectOutlet('highAvailabilityWizardStep1', controller.get('content'));
      })
    },
    unroutePath: function () {
      return false;
    },
    next: function (router) {
      var controller = router.get('highAvailabilityWizardController');
      controller.saveNameServiceId(router.get('highAvailabilityWizardStep1Controller.content.nameServiceId'));
      router.transitionTo('step2');
    }
  }),

  step2: Em.Route.extend({
    route: '/step2',
    connectOutlets: function (router) {
      var controller = router.get('highAvailabilityWizardController');
      controller.setCurrentStep('2');
      controller.dataLoading().done(function () {
        controller.loadAllPriorSteps();
        controller.connectOutlet('highAvailabilityWizardStep2', controller.get('content'));
      })
    },
    unroutePath: function () {
      return false;
    },
    next: function (router) {
      var controller = router.get('highAvailabilityWizardController');
      var highAvailabilityWizardStep2Controller = router.get('highAvailabilityWizardStep2Controller');
      controller.saveMasterComponentHosts(highAvailabilityWizardStep2Controller);
      router.transitionTo('step3');
    },
    back: function (router) {
      router.transitionTo('step1');
    }
  }),

  step3: Em.Route.extend({
    route: '/step3',
    connectOutlets: function (router) {
      var controller = router.get('highAvailabilityWizardController');
      controller.setCurrentStep('3');
      controller.dataLoading().done(function () {
        controller.loadAllPriorSteps();
        controller.connectOutlet('highAvailabilityWizardStep3',  controller.get('content'));
      })
    },
    unroutePath: function () {
      return false;
    },
    next: function (router) {
      router.transitionTo('step4');
    },
    back: function (router) {
      router.transitionTo('step2');
    }
  }),

  step4: Em.Route.extend({
    route: '/step4',
    connectOutlets: function (router) {
      var controller = router.get('highAvailabilityWizardController');
      controller.setCurrentStep('4');
      controller.setLowerStepsDisable(4);
      controller.dataLoading().done(function () {
        controller.loadAllPriorSteps();
        controller.connectOutlet('highAvailabilityWizardStep4',  controller.get('content'));
      })
    },
    unroutePath: function () {
      return false;
    },
    next: function (router) {
      var controller = router.get('highAvailabilityWizardController');
      controller.clearTasksData();
      router.transitionTo('step5');
    }
  }),

  step5: Em.Route.extend({
    route: '/step5',
    connectOutlets: function (router) {
      var controller = router.get('highAvailabilityWizardController');
      controller.setCurrentStep('5');
      controller.setLowerStepsDisable(5);
      controller.dataLoading().done(function () {
        controller.loadAllPriorSteps();
        controller.connectOutlet('highAvailabilityWizardStep5',  controller.get('content'));
      })
    },
    unroutePath: function () {
      return false;
    },
    next: function (router) {
      var controller = router.get('highAvailabilityWizardController');
      controller.clearTasksData();
      router.transitionTo('step6');
    }
  }),

  step6: Em.Route.extend({
    route: '/step6',
    connectOutlets: function (router) {
      var controller = router.get('highAvailabilityWizardController');
      controller.setCurrentStep('6');
      controller.setLowerStepsDisable(6);
      App.clusterStatus.setClusterStatus({
        clusterName: this.get('content.cluster.name'),
        clusterState: 'HIGH_AVAILABILITY_DEPLOY',
        wizardControllerName: this.get('content.controllerName'),
        localdb: App.db.data
      });
      controller.dataLoading().done(function () {
        controller.loadAllPriorSteps();
        controller.connectOutlet('highAvailabilityWizardStep6',  controller.get('content'));
      })
    },
    unroutePath: function () {
      return false;
    },
    next: function (router) {
      router.transitionTo('step7');
    }
  }),

  step7: Em.Route.extend({
    route: '/step7',
    connectOutlets: function (router) {
      var controller = router.get('highAvailabilityWizardController');
      controller.setCurrentStep('7');
      controller.setLowerStepsDisable(7);
      controller.dataLoading().done(function () {
        controller.loadAllPriorSteps();
        controller.connectOutlet('highAvailabilityWizardStep7',  controller.get('content'));
      })
    },
    unroutePath: function () {
      return false;
    },
    next: function (router) {
      var controller = router.get('highAvailabilityWizardController');
      controller.clearTasksData();
      router.transitionTo('step8');
    }
  }),

  step8: Em.Route.extend({
    route: '/step8',
    connectOutlets: function (router) {
      var controller = router.get('highAvailabilityWizardController');
      controller.setCurrentStep('8');
      controller.setLowerStepsDisable(8);
      App.clusterStatus.setClusterStatus({
        clusterName: this.get('content.cluster.name'),
        clusterState: 'HIGH_AVAILABILITY_DEPLOY',
        wizardControllerName: this.get('content.controllerName'),
        localdb: App.db.data
      });
      controller.dataLoading().done(function () {
        controller.loadAllPriorSteps();
        controller.connectOutlet('highAvailabilityWizardStep8',  controller.get('content'));
      })
    },
    unroutePath: function () {
      return false;
    },
    next: function (router) {
      App.showConfirmationPopup(function() {
        router.transitionTo('step9');
      }, Em.I18n.t('admin.highAvailability.wizard.step8.confirmPopup.body'));
    }
  }),

  step9: Em.Route.extend({
    route: '/step9',
    connectOutlets: function (router) {
      var controller = router.get('highAvailabilityWizardController');
      controller.setCurrentStep('9');
      controller.setLowerStepsDisable(9);
      controller.dataLoading().done(function () {
        controller.loadAllPriorSteps();
        controller.connectOutlet('highAvailabilityWizardStep9',  controller.get('content'));
      })
    },
    unroutePath: function () {
      return false;
    },
    next: function (router) {
      var controller = router.get('highAvailabilityWizardController');
      controller.clearTasksData();
      controller.finish();
      controller.clearStorageData();
      controller.get('popup').hide();
      App.clusterStatus.setClusterStatus({
        clusterName: controller.get('content.cluster.name'),
        clusterState: 'HIGH_AVAILABILITY_COMPLETED',
        wizardControllerName: 'highAvailabilityWizardController',
        localdb: App.db.data
      });
      router.transitionTo('main.index');
      location.reload();
    }
  }),

  gotoStep1: Em.Router.transitionTo('step1'),

  gotoStep2: Em.Router.transitionTo('step2'),

  gotoStep3: Em.Router.transitionTo('step3'),

  gotoStep4: Em.Router.transitionTo('step4'),

  gotoStep5: Em.Router.transitionTo('step5'),

  gotoStep6: Em.Router.transitionTo('step6'),

  gotoStep7: Em.Router.transitionTo('step7'),

  gotoStep8: Em.Router.transitionTo('step8'),

  gotoStep9: Em.Router.transitionTo('step9')
});
<|endoftext|>


<commit_before>/* global module:true */

"use strict";

var React = require("react"),
    _ = require("lodash");

module.exports = React.createClass({
    toHexadecimal: function(integer) {
        if (integer < 10) {
            return "0x0" + integer.toString(16).toUpperCase();
        }

        return "0x" + integer.toString(16).toUpperCase();
    },
    createLine: function(data) {
        return React.DOM.tbody(
            {
                key: data.offset
            },
            React.DOM.tr(
                null,
                React.DOM.th(
                    {
                        className: "offset",
                        scope: "row"
                    },
                    this.toHexadecimal(data.offset)
                ),
                React.DOM.td(
                    null,
                    data.name
                ),
                React.DOM.td(
                    {
                        className: "value"
                    },
                    "0x00"
                )
            )
        );
    },
    render: function() {
        return React.DOM.div(
            null,
            React.DOM.div(
                {
                    className: "registerlist"
                },
                React.DOM.table(
                    {
                        className: "table table-sm table-bordered"
                    },
                    React.DOM.thead(
                        null,
                        React.DOM.tr(
                            {
                                className: "table-dark"
                            },
                            React.DOM.th(
                                null,
                                "Offset"
                            ),
                            React.DOM.th(
                                null,
                                "Name"
                            ),
                            React.DOM.th(
                                null,
                                "Value"
                            )
                        )
                    ),
                    _.map(this.props.data, function(data) {
                        return this.createLine(data);
                    }.bind(this))
                )
            )
        );
    }
});
<commit_msg>Try to group consecutive offset to reduce I2C access (still got error with 1 offset group)<commit_after>/* global module:true */

"use strict";

var React = require("react"),
    _ = require("lodash");

module.exports = React.createClass({
    componentDidMount: function() {
        var prevOffset = -1;
        var startOffset = -1;
        var nbofdata = 0;
        var array = [];
        _.forEach(this.props.data, function(data) {
            if (startOffset === -1) {
                startOffset = data.offset;
            }

            if (prevOffset !== -1) {
                if ((prevOffset + 1) === data.offset) {
                    nbofdata += 1;
                } else {
                    array.push(startOffset);
                    console.log(startOffset + " " + (nbofdata + 1));
                    nbofdata = 0;
                    startOffset = data.offset;
                }
            }

            prevOffset = data.offset;
        });
    },
    toHexadecimal: function(integer) {
        if (integer < 10) {
            return "0x0" + integer.toString(16).toUpperCase();
        }

        return "0x" + integer.toString(16).toUpperCase();
    },
    createLine: function(data) {
        return React.DOM.tbody(
            {
                key: data.offset
            },
            React.DOM.tr(
                null,
                React.DOM.th(
                    {
                        className: "offset",
                        scope: "row"
                    },
                    this.toHexadecimal(data.offset)
                ),
                React.DOM.td(
                    null,
                    data.name
                ),
                React.DOM.td(
                    {
                        className: "value"
                    },
                    "0x00"
                )
            )
        );
    },
    render: function() {
        return React.DOM.div(
            null,
            React.DOM.div(
                {
                    className: "registerlist"
                },
                React.DOM.table(
                    {
                        className: "table table-sm table-bordered"
                    },
                    React.DOM.thead(
                        null,
                        React.DOM.tr(
                            {
                                className: "table-dark"
                            },
                            React.DOM.th(
                                null,
                                "Offset"
                            ),
                            React.DOM.th(
                                null,
                                "Name"
                            ),
                            React.DOM.th(
                                null,
                                "Value"
                            )
                        )
                    ),
                    _.map(this.props.data, function(data) {
                        return this.createLine(data);
                    }.bind(this))
                )
            )
        );
    }
});
<|endoftext|>