Jelajahi Sumber

Update from 1.11.x

Julio Montoya 5 tahun lalu
induk
melakukan
8f6c80cee1

+ 45 - 0
app/Resources/public/assets/linkifyjs/.bower.json

@@ -0,0 +1,45 @@
+{
+  "name": "linkifyjs",
+  "main": "linkify.js",
+  "version": "2.1.8",
+  "authors": [
+    "SoapBox Innovations Inc. <dev@soapboxhq.com>"
+  ],
+  "description": "Intelligent link recognition, made easy",
+  "keywords": [
+    "node",
+    "js",
+    "jquery",
+    "link",
+    "autolink",
+    "text",
+    "url",
+    "email",
+    "hashtag",
+    "hashtags",
+    "mention",
+    "mentions"
+  ],
+  "license": "MIT",
+  "homepage": "http://soapbox.github.io/linkifyjs/",
+  "ignore": [
+    "**/.*",
+    "node_modules",
+    "bower_components",
+    "test",
+    "tests"
+  ],
+  "dependencies": {
+    "jquery": ">=1.7.0"
+  },
+  "_release": "2.1.8",
+  "_resolution": {
+    "type": "version",
+    "tag": "v2.1.8",
+    "commit": "e7fbf85e679af9ef786a6e5ab83de546a371cbac"
+  },
+  "_source": "https://github.com/nfrasser/linkify-shim.git",
+  "_target": "^2.1.8",
+  "_originalSource": "linkifyjs",
+  "_direct": true
+}

+ 21 - 0
app/Resources/public/assets/linkifyjs/README.md

@@ -0,0 +1,21 @@
+Linkify
+=======
+
+Shim repository for Linkify. All issues with this plugin should be directed to http://github.com/SoapBox/linkifyjs/
+
+Package Managers
+----------------
+
+### [Bower](http://bower.io/)
+
+```
+bower install linkifyjs
+```
+
+### [NPM](https://npmjs.com/)
+
+See the [main repository](https://github.com/SoapBox/linkifyjs/blob/master/README.md) for usage with Node.js/Browserify.
+
+```
+npm install linkifyjs
+```

+ 36 - 0
app/Resources/public/assets/linkifyjs/bower.json

@@ -0,0 +1,36 @@
+{
+  "name": "linkifyjs",
+  "main": "linkify.js",
+
+  "version": "2.1.8",
+  "authors": [
+    "SoapBox Innovations Inc. <dev@soapboxhq.com>"
+  ],
+  "description": "Intelligent link recognition, made easy",
+  "keywords": [
+    "node",
+    "js",
+    "jquery",
+    "link",
+    "autolink",
+    "text",
+    "url",
+    "email",
+    "hashtag",
+    "hashtags",
+    "mention",
+    "mentions"
+  ],
+  "license": "MIT",
+  "homepage": "http://soapbox.github.io/linkifyjs/",
+  "ignore": [
+    "**/.*",
+    "node_modules",
+    "bower_components",
+    "test",
+    "tests"
+  ],
+  "dependencies": {
+    "jquery": ">=1.7.0"
+  }
+}

+ 293 - 0
app/Resources/public/assets/linkifyjs/linkify-jquery.js

@@ -0,0 +1,293 @@
+'use strict';
+
+;(function (window, linkify, $) {
+	var linkifyJquery = function (linkify) {
+		'use strict';
+
+		/**
+  	Linkify a HTML DOM node
+  */
+
+		var tokenize = linkify.tokenize,
+		    options = linkify.options;
+		var Options = options.Options;
+
+
+		var TEXT_TOKEN = linkify.parser.TOKENS.TEXT;
+
+		var HTML_NODE = 1;
+		var TXT_NODE = 3;
+
+		/**
+  	Given a parent element and child node that the parent contains, replaces
+  	that child with the given array of new children
+  */
+		function replaceChildWithChildren(parent, oldChild, newChildren) {
+			var lastNewChild = newChildren[newChildren.length - 1];
+			parent.replaceChild(lastNewChild, oldChild);
+			for (var i = newChildren.length - 2; i >= 0; i--) {
+				parent.insertBefore(newChildren[i], lastNewChild);
+				lastNewChild = newChildren[i];
+			}
+		}
+
+		/**
+  	Given an array of MultiTokens, return an array of Nodes that are either
+  	(a) Plain Text nodes (node type 3)
+  	(b) Anchor tag nodes (usually, unless tag name is overridden in the options)
+  
+  	Takes the same options as linkifyElement and an optional doc element
+  	(this should be passed in by linkifyElement)
+  */
+		function tokensToNodes(tokens, opts, doc) {
+			var result = [];
+
+			for (var _iterator = tokens, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
+				var _ref;
+
+				if (_isArray) {
+					if (_i >= _iterator.length) break;
+					_ref = _iterator[_i++];
+				} else {
+					_i = _iterator.next();
+					if (_i.done) break;
+					_ref = _i.value;
+				}
+
+				var token = _ref;
+
+				if (token.type === 'nl' && opts.nl2br) {
+					result.push(doc.createElement('br'));
+					continue;
+				} else if (!token.isLink || !opts.check(token)) {
+					result.push(doc.createTextNode(token.toString()));
+					continue;
+				}
+
+				var _opts$resolve = opts.resolve(token),
+				    formatted = _opts$resolve.formatted,
+				    formattedHref = _opts$resolve.formattedHref,
+				    tagName = _opts$resolve.tagName,
+				    className = _opts$resolve.className,
+				    target = _opts$resolve.target,
+				    events = _opts$resolve.events,
+				    attributes = _opts$resolve.attributes;
+
+				// Build the link
+
+
+				var link = doc.createElement(tagName);
+				link.setAttribute('href', formattedHref);
+
+				if (className) {
+					link.setAttribute('class', className);
+				}
+
+				if (target) {
+					link.setAttribute('target', target);
+				}
+
+				// Build up additional attributes
+				if (attributes) {
+					for (var attr in attributes) {
+						link.setAttribute(attr, attributes[attr]);
+					}
+				}
+
+				if (events) {
+					for (var event in events) {
+						if (link.addEventListener) {
+							link.addEventListener(event, events[event]);
+						} else if (link.attachEvent) {
+							link.attachEvent('on' + event, events[event]);
+						}
+					}
+				}
+
+				link.appendChild(doc.createTextNode(formatted));
+				result.push(link);
+			}
+
+			return result;
+		}
+
+		// Requires document.createElement
+		function linkifyElementHelper(element, opts, doc) {
+
+			// Can the element be linkified?
+			if (!element || element.nodeType !== HTML_NODE) {
+				throw new Error('Cannot linkify ' + element + ' - Invalid DOM Node type');
+			}
+
+			var ignoreTags = opts.ignoreTags;
+
+			// Is this element already a link?
+			if (element.tagName === 'A' || options.contains(ignoreTags, element.tagName)) {
+				// No need to linkify
+				return element;
+			}
+
+			var childElement = element.firstChild;
+
+			while (childElement) {
+				var str = void 0,
+				    tokens = void 0,
+				    nodes = void 0;
+
+				switch (childElement.nodeType) {
+					case HTML_NODE:
+						linkifyElementHelper(childElement, opts, doc);
+						break;
+					case TXT_NODE:
+						{
+							str = childElement.nodeValue;
+							tokens = tokenize(str);
+
+							if (tokens.length === 0 || tokens.length === 1 && tokens[0] instanceof TEXT_TOKEN) {
+								// No node replacement required
+								break;
+							}
+
+							nodes = tokensToNodes(tokens, opts, doc);
+
+							// Swap out the current child for the set of nodes
+							replaceChildWithChildren(element, childElement, nodes);
+
+							// so that the correct sibling is selected next
+							childElement = nodes[nodes.length - 1];
+
+							break;
+						}
+				}
+
+				childElement = childElement.nextSibling;
+			}
+
+			return element;
+		}
+
+		function linkifyElement(element, opts) {
+			var doc = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
+
+
+			try {
+				doc = doc || document || window && window.document || global && global.document;
+			} catch (e) {/* do nothing for now */}
+
+			if (!doc) {
+				throw new Error('Cannot find document implementation. ' + 'If you are in a non-browser environment like Node.js, ' + 'pass the document implementation as the third argument to linkifyElement.');
+			}
+
+			opts = new Options(opts);
+			return linkifyElementHelper(element, opts, doc);
+		}
+
+		// Maintain reference to the recursive helper to cache option-normalization
+		linkifyElement.helper = linkifyElementHelper;
+		linkifyElement.normalize = function (opts) {
+			return new Options(opts);
+		};
+
+		// Applies the plugin to jQuery
+		function apply($) {
+			var doc = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
+
+
+			$.fn = $.fn || {};
+
+			try {
+				doc = doc || document || window && window.document || global && global.document;
+			} catch (e) {/* do nothing for now */}
+
+			if (!doc) {
+				throw new Error('Cannot find document implementation. ' + 'If you are in a non-browser environment like Node.js, ' + 'pass the document implementation as the second argument to linkify/jquery');
+			}
+
+			if (typeof $.fn.linkify === 'function') {
+				// Already applied
+				return;
+			}
+
+			function jqLinkify(opts) {
+				opts = linkifyElement.normalize(opts);
+				return this.each(function () {
+					linkifyElement.helper(this, opts, doc);
+				});
+			}
+
+			$.fn.linkify = jqLinkify;
+
+			$(doc).ready(function () {
+				$('[data-linkify]').each(function () {
+					var $this = $(this);
+					var data = $this.data();
+					var target = data.linkify;
+					var nl2br = data.linkifyNlbr;
+
+					var options = {
+						nl2br: !!nl2br && nl2br !== 0 && nl2br !== 'false'
+					};
+
+					if ('linkifyAttributes' in data) {
+						options.attributes = data.linkifyAttributes;
+					}
+
+					if ('linkifyDefaultProtocol' in data) {
+						options.defaultProtocol = data.linkifyDefaultProtocol;
+					}
+
+					if ('linkifyEvents' in data) {
+						options.events = data.linkifyEvents;
+					}
+
+					if ('linkifyFormat' in data) {
+						options.format = data.linkifyFormat;
+					}
+
+					if ('linkifyFormatHref' in data) {
+						options.formatHref = data.linkifyFormatHref;
+					}
+
+					if ('linkifyTagname' in data) {
+						options.tagName = data.linkifyTagname;
+					}
+
+					if ('linkifyTarget' in data) {
+						options.target = data.linkifyTarget;
+					}
+
+					if ('linkifyValidate' in data) {
+						options.validate = data.linkifyValidate;
+					}
+
+					if ('linkifyIgnoreTags' in data) {
+						options.ignoreTags = data.linkifyIgnoreTags;
+					}
+
+					if ('linkifyClassName' in data) {
+						options.className = data.linkifyClassName;
+					} else if ('linkifyLinkclass' in data) {
+						// linkClass is deprecated
+						options.className = data.linkifyLinkclass;
+					}
+
+					options = linkifyElement.normalize(options);
+
+					var $target = target === 'this' ? $this : $this.find(target);
+					$target.linkify(options);
+				});
+			});
+		}
+
+		// Try assigning linkifyElement to the browser scope
+		try {
+			!undefined.define && (window.linkifyElement = linkifyElement);
+		} catch (e) {/**/}
+
+		return apply;
+	}(linkify);
+
+	if (typeof $.fn.linkify !== 'function') {
+		linkifyJquery($);
+	}
+})(window, linkify, jQuery);

File diff ditekan karena terlalu besar
+ 0 - 0
app/Resources/public/assets/linkifyjs/linkify-jquery.min.js


File diff ditekan karena terlalu besar
+ 589 - 0
app/Resources/public/assets/linkifyjs/linkify.js


File diff ditekan karena terlalu besar
+ 0 - 0
app/Resources/public/assets/linkifyjs/linkify.min.js


+ 123 - 106
main/inc/lib/javascript/chat/css/chat.css

@@ -1,181 +1,198 @@
 .chatboxmain {
-	position: fixed;
-	width: auto;
-	z-index: 9000;
-	bottom: 0px;
-	right: 20px;
-	display: block;
+    position: fixed;
+    width: auto;
+    z-index: 9000;
+    bottom: 0px;
+    right: 20px;
+    display: block;
 }
+
 .chatboxheadmain {
-	color: #ffffff;
-	background-color: #000;
-	min-height: 34px;
-	padding: 0 10px;
+    color: #ffffff;
+    background-color: #000;
+    min-height: 34px;
+    padding: 0 10px;
 }
 
 #chatboxtitlemain {
-  font-weight: normal;
-	float: left;
-	font-size: 12px;
-  padding-top: 2px;
-	cursor:pointer;
+    font-weight: normal;
+    float: left;
+    font-size: 12px;
+    padding-top: 2px;
+    cursor: pointer;
 }
+
 .user_status_main {
-	width:18px;
-	display:inline;
-	float:left;
+    width: 18px;
+    display: inline;
+    float: left;
 }
+
 .chatbox {
-	position: fixed;
-	position:expression("absolute");
-	width: 320px;
-	display:none;
-	z-index: 9000;
+    position: fixed;
+    position: expression("absolute");
+    width: 320px;
+    display: none;
+    z-index: 9000;
+}
+
+.chatbox-common {
+    word-wrap: break-word;
 }
 
 .chatboxmessage_me {
     background-color: #4080ff;
     color: #fff;
     width: 80%;
-    float:right !important;
+    float: right !important;
     border-radius: 12px;
 }
 
 .chatboxmessage {
     background-color: #ebedf2;
     color: #2a2f35;
-	margin-left:1em;
+    margin-left: 1em;
     width: 80%;
-    float:left;
+    float: left;
     border-radius: 12px;
 }
 
 .chatboxmessagecontent {
 }
 
+.chatboxmessage_me .chatboxmessagecontent a {
+    color: #ffffff;
+}
+
 .chatboxcontent {
-	font-family: arial,sans-serif;
-	font-size: 13px;
-	color: #333333;
-	height:200px;
-	overflow-y:auto;
-	overflow-x:auto;
-	padding:7px;
-	border-left:1px solid #cccccc;
-	border-right:1px solid #cccccc;
-	border-bottom:1px solid #eeeeee;
-	background-color: #ffffff;
-	line-height: 1.3em;
+    font-family: arial, sans-serif;
+    font-size: 13px;
+    color: #333333;
+    max-height: 200px;
+    overflow-y: auto;
+    overflow-x: auto;
+    padding: 7px;
+    border-left: 1px solid #cccccc;
+    border-right: 1px solid #cccccc;
+    border-bottom: 1px solid #eeeeee;
+    background-color: #ffffff;
+    line-height: 1.3em;
+}
+
+.chatboxcontent .alert {
+    margin-bottom: 0;
 }
 
 .user_status {
-	width:8px;
-	display:inline-block;
-  margin-right: 5px;
+    width: 8px;
+    display: inline-block;
+    margin-right: 5px;
 }
+
 .chatimage {
-  display: inline-block;
-  margin-right: 5px;
+    display: inline-block;
+    margin-right: 5px;
 }
 
 .chatboxtitle {
-	font-weight: normal;
-	display: inline-block;
-	font-size: 10px;
-	width: auto;
-	cursor:pointer;
-	overflow: hidden;
-	padding-left: 2px;
-	text-overflow: ellipsis;
-	white-space: nowrap;
-	line-height: 10px;
+    font-weight: normal;
+    display: inline-block;
+    font-size: 10px;
+    width: auto;
+    cursor: pointer;
+    overflow: hidden;
+    padding-left: 2px;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    line-height: 10px;
 }
 
 .chatboxhead {
-	/* background-color: #222; */
-	padding: 5px;
-	color: #ffffff;
-	border-right:1px solid #222;
-	border-left:1px solid #222;
-	background-color: #222;
-	background-repeat: repeat-x;
-	background-image: -khtml-gradient(linear, left top, left bottom, from(#333333), to(#222222));
-	background-image: -moz-linear-gradient(top, #333333, #222222);
-	background-image: -ms-linear-gradient(top, #333333, #222222);
-	background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #333333), color-stop(100%, #222222));
-	background-image: -webkit-linear-gradient(top, #333333, #222222);
-	background-image: -o-linear-gradient(top, #333333, #222222);
-	background-image: linear-gradient(top, #333333, #222222);
-	filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0);
-	-webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
-	-moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
-	box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
+    /* background-color: #222; */
+    padding: 5px;
+    color: #ffffff;
+    border-right: 1px solid #222;
+    border-left: 1px solid #222;
+    background-color: #222;
+    background-repeat: repeat-x;
+    background-image: -khtml-gradient(linear, left top, left bottom, from(#333333), to(#222222));
+    background-image: -moz-linear-gradient(top, #333333, #222222);
+    background-image: -ms-linear-gradient(top, #333333, #222222);
+    background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #333333), color-stop(100%, #222222));
+    background-image: -webkit-linear-gradient(top, #333333, #222222);
+    background-image: -o-linear-gradient(top, #333333, #222222);
+    background-image: linear-gradient(top, #333333, #222222);
+    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0);
+    -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
+    -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
+    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
 }
 
 .chatboxblink {
-	background-color: #FF921F;
-	border-right:1px solid #EF7A00;
-	border-left:1px solid #EF7A00;
+    background-color: #FF921F;
+    border-right: 1px solid #EF7A00;
+    border-left: 1px solid #EF7A00;
     background-repeat: repeat-x;
-	background-image: -khtml-gradient(linear, left top, left bottom, from(#FF921F), to(#FF921F));
-	background-image: -moz-linear-gradient(top, #FF921F, #FFAC55);
-	background-image: -ms-linear-gradient(top, #FF921F, #FF921F);
-	background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #FF921F), color-stop(100%, #FF921F));
-	background-image: -webkit-linear-gradient(top, #FF921F, #FF921F);
-	background-image: -o-linear-gradient(top, #FF921F, #FF921F);
-	background-image: linear-gradient(top, #FF921F, #FF921F);
+    background-image: -khtml-gradient(linear, left top, left bottom, from(#FF921F), to(#FF921F));
+    background-image: -moz-linear-gradient(top, #FF921F, #FFAC55);
+    background-image: -ms-linear-gradient(top, #FF921F, #FF921F);
+    background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #FF921F), color-stop(100%, #FF921F));
+    background-image: -webkit-linear-gradient(top, #FF921F, #FF921F);
+    background-image: -o-linear-gradient(top, #FF921F, #FF921F);
+    background-image: linear-gradient(top, #FF921F, #FF921F);
 }
 
 .chatboxinput {
-	padding: 5px;
-	background-color: #ffffff;
-	border-left:1px solid #cccccc;
-	border-right:1px solid #cccccc;
-	border-bottom:1px solid #cccccc;
+    padding: 5px;
+    background-color: #ffffff;
+    border-left: 1px solid #cccccc;
+    border-right: 1px solid #cccccc;
+    border-bottom: 1px solid #cccccc;
 }
 
 .chatboxtextarea {
-	width: 300px;
-	height:44px;
-	padding:3px 0pt 3px 3px;
-	border: 1px solid #eeeeee;
-	margin: 1px;
-	overflow:hidden;
+    width: 300px;
+    height: 44px;
+    padding: 3px 0pt 3px 3px;
+    border: 1px solid #eeeeee;
+    margin: 1px;
+    overflow: hidden;
 }
 
 .chatboxtextareaselected {
-	border: 2px solid #f99d39;
-	margin:0;
+    border: 2px solid #f99d39;
+    margin: 0;
 }
+
 .chatboxinfo {
-	margin-left:-1em;
-	color:#666666;
+    margin-left: -1em;
+    color: #666666;
 }
 
 .chatboxmessagefrom {
-	margin-left:-1em;
-	font-weight: bold;
+    margin-left: -1em;
+    font-weight: bold;
 }
 
 .chatboxoptions {
-	float: right;
+    float: right;
 }
 
 .chatboxoptions a {
-	text-decoration: none;
-	color: white;
-	font-weight:bold;
-	font-family:Verdana,Arial,"Bitstream Vera Sans",sans-serif;
+    text-decoration: none;
+    color: white;
+    font-weight: bold;
+    font-family: Verdana, Arial, "Bitstream Vera Sans", sans-serif;
 }
 
 .chatboxoptions a:hover {
-	background-color: #aaa;
+    background-color: #aaa;
 }
 
 .chatbox_checks {
-	float:right;
+    float: right;
 }
 
 .chatbox_checked {
-	color: #13A7F0;
+    color: #13A7F0;
 }

+ 12 - 26
main/inc/lib/javascript/chat/js/chat.js

@@ -165,7 +165,6 @@ function startChatSession()
 										window_user_info.avatar_small
 									);
 								}
-
 								createChatBubble(my_user_id, item);
 							}
 						});
@@ -279,7 +278,6 @@ function chatHeartbeat()
 						newMessagesWin[my_user_id]= {'status':true, 'username':item.username};
 
 						var chatBubble = createChatBubble(my_user_id, item);
-						//$("#chatbox_"+my_user_id+" .chatboxcontent").append(chatBubble);
 
 						$("#chatbox_"+my_user_id+" .chatboxcontent").scrollTop(
 							$("#chatbox_"+my_user_id+" .chatboxcontent")[0].scrollHeight
@@ -338,18 +336,22 @@ function createChatBubble(my_user_id, item, appendType = 'append')
 
 	var messageObject = $("#chatbox_"+my_user_id+" .chatboxcontent").find('#message_id_' + item.id);
 	var exists = messageObject.length !== 0;
-	var messageHeader = '<div id="message_id_'+item.id+'" class="chatbox-common boot-tooltip well '+myDiv+'" title="'+sentDate+'" >';
+	var messageHeader = '<div id="message_id_'+item.id+'" class="chatbox-common well '+myDiv+'" title="'+sentDate+'" >';
 	var messageEnd = '</div>';
 
 	var message = '';
 	if (my_user_id == item.from_user_info.id) {
 		message += '<span class="chatboxmessagefrom">'+item.from_user_info.complete_name+':&nbsp;&nbsp;</span>';
 	}
+
 	message += '<div class="chatboxmessagecontent">'+item.message+'</div>';
 	message += '<div class="chatbox_checks' + unCheckClass + '">'+check+'</div>';
 
 	if (exists) {
 		messageObject.html(message);
+		$(messageObject).linkify({
+			target: "_blank"
+		});
 	} else {
 		message = messageHeader + message + messageEnd;
 		if (appendType == 'append') {
@@ -358,6 +360,9 @@ function createChatBubble(my_user_id, item, appendType = 'append')
 			$("#chatbox_"+my_user_id+" .chatboxcontent").prepend(message);
 		}
 
+		$("#chatbox_"+my_user_id+" .chatboxcontent").linkify({
+			target: "_blank"
+		});
 	}
 
 	return message;
@@ -369,9 +374,7 @@ function createChatBubble(my_user_id, item, appendType = 'append')
 function closeChat()
 {
 	$.post(
-		ajax_url + "?action=close",
-		{
-		},
+		ajax_url + "?action=close", {},
 		function (data) {
 			// Disconnects from chat
 			set_user_status(0);
@@ -730,7 +733,7 @@ function createChatBox(user_id, chatboxtitle, minimizeChatBox, online, userImage
 
 	$("#chatbox_"+user_id).click(function() {
 		if ($('#chatbox_'+user_id+' .chatboxcontent').css('display') != 'none') {
-			$("#chatbox_"+user_id+" .chatboxtextarea").focus();
+			//$("#chatbox_"+user_id+" .chatboxtextarea").focus();
 		}
 	});
 
@@ -756,36 +759,21 @@ function getMoreItems(userId, scrollType)
 		cache: false,
 		dataType: "json",
 		success: function(items) {
-			console.log(items);
 			items = items.reverse();
 			$.each(items, function(i, item) {
-				console.log(i);
 				if (item) {
 					if ($("#chatbox_"+userId).css('display') == 'none') {
 						$("#chatbox_"+userId).css('display','block');
 						restructureChatBoxes();
 					}
 					var chatBubble = createChatBubble(userId, item, 'prepend');
-					//$("#chatbox_"+userId+" .chatboxcontent").prepend(chatBubble);
-
 					if ($('#chatbox_'+userId+' .chatboxcontent').css('display') == 'none') {
 						$('#chatbox_'+userId+' .chatboxhead').toggleClass('chatboxblink');
 					}
-
-					// When using scroll set the scroll window to the first
-					var scrollValue = 10;
-					if (scrollType === 'last') {
-						// When loading for the first time show the last msg
-						//scrollValue = $("#chatbox_"+userId+" .chatboxcontent").height();
-					}
-
-					/*$("#chatbox_"+userId+" .chatboxcontent").scrollTop(
-						scrollValue
-					);*/
 				}
 			});
 		}
-	}); //ajax
+	});
 }
 
 /**
@@ -847,7 +835,6 @@ function toggleChatBoxGrowth(user_id)
 		Cookies.set('chatbox_minimized', newCookie);
 		$('#chatbox_'+user_id+' .chatboxcontent').css('display','block');
 		$('#chatbox_'+user_id+' .chatboxinput').css('display','block');
-		//$("#chatbox_"+user_id+" .chatboxcontent").scrollTop($("#chatbox_"+user_id+" .chatboxcontent")[0].scrollHeight);
 		$('.togglelink').html('<em class="fa fa-toggle-down"></em>');
 	} else {
 		// hide box
@@ -926,8 +913,7 @@ function checkChatBoxInputKey(event, chatboxtextarea, user_id)
 						message: message,
 						id: messageId
 					};
-					var bubble = createChatBubble(user_id, item);
-					//$("#chatbox_" + user_id + " .chatboxcontent").append(bubble);
+					createChatBubble(user_id, item);
 					$("#chatbox_" + user_id + " .chatboxcontent").scrollTop(
 						$("#chatbox_" + user_id + " .chatboxcontent")[0].scrollHeight
 					);

+ 30 - 13
main/inc/lib/pdf.lib.php

@@ -43,6 +43,7 @@ class PDF
         $params['right'] = isset($params['right']) ? $params['right'] : 15;
         $params['top'] = isset($params['top']) ? $params['top'] : 30;
         $params['bottom'] = isset($params['bottom']) ? $params['bottom'] : 30;
+        $params['margin_footer'] = isset($params['margin_footer']) ? $params['margin_footer'] : 8;
 
         $this->params['filename'] = isset($params['filename']) ? $params['filename'] : api_get_local_time();
         $this->params['pdf_title'] = isset($params['pdf_title']) ? $params['pdf_title'] : '';
@@ -72,6 +73,8 @@ class PDF
             $orientation
         );
 
+        $this->pdf->margin_footer = $params['margin_footer'];
+
         // Default value is 96 set in the mpdf library file config.php
         $value = api_get_configuration_value('pdf_img_dpi');
         if (!empty($value)) {
@@ -83,9 +86,8 @@ class PDF
      * Export the given HTML to PDF, using a global template.
      *
      * @uses \export/table_pdf.tpl
-
      *
-     * @param $content
+     * @param string     $content
      * @param bool|false $saveToFile
      * @param bool|false $returnHtml
      * @param bool       $addDefaultCss (bootstrap/default/base.css)
@@ -147,12 +149,17 @@ class PDF
         $html = $tpl->fetch($tableTemplate);
         $html = api_utf8_encode($html);
 
+        if ($returnHtml) {
+            return $html;
+        }
+
         $css_file = api_get_path(SYS_CSS_PATH).'themes/'.$tpl->theme.'/print.css';
         if (!file_exists($css_file)) {
             $css_file = api_get_path(SYS_CSS_PATH).'print.css';
         }
         $css = file_get_contents($css_file);
-        $html = self::content_to_pdf(
+
+        self::content_to_pdf(
             $html,
             $css,
             $this->params['filename'],
@@ -163,10 +170,6 @@ class PDF
             $returnHtml,
             $addDefaultCss
         );
-
-        if ($returnHtml) {
-            return $html;
-        }
     }
 
     /**
@@ -187,6 +190,7 @@ class PDF
      * @param bool   $print_title     add title
      * @param bool   $complete_style  show header and footer if true
      * @param bool   $addStyle
+     * @param string $mainTitle
      *
      * @return false|null
      */
@@ -196,7 +200,8 @@ class PDF
         $course_code = null,
         $print_title = false,
         $complete_style = true,
-        $addStyle = true
+        $addStyle = true,
+        $mainTitle = ''
     ) {
         if (empty($html_file_array)) {
             return false;
@@ -231,14 +236,13 @@ class PDF
 
         $counter = 1;
         foreach ($html_file_array as $file) {
-            //Add a page break per file
+            // Add a page break per file
             $page_break = '<pagebreak>';
             if ($counter == count($html_file_array)) {
                 $page_break = '';
             }
-            $counter++;
 
-            //if the array provided contained subarrays with 'title' entry,
+            // if the array provided contained subarrays with 'title' entry,
             // then print the title in the PDF
             if (is_array($file) && isset($file['title'])) {
                 $html_title = $file['title'];
@@ -248,14 +252,27 @@ class PDF
                 $html_title = basename($file);
             }
 
+            $counter++;
+
             if (empty($file) && !empty($html_title)) {
-                //this is a chapter, print title & skip the rest
+                // this is a chapter, print title & skip the rest
+                if ($counter === 2 && !empty($mainTitle)) {
+                    $this->pdf->WriteHTML(
+                        '<html><body><h2 style="text-align: center">'.$mainTitle.'</h2></body></html>'
+                    );
+                }
                 if ($print_title) {
                     $this->pdf->WriteHTML(
                         '<html><body><h3>'.$html_title.'</h3></body></html>'.$page_break
                     );
                 }
                 continue;
+            } else {
+                if ($counter === 2 && !empty($mainTitle)) {
+                    $this->pdf->WriteHTML(
+                        '<html><body><h2 style="text-align: center">'.$mainTitle.'</h2></body></html>'
+                    );
+                }
             }
 
             if (!file_exists($file)) {
@@ -382,7 +399,7 @@ class PDF
             return false;
         }
 
-        //clean styles and javascript document
+        // clean styles and javascript document
         $clean_search = [
             '@<script[^>]*?>.*?</script>@si',
             '@<style[^>]*?>.*?</style>@siU',

+ 19 - 13
main/inc/lib/template.lib.php

@@ -706,18 +706,6 @@ class Template
             'chosen/chosen.jquery.min.js',
         ];
 
-        $viewBySession = api_get_setting('my_courses_view_by_session') === 'true';
-
-        if (api_is_global_chat_enabled() || $viewBySession) {
-            // Do not include the global chat in LP
-            if ($this->show_learnpath == false &&
-                $this->show_footer == true &&
-                $this->hide_global_chat == false
-            ) {
-                $js_files[] = 'chat/js/chat.js';
-            }
-        }
-
         if (api_get_setting('accessibility_font_resize') === 'true') {
             $js_files[] = 'fontresize.js';
         }
@@ -745,6 +733,20 @@ class Template
             'js-cookie/src/js.cookie.js',
         ];
 
+        $viewBySession = api_get_setting('my_courses_view_by_session') === 'true';
+
+        if ($viewBySession || api_is_global_chat_enabled()) {
+            // Do not include the global chat in LP
+            if ($this->show_learnpath == false &&
+                $this->show_footer == true &&
+                $this->hide_global_chat == false
+            ) {
+                $js_files[] = 'chat/js/chat.js';
+                $bowerJsFiles[] = 'linkifyjs/linkify.js';
+                $bowerJsFiles[] = 'linkifyjs/linkify-jquery.js';
+            }
+        }
+
         $features = api_get_configuration_value('video_features');
         if (!empty($features) && isset($features['features'])) {
             foreach ($features['features'] as $feature) {
@@ -838,10 +840,13 @@ class Template
     {
         global $disable_js_and_css_files;
         $js_files = [];
+        $bower = '';
         if (api_is_global_chat_enabled()) {
             //Do not include the global chat in LP
             if ($this->show_learnpath == false && $this->show_footer == true && $this->hide_global_chat == false) {
                 $js_files[] = 'chat/js/chat.js';
+                $bower .= '<script type="text/javascript" src="'.api_get_path(WEB_PUBLIC_PATH).'assets/linkifyjs/linkify.js"></script>';
+                $bower .= '<script type="text/javascript" src="'.api_get_path(WEB_PUBLIC_PATH).'assets/linkifyjs/linkify-jquery.js"></script>';
             }
         }
         $js_file_to_string = '';
@@ -849,7 +854,7 @@ class Template
             $js_file_to_string .= api_get_js($js_file);
         }
         if (!$disable_js_and_css_files) {
-            $this->assign('js_file_to_string_post', $js_file_to_string);
+            $this->assign('js_file_to_string_post', $js_file_to_string.$bower);
         }
     }
 
@@ -1296,6 +1301,7 @@ class Template
             $url = api_get_path(WEB_CODE_PATH).'ticket/tickets.php?project_id='.$defaultProjectId.'&'.$courseParams;
 
             $allow = TicketManager::userIsAllowInProject(api_get_user_info(), $defaultProjectId);
+
             if ($allow) {
                 $rightFloatMenu .= '<div class="help">
                     <a href="'.$url.'" target="_blank">

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini