From f2d631e42d6840d0b07c2183539a23c5e2573db4 Mon Sep 17 00:00:00 2001
From: Julian Lam <julian.lam@gmail.com>
Date: Tue, 17 Dec 2013 23:42:02 -0500
Subject: [PATCH] new composer window template (WIP!)

---
 public/src/modules/composer.js | 294 +++++++++++++++++----------------
 public/src/templates.js        |  35 ++--
 public/templates/composer.tpl  |  22 +++
 3 files changed, 193 insertions(+), 158 deletions(-)
 create mode 100644 public/templates/composer.tpl

diff --git a/public/src/modules/composer.js b/public/src/modules/composer.js
index 34941f7518..de16eb733d 100644
--- a/public/src/modules/composer.js
+++ b/public/src/modules/composer.js
@@ -112,163 +112,167 @@ define(['taskbar'], function(taskbar) {
 
 	composer.init = function() {
 		if (!composer.initialized) {
-			var taskbar = document.getElementById('taskbar');
-
-			composer.postContainer = document.createElement('div');
-			composer.postContainer.className = 'post-window row';
-			composer.postContainer.innerHTML =	'<div class="col-md-5">' +
-													'<input type="text" tabIndex="1" placeholder="Enter your topic title here..." />' +
-													'<div class="btn-toolbar formatting-bar">' +
-														'<div class="btn-group">' +
-															'<span class="btn btn-link" tabindex="-1"><i class="fa fa-bold"></i></span>' +
-															'<span class="btn btn-link" tabindex="-1"><i class="fa fa-italic"></i></span>' +
-															'<span class="btn btn-link" tabindex="-1"><i class="fa fa-list"></i></span>' +
-															'<span class="btn btn-link" tabindex="-1"><i class="fa fa-link"></i></span>' +
-														'</div>' +
-													'</div>' +
-													'<textarea tabIndex="2"></textarea>' +
-													'<div class="imagedrop"><div>Drag and Drop Images Here</div></div>'+
-													'<div class="btn-toolbar action-bar">' +
-														'<div class="btn-group" style="float: right; margin-right: -8px">' +
-															'<button data-action="minimize" class="btn hidden-xs" tabIndex="4"><i class="fa fa-download"></i> Minimize</button>' +
-															'<button class="btn" data-action="discard" tabIndex="5"><i class="fa fa-times"></i> Discard</button>' +
-															'<button data-action="post" class="btn" tabIndex="3"><i class="fa fa-check"></i> Submit</button>' +
-														'</div>' +
-													'</div>' +
-												'</div>';
-
-			document.body.insertBefore(composer.postContainer, taskbar);
-
-			if(config.imgurClientIDSet) {
-				initializeFileReader();
-			}
+			templates.preload_template('composer', function() {
+				$(document.body).append(templates['composer'].parse({}));
+				composer.postContainer = $('.composer')[0];
 
-			socket.on('api:composer.push', function(threadData) {
-				if (!threadData.error) {
-					var uuid = utils.generateUUID();
-
-					composer.taskbar.push('composer', uuid, {
-						title: (!threadData.cid ? (threadData.title || '') : 'New Topic'),
-						icon: threadData.picture
-					});
-
-					composer.posts[uuid] = {
-						tid: threadData.tid,
-						cid: threadData.cid,
-						pid: threadData.pid,
-						title: threadData.title || '',
-						body: threadData.body || '',
-						modified: false
-					};
-					composer.load(uuid);
-				} else {
-					app.alert({
-						type: 'danger',
-						timeout: 5000,
-						alert_id: 'post_error',
-						title: 'Please Log In to Post',
-						message: 'Posting is currently restricted to registered members only, click here to log in',
-						clickfn: function() {
-							ajaxify.go('login');
-						}
-					});
+				if(config.imgurClientIDSet) {
+					initializeFileReader();
 				}
-			});
 
-			socket.on('api:composer.editCheck', function(editCheck) {
-				if (editCheck.titleEditable === true) composer.postContainer.querySelector('input').readOnly = false;
-			});
+				socket.on('api:composer.push', function(threadData) {
+					if (!threadData.error) {
+						var uuid = utils.generateUUID();
+
+						composer.taskbar.push('composer', uuid, {
+							title: (!threadData.cid ? (threadData.title || '') : 'New Topic'),
+							icon: threadData.picture
+						});
+
+						composer.posts[uuid] = {
+							tid: threadData.tid,
+							cid: threadData.cid,
+							pid: threadData.pid,
+							title: threadData.title || '',
+							body: threadData.body || '',
+							modified: false
+						};
+						composer.load(uuid);
+					} else {
+						app.alert({
+							type: 'danger',
+							timeout: 5000,
+							alert_id: 'post_error',
+							title: 'Please Log In to Post',
+							message: 'Posting is currently restricted to registered members only, click here to log in',
+							clickfn: function() {
+								ajaxify.go('login');
+							}
+						});
+					}
+				});
 
-			// Post Window events
-			var	jPostContainer = $(composer.postContainer),
-				postContentEl = composer.postContainer.querySelector('textarea');
+				socket.on('api:composer.editCheck', function(editCheck) {
+					if (editCheck.titleEditable === true) composer.postContainer.querySelector('input').readOnly = false;
+				});
 
-			jPostContainer.on('change', 'input, textarea', function() {
-				var uuid = $(this).parents('.post-window')[0].getAttribute('data-uuid');
-				if (this.nodeName === 'INPUT') composer.posts[uuid].title = this.value;
-				else if (this.nodeName === 'TEXTAREA') composer.posts[uuid].body = this.value;
+				// Post Window events
+				var	jPostContainer = $(composer.postContainer),
+					postContentEl = composer.postContainer.querySelector('textarea');
 
-				// Mark this post window as having been changed
-				composer.posts[uuid].modified = true;
-			});
+				jPostContainer.on('change', 'input, textarea', function() {
+					var uuid = $(this).parents('.post-window')[0].getAttribute('data-uuid');
+					if (this.nodeName === 'INPUT') composer.posts[uuid].title = this.value;
+					else if (this.nodeName === 'TEXTAREA') composer.posts[uuid].body = this.value;
 
-			jPostContainer.on('click', '.action-bar button', function() {
-				var	action = this.getAttribute('data-action'),
-					uuid = $(this).parents('.post-window').attr('data-uuid');
-				switch(action) {
-					case 'post': composer.post(uuid); break;
-					case 'minimize': composer.minimize(uuid); break;
-					case 'discard':
-						if (composer.posts[uuid].modified) {
-							bootbox.confirm('Are you sure you wish to discard this post?', function(discard) {
-								if (discard) composer.discard(uuid);
-							});
-						} else {
-							composer.discard(uuid);
-						}
-						break;
-				}
-			});
+					// Mark this post window as having been changed
+					composer.posts[uuid].modified = true;
+				});
 
-			jPostContainer.on('click', '.formatting-bar span', function() {
-				var iconClass = this.querySelector('i').className,
-					cursorEnd = postContentEl.value.length,
-					selectionStart = postContentEl.selectionStart,
-					selectionEnd = postContentEl.selectionEnd,
-					selectionLength = selectionEnd - selectionStart;
-
-				function insertIntoInput(element, value) {
-					var start = postContentEl.selectionStart;
-					element.value = element.value.slice(0, start) + value + element.value.slice(start, element.value.length);
-					postContentEl.selectionStart = postContentEl.selectionEnd = start + value.length;
-				}
+				jPostContainer.on('click', '.action-bar button', function() {
+					var	action = this.getAttribute('data-action'),
+						uuid = $(this).parents('.post-window').attr('data-uuid');
+					switch(action) {
+						case 'post': composer.post(uuid); break;
+						case 'minimize': composer.minimize(uuid); break;
+						case 'discard':
+							if (composer.posts[uuid].modified) {
+								bootbox.confirm('Are you sure you wish to discard this post?', function(discard) {
+									if (discard) composer.discard(uuid);
+								});
+							} else {
+								composer.discard(uuid);
+							}
+							break;
+					}
+				});
 
-				switch(iconClass) {
-					case 'fa fa-bold':
-						if (selectionStart === selectionEnd) {
-							// Nothing selected
-							insertIntoInput(postContentEl, "**bolded text**");
-						} else {
-							// Text selected
-							postContentEl.value = postContentEl.value.slice(0, selectionStart) + '**' + postContentEl.value.slice(selectionStart, selectionEnd) + '**' + postContentEl.value.slice(selectionEnd);
-							postContentEl.selectionStart = selectionStart + 2;
-							postContentEl.selectionEnd = selectionEnd + 2;
-						}
-					break;
-					case 'fa fa-italic':
-						if (selectionStart === selectionEnd) {
-							// Nothing selected
-							insertIntoInput(postContentEl, "*italicised text*");
-						} else {
-							// Text selected
-							postContentEl.value = postContentEl.value.slice(0, selectionStart) + '*' + postContentEl.value.slice(selectionStart, selectionEnd) + '*' + postContentEl.value.slice(selectionEnd);
-							postContentEl.selectionStart = selectionStart + 1;
-							postContentEl.selectionEnd = selectionEnd + 1;
-						}
-					break;
-					case 'fa fa-list':
-						// Nothing selected
-						insertIntoInput(postContentEl, "\n\n* list item");
-					break;
-					case 'fa fa-link':
-						if (selectionStart === selectionEnd) {
+				jPostContainer.on('click', '.formatting-bar span', function() {
+					var iconClass = this.querySelector('i').className,
+						cursorEnd = postContentEl.value.length,
+						selectionStart = postContentEl.selectionStart,
+						selectionEnd = postContentEl.selectionEnd,
+						selectionLength = selectionEnd - selectionStart;
+
+					function insertIntoInput(element, value) {
+						var start = postContentEl.selectionStart;
+						element.value = element.value.slice(0, start) + value + element.value.slice(start, element.value.length);
+						postContentEl.selectionStart = postContentEl.selectionEnd = start + value.length;
+					}
+
+					switch(iconClass) {
+						case 'fa fa-bold':
+							if (selectionStart === selectionEnd) {
+								// Nothing selected
+								insertIntoInput(postContentEl, "**bolded text**");
+							} else {
+								// Text selected
+								postContentEl.value = postContentEl.value.slice(0, selectionStart) + '**' + postContentEl.value.slice(selectionStart, selectionEnd) + '**' + postContentEl.value.slice(selectionEnd);
+								postContentEl.selectionStart = selectionStart + 2;
+								postContentEl.selectionEnd = selectionEnd + 2;
+							}
+						break;
+						case 'fa fa-italic':
+							if (selectionStart === selectionEnd) {
+								// Nothing selected
+								insertIntoInput(postContentEl, "*italicised text*");
+							} else {
+								// Text selected
+								postContentEl.value = postContentEl.value.slice(0, selectionStart) + '*' + postContentEl.value.slice(selectionStart, selectionEnd) + '*' + postContentEl.value.slice(selectionEnd);
+								postContentEl.selectionStart = selectionStart + 1;
+								postContentEl.selectionEnd = selectionEnd + 1;
+							}
+						break;
+						case 'fa fa-list':
 							// Nothing selected
-							insertIntoInput(postContentEl, "[link text](link url)");
-						} else {
-							// Text selected
-							postContentEl.value = postContentEl.value.slice(0, selectionStart) + '[' + postContentEl.value.slice(selectionStart, selectionEnd) + '](link url)' + postContentEl.value.slice(selectionEnd);
-							postContentEl.selectionStart = selectionStart + selectionLength + 3;
-							postContentEl.selectionEnd = selectionEnd + 11;
-						}
-					break;
-				}
-			});
+							insertIntoInput(postContentEl, "\n\n* list item");
+						break;
+						case 'fa fa-link':
+							if (selectionStart === selectionEnd) {
+								// Nothing selected
+								insertIntoInput(postContentEl, "[link text](link url)");
+							} else {
+								// Text selected
+								postContentEl.value = postContentEl.value.slice(0, selectionStart) + '[' + postContentEl.value.slice(selectionStart, selectionEnd) + '](link url)' + postContentEl.value.slice(selectionEnd);
+								postContentEl.selectionStart = selectionStart + selectionLength + 3;
+								postContentEl.selectionEnd = selectionEnd + 11;
+							}
+						break;
+					}
+				});
 
-			window.addEventListener('resize', function() {
-				if (composer.active !== undefined) composer.reposition(composer.active);
-			});
+				window.addEventListener('resize', function() {
+					if (composer.active !== undefined) composer.reposition(composer.active);
+				});
 
-			composer.initialized = true;
+				composer.initialized = true;
+			});
+			// var taskbar = document.getElementById('taskbar');
+
+			// composer.postContainer = document.createElement('div');
+			// composer.postContainer.className = 'post-window row';
+			// composer.postContainer.innerHTML =	'<div class="col-md-5">' +
+			// 										'<input type="text" tabIndex="1" placeholder="Enter your topic title here..." />' +
+			// 										'<div class="btn-toolbar formatting-bar">' +
+			// 											'<div class="btn-group">' +
+			// 												'<span class="btn btn-link" tabindex="-1"><i class="fa fa-bold"></i></span>' +
+			// 												'<span class="btn btn-link" tabindex="-1"><i class="fa fa-italic"></i></span>' +
+			// 												'<span class="btn btn-link" tabindex="-1"><i class="fa fa-list"></i></span>' +
+			// 												'<span class="btn btn-link" tabindex="-1"><i class="fa fa-link"></i></span>' +
+			// 											'</div>' +
+			// 										'</div>' +
+			// 										'<textarea tabIndex="2"></textarea>' +
+			// 										'<div class="imagedrop"><div>Drag and Drop Images Here</div></div>'+
+			// 										'<div class="btn-toolbar action-bar">' +
+			// 											'<div class="btn-group" style="float: right; margin-right: -8px">' +
+			// 												'<button data-action="minimize" class="btn hidden-xs" tabIndex="4"><i class="fa fa-download"></i> Minimize</button>' +
+			// 												'<button class="btn" data-action="discard" tabIndex="5"><i class="fa fa-times"></i> Discard</button>' +
+			// 												'<button data-action="post" class="btn" tabIndex="3"><i class="fa fa-check"></i> Submit</button>' +
+			// 											'</div>' +
+			// 										'</div>' +
+			// 									'</div>';
+
+			// document.body.insertBefore(composer.postContainer, taskbar);
 		}
 	}
 
diff --git a/public/src/templates.js b/public/src/templates.js
index 53f7919f91..8390f54075 100644
--- a/public/src/templates.js
+++ b/public/src/templates.js
@@ -122,6 +122,27 @@
 		return '';
 	}
 
+	templates.preload_template = function(tpl_name, callback) {
+		// TODO: This should be "load_template", and the current load_template
+		// should be named something else
+		// TODO: The "Date.now()" in the line below is only there for development purposes.
+		// It should be removed at some point.
+		jQuery.get(RELATIVE_PATH + '/templates/' + tpl_name + '.tpl?v=' + Date.now(), function (html) {
+			var template = function () {
+				this.toString = function () {
+					return this.html;
+				};
+			}
+
+			template.prototype.parse = parse;
+			template.prototype.html = String(html);
+			template.prototype.blocks = {};
+
+			templates[tpl_name] = new template;
+
+			callback();
+		});
+	}
 
 	templates.load_template = function (callback, url, template) {
 		var location = document.location || window.location,
@@ -137,19 +158,7 @@
 		var timestamp = new Date().getTime(); //debug
 
 		if (!templates[tpl_url]) {
-			jQuery.get(RELATIVE_PATH + '/templates/' + tpl_url + '.tpl?v=' + timestamp, function (html) {
-				var template = function () {
-					this.toString = function () {
-						return this.html;
-					};
-				}
-
-				template.prototype.parse = parse;
-				template.prototype.html = String(html);
-				template.prototype.blocks = {};
-
-				templates[tpl_url] = new template;
-
+			templates.preload_template(tpl_url, function() {
 				parse_template();
 			});
 		} else {
diff --git a/public/templates/composer.tpl b/public/templates/composer.tpl
new file mode 100644
index 0000000000..7441dbbe6f
--- /dev/null
+++ b/public/templates/composer.tpl
@@ -0,0 +1,22 @@
+<div class="composer">
+	<input class="title" type="text" tabIndex="1" placeholder="Enter your topic title here..." />
+	<div class="btn-toolbar formatting-bar">
+		<div class="btn-group">
+			<span class="btn btn-link" tabindex="-1"><i class="fa fa-bold"></i></span>
+			<span class="btn btn-link" tabindex="-1"><i class="fa fa-italic"></i></span>
+			<span class="btn btn-link" tabindex="-1"><i class="fa fa-list"></i></span>
+			<span class="btn btn-link" tabindex="-1"><i class="fa fa-link"></i></span>
+		</div>
+		<div class="btn btn-link pull-right">Preview</div>
+	</div>
+	<textarea tabIndex="2"></textarea>
+	<div class="imagedrop"><div>Drag and Drop Images Here</div></div>
+	<div class="btn-toolbar action-bar">
+		<div class="btn-group pull-right">
+			<button data-action="minimize" class="btn hidden-xs" tabIndex="4"><i class="fa fa-download"></i> Minimize</button>
+			<button class="btn" data-action="discard" tabIndex="5"><i class="fa fa-times"></i> Discard</button>
+			<button data-action="post" class="btn" tabIndex="3"><i class="fa fa-check"></i> Submit</button>
+		</div>
+	</div>
+	<div class="resizer"><div class="trigger"><i class="fa fa-chevron-left"></i></div></div>
+</div>
\ No newline at end of file