* Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)\r
* and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.\r
* \r
- * restructured from rabzuarus (https://friendica.kommune4.de/profile/rabuzarus)\r
- * for the decental social network Friendica.\r
+ * Restructured from Rabzuarus (https://friendica.kommune4.de/profile/rabuzarus)\r
+ * to use it for the decental social network Friendica (https://friendi.ca).\r
* \r
* Version: 1.4.0\r
*/\r
var defaultTitle = opts.defaultTitle;\r
var defaultDescription = opts.defaultDescription;\r
\r
+ /**\r
+ * Initialize the plugin\r
+ * \r
+ * @returns {void}\r
+ */\r
var init = function() {\r
$('#' + selector).bind({\r
paste: function () {\r
}\r
}\r
});\r
+\r
+ // Check if we have already attachment bbcode in the textarea\r
+ // and add it to the attachment preview.\r
+ var content = $('#' + selector).val();\r
+ addBBCodeToPreview(content);\r
};\r
+\r
+ /**\r
+ * Reset some values.\r
+ * \r
+ * @returns {void}\r
+ */\r
var resetPreview = function() {\r
$('#hasAttachment_' + selector).val(0);\r
photoNumber = 0;\r
images = "";\r
- }\r
+ };\r
\r
+ /**\r
+ * Crawl a text string if it contains an url and try\r
+ * to attach it.\r
+ * \r
+ * If no text is passed to crawlText() we take\r
+ * the previous word before the cursor of the textarea.\r
+ * \r
+ * @param {string} text (optional)\r
+ * @returns {void}\r
+ */\r
var crawlText = function (text) {\r
block = false;\r
images = '';\r
isExtern = false;\r
\r
+ // If no text is passed to crawlText() we \r
+ // take the previous word before the cursor.\r
if (typeof text === 'undefined') {\r
text = getPrevWord(selector);\r
} else {\r
}\r
};\r
\r
+ /**\r
+ * Process the attachment data according to\r
+ * its content type (image, audio, video, attachment)\r
+ * \r
+ * @param {object} result\r
+ * @returns {void}\r
+ */\r
var processContentData = function(result) {\r
if (result.contentType === 'image') {\r
insertImage(result.data);\r
}\r
+ if (result.contentType === 'audio') {\r
+ insertAudio(result.data);\r
+ }\r
+ if (result.contentType === 'video') {\r
+ insertVideo(result.data);\r
+ }\r
if (result.contentType === 'attachment') {\r
insertAttachment(result.data);\r
}\r
$('#profile-rotator').hide();\r
- }\r
+ };\r
\r
+ /**\r
+ * Fetch the content of link which should be attached.\r
+ * \r
+ * @param {string} binurl Link which should be attached as hexadecimal string.\r
+ * @param {type} callback\r
+ * @returns {void}\r
+ */\r
var getContentData = function(binurl, callback) {\r
$.get('parse_url?binurl='+ binurl + '&dataType=json', function (answer) {\r
- if (typeof answer.contentType === 'undefined'\r
- || answer.contentType === null)\r
- {\r
- answer.contentType = "";\r
- }\r
- if (typeof answer.data.url === 'undefined'\r
- || answer.data.url === null)\r
- {\r
- answer.data.url = "";\r
- }\r
- if (typeof answer.data.title === 'undefined'\r
- || answer.data.title === null\r
- || answer.data.title === "")\r
- {\r
- answer.data.title = defaultTitle;\r
- }\r
- if (typeof answer.data.text === 'undefined'\r
- || answer.data.text === null\r
- || answer.data.text === "")\r
- {\r
- answer.data.text = "";\r
- }\r
- if (typeof answer.data.images === 'undefined'\r
- || answer.data.images === null)\r
- {\r
- answer.data.images = "";\r
- }\r
+ obj = sanitizeInputData(answer);\r
\r
// Put the data into a cache\r
- cache[binurl] = answer;\r
+ cache[binurl] = obj;\r
\r
- callback(answer);\r
+ callback(obj);\r
\r
isCrawling = false;\r
});\r
- }\r
+ };\r
\r
- var insertImage = function(json) {\r
+ /*\r
+ * Add a [img] bbtag with the image url to the jot editor.\r
+ * \r
+ * @param {type} data\r
+ * @returns {void}\r
+ */\r
+ var insertImage = function(data) {\r
if (!isExtern) {\r
- return\r
+ return;\r
}\r
- var bbcode = '\n[img]' + json.url + '[/img]\n';\r
+ var bbcode = '\n[img]' + data.url + '[/img]\n';\r
addeditortext(bbcode);\r
};\r
\r
- var insertAudio = function(json) {\r
+ /*\r
+ * Add a [audio] bbtag with the audio url to the jot editor.\r
+ * \r
+ * @param {type} data\r
+ * @returns {void}\r
+ */\r
+ var insertAudio = function(data) {\r
if (!isExtern) {\r
- return\r
+ return;\r
}\r
- var bbcode = '\n[audio]' + json.url + '[/audio]\n';\r
+ var bbcode = '\n[audio]' + data.url + '[/audio]\n';\r
addeditortext(bbcode);\r
};\r
\r
- var insertVideo = function(json) {\r
+ /*\r
+ * Add a [video] bbtag with the video url to the jot editor.\r
+ * \r
+ * @param {type} data\r
+ * @returns {void}\r
+ */\r
+ var insertVideo = function(data) {\r
if (!isExtern) {\r
- return\r
+ return;\r
}\r
var bbcode = '\n[video]' + json.url + '[/video]\n';\r
addeditortext(bbcode);\r
};\r
\r
- var insertAttachment = function(json) {\r
+ /**\r
+ * Proccess all attachment data and show up a html\r
+ * attachment preview.\r
+ * \r
+ * @param {obj} data Attachment data.\r
+ * @returns {void}\r
+ */\r
+ var insertAttachment = function(data) {\r
// If we have already a preview, leaver here.\r
// Note: if we finish the Preview of other media content type,\r
// we can move this condition to the beggining of crawlText();\r
return;\r
}\r
\r
- if (json.type != 'link' && json.type != 'video' && json.type != 'photo' || json.url == json.title) {\r
+ if (data.type !== 'link' && data.type !== 'video' && data.type !== 'photo' || data.url === data.title) {\r
$('#profile-rotator').hide();\r
return;\r
}\r
$('#photoNumber_' + selector).val(0);\r
resetPreview();\r
\r
- var typeClass = 'type-' + json.type;\r
- var imageClass = 'attachment-preview';\r
- var urlHost = "";\r
- var description = json.text;\r
+ processAttachmentTpl(data, 'type-' + data.type);\r
+ addTitleDescription(data);\r
+ addHostToAttachment(data.url);\r
+ addImagesToAttachment(data.images);\r
+\r
+ processEventListener();\r
+ $('#profile-rotator').hide();\r
+ };\r
\r
+ /**\r
+ * Construct the attachment html from the attachment template and\r
+ * add it to the DOM.\r
+ * \r
+ * @param {object} data Attachment data.\r
+ * @returns {void}\r
+ */\r
+ var processAttachmentTpl = function(data) {\r
// Load and add the template if it isn't allready loaded.\r
- if ($('#preview_' + selector).length == 0) {\r
+ if ($('#preview_' + selector).length === 0) {\r
var tpl = previewTpl.format(\r
- typeClass,\r
+ 'type-' + data.type,\r
attachmentTpl,\r
1,\r
- bin2hex(json.url),\r
- json.type\r
+ bin2hex(data.url),\r
+ data.type\r
);\r
$('#' + selector).after(tpl);\r
}\r
\r
isActive = true;\r
+ };\r
+\r
+ /**\r
+ * Add the attachment title and the description\r
+ * to the attachment preview.\r
+ * \r
+ * @param {object} data Attachment data.\r
+ * @returns {void}\r
+ */\r
+ var addTitleDescription = function(data) {\r
+ var description = data.text;\r
\r
if (description === '') {\r
description = defaultDescription;\r
}\r
\r
$('#previewTitle_' + selector).html("\\r
- <span id='previewSpanTitle_" + selector + "' class='previewSpanTitle' >" + escapeHTML(json.title) + "</span>\\r
- <input type='text' name='attachment_title' value='" + escapeHTML(json.title) + "' id='previewInputTitle_" + selector + "' class='previewInputTitle inputPreview' style='display: none;'/>"\r
+ <span id='previewSpanTitle_" + selector + "' class='previewSpanTitle' >" + escapeHTML(data.title) + "</span>\\r
+ <input type='text' name='attachment_title' value='" + escapeHTML(data.title) + "' id='previewInputTitle_" + selector + "' class='previewInputTitle inputPreview' style='display: none;'/>"\r
);\r
\r
$('#previewDescription_' + selector).html("\\r
<span id='previewSpanDescription_" + selector + "' class='previewSpanDescription' >" + escapeHTML(description) + "</span>\n\\r
- <textarea id='previewInputDescription_" + selector + "' name='attachment_text' class='previewInputDescription' style='display: none;' class='inputPreview' >" + escapeHTML(json.text) + "</textarea>"\r
+ <textarea id='previewInputDescription_" + selector + "' name='attachment_text' class='previewInputDescription' style='display: none;' class='inputPreview' >" + escapeHTML(data.text) + "</textarea>"\r
);\r
+ };\r
\r
- if (json.url) {\r
+ /**\r
+ * Add the host to the attachment preview.\r
+ * \r
+ * @param {string} url The url of the link attachment.\r
+ * @returns {void}\r
+ */\r
+ var addHostToAttachment = function(url) {\r
+ if (url) {\r
var regexpr = "(https?://)([^:^/]*)(:\\d*)?(.*)?";\r
- var regResult = json.url.match(regexpr);\r
+ var regResult = url.match(regexpr);\r
var urlHost = regResult[1] + regResult[2];\r
- $('#previewUrl_' + selector).html("<a href='" + json.url + "'>" + urlHost + "</a>");\r
+ $('#previewUrl_' + selector).html("<a href='" + url + "'>" + urlHost + "</a>");\r
}\r
+ };\r
\r
- images = json.images;\r
-\r
+ /**\r
+ * Add preview images to the attachment.\r
+ * \r
+ * @param {array} images\r
+ * \r
+ * @returns {void}\r
+ */\r
+ var addImagesToAttachment = function(images) {\r
+ var imageClass = 'attachment-preview';\r
+ \r
if (Array.isArray(images)) {\r
$('#previewImages_' + selector).show();\r
$('#attachmentImageSrc_' + selector).val(bin2hex(images[photoNumber].src));\r
\r
for (i = 0; i < images.length; i++) {\r
// For small preview images we use a smaller attachment format.\r
-// if (Array.isArray(images) && typeof images[i].width !== 'undefined') {\r
- ///@todo here we need to add a check for !Config::get('system', 'always_show_preview').\r
- if (images[i].width >= 500 && images[i].width >= images[i].height) {\r
- imageClass = 'attachment-image';\r
- }\r
-// }\r
+ ///@todo here we need to add a check for !Config::get('system', 'always_show_preview').\r
+ if (images[i].width >= 500 && images[i].width >= images[i].height) {\r
+ imageClass = 'attachment-image';\r
+ }\r
+\r
if (i === 0) {\r
appendImage += "<img id='imagePreview_" + selector + "_" + i + "' src='" + images[i].src + "' class='" + imageClass + "' ></img>";\r
} else {\r
});\r
}\r
}\r
-\r
- processEventListener();\r
- $('#profile-rotator').hide();\r
};\r
\r
+ /**\r
+ * Add event listener to control the attachment preview.\r
+ * \r
+ * @returns {void}\r
+ */\r
var processEventListener = function() {\r
$('#previewSpanTitle_' + selector).unbind('click').click(function (e) {\r
e.stopPropagation();\r
$('#preview_' + selector).fadeOut("fast", function () {\r
$('#preview_' + selector).remove();\r
$('#profile-rotator').hide();\r
+ $('#' + selector).focus();\r
});\r
\r
});\r
};\r
\r
+ /**\r
+ * Convert attachmant bbcode into an array.\r
+ * \r
+ * @param {string} content Text content with the attachment bbcode.\r
+ * @returns {object || null}\r
+ */\r
+ var getAttachmentData = function(content) {\r
+ var data = {};\r
+\r
+ var match = content.match(/(.*)\[attachment(.*?)\](.*?)\[\/attachment\](.*)/ism);\r
+ if (match === null || match.length < 5) {\r
+ return null;\r
+ }\r
+\r
+ var attributes = match[2];\r
+ data.text = trim(match[1]);\r
+\r
+ var type = '';\r
+ var matches = attributes.match(/type='(.*?)'/ism);\r
+ if (matches !== null && typeof matches[1] !== 'undefined') {\r
+ type = matches[1].toLowerCase();\r
+ }\r
+\r
+ matches = attributes.match(/type="(.*?)"/ism);\r
+ if (matches !== null && typeof matches[1] !== 'undefined') {\r
+ type = matches[1].toLowerCase();\r
+ }\r
+\r
+ if (type === '') {\r
+ return null;\r
+ }\r
+\r
+ if (\r
+ type !== 'link'\r
+ && type !== 'audio'\r
+ && type !== 'photo'\r
+ && type !== 'video')\r
+ {\r
+ return null;\r
+ }\r
+\r
+ if (type !== '') {\r
+ data.type = type;\r
+ }\r
+\r
+ var url = '';\r
+\r
+ matches = attributes.match(/url='(.*?)'/ism);\r
+ if (matches !== null && typeof matches[1] !== 'undefined') {\r
+ url = matches[1].toLowerCase();\r
+ }\r
+\r
+ matches = attributes.match(/url="(.*?)"/ism);\r
+ if (matches !== null && typeof matches[1] !== 'undefined') {\r
+ url = matches[1].toLowerCase();\r
+ }\r
+\r
+ if(url !== '') {\r
+ data.url = escapeHTML(url);\r
+ }\r
+\r
+ var title = '';\r
+\r
+ matches = attributes.match(/title='(.*?)'/ism);\r
+ if (matches !== null && typeof matches[1] !== 'undefined') {\r
+ title = matches[1].toLowerCase();\r
+ }\r
+\r
+ matches = attributes.match(/title="(.*?)"/ism);\r
+ if (matches !== null && typeof matches[1] !== 'undefined') {\r
+ title = matches[1].toLowerCase();\r
+ }\r
+\r
+ if (title !== '') {\r
+ data.title = escapeHTML(title);\r
+ }\r
+\r
+ var image = '';\r
+\r
+ matches = attributes.match(/image='(.*?)'/ism);\r
+ if (matches !== null && typeof matches[1] !== 'undefined') {\r
+ image = matches[1].toLowerCase();\r
+ }\r
+\r
+ matches = attributes.match(/image="(.*?)"/ism);\r
+ if (matches !== null && typeof matches[1] !== 'undefined') {\r
+ image = matches[1].toLowerCase();\r
+ }\r
+\r
+ if (image !== '') {\r
+ data.image = escapeHTML(image);\r
+ }\r
+\r
+ var preview = '';\r
+\r
+ matches = attributes.match(/preview='(.*?)'/ism);\r
+ if (matches !== null && typeof matches[1] !== 'undefined') {\r
+ preview = matches[1].toLowerCase();\r
+ }\r
+\r
+ matches = attributes.match(/preview="(.*?)"/ism);\r
+ if (matches !== null && typeof matches[1] !== 'undefined') {\r
+ preview = matches[1].toLowerCase();\r
+ }\r
+\r
+ if (preview !== '') {\r
+ data.preview = escapeHTML(preview);\r
+ }\r
+\r
+ data.text = trim(match[3]);\r
+ data.after = trim(match[4]);\r
+\r
+ return data;\r
+ };\r
+\r
+ /**\r
+ * Process txt content and if it contains attachment bbcode\r
+ * add it to the attachment preview .\r
+ * \r
+ * @param {string} content\r
+ * @returns {void}\r
+ */\r
+ var addBBCodeToPreview =function(content) {\r
+ var attachmentData = getAttachmentData(content);\r
+ if (attachmentData) {\r
+ reAddAttachment(attachmentData);\r
+ // Remove the attachment bbcode from the textarea.\r
+ var content = content.replace(/\[attachment.*\[\/attachment]/ism, '');\r
+ $('#' + selector).val(content);\r
+ $('#' + selector).focus();\r
+ }\r
+ };\r
+\r
+ /**\r
+ * Add an Attachment with data from an old bbcode\r
+ * generated attachment.\r
+ * \r
+ * @param {object} json The attachment data.\r
+ * @returns {void}\r
+ */\r
+ var reAddAttachment = function(json) {\r
+ if (isActive) {\r
+ $('#profile-rotator').hide();\r
+ return;\r
+ }\r
+\r
+ if (json.type !== 'link' && json.type !== 'video' && json.type !== 'photo' || json.url === json.title) {\r
+ $('#profile-rotator').hide();\r
+ return;\r
+ }\r
+\r
+ var obj = {data: json};\r
+ obj = sanitizeInputData(obj);\r
+\r
+ var data = obj.data;\r
+\r
+ resetPreview();\r
+\r
+ processAttachmentTpl(data);\r
+ addTitleDescription(data);\r
+ addHostToAttachment(data.url);\r
+\r
+ // Since we don't have an array of image data,\r
+ // we need to add the preview images in a different way\r
+ // than in function addImagesToAttachment().\r
+ var imageClass = 'attachment-preview';\r
+ var image = '';\r
+\r
+ if (data.image !== '') {\r
+ imageClass = 'attachment-image';\r
+ image = data.image;\r
+ } else {\r
+ image = data.preview;\r
+ }\r
+\r
+ if (image !== '') {\r
+ var appendImage = "<img id='imagePreview_" + selector + "' src='" + image + "' class='" + imageClass + "' ></img>"\r
+ $('#previewImage_' + selector).html(appendImage);\r
+ $('#attachmentImageSrc_' + selector).val(bin2hex(image));\r
+\r
+ // We need to add the image widht and height when it is \r
+ // loaded.\r
+ $('<img/>' ,{\r
+ load : function(){\r
+ $('#attachmentImageWidth_' + selector).val(this.width);\r
+ $('#attachmentImageHeight_' + selector).val(this.height);\r
+ },\r
+ src : image\r
+ });\r
+ }\r
+\r
+ processEventListener();\r
+ $('#profile-rotator').hide();\r
+ };\r
+\r
+ /**\r
+ * Add missing default properties to the input data object.\r
+ * \r
+ * @param {object} obj Input data.\r
+ * @returns {object}\r
+ */\r
+ var sanitizeInputData = function(obj) {\r
+ if (typeof obj.contentType === 'undefined'\r
+ || obj.contentType === null)\r
+ {\r
+ obj.contentType = "";\r
+ }\r
+ if (typeof obj.data.url === 'undefined'\r
+ || obj.data.url === null)\r
+ {\r
+ obj.data.url = "";\r
+ }\r
+ if (typeof obj.data.title === 'undefined'\r
+ || obj.data.title === null\r
+ || obj.data.title === "")\r
+ {\r
+ obj.data.title = defaultTitle;\r
+ }\r
+ if (typeof obj.data.text === 'undefined'\r
+ || obj.data.text === null\r
+ || obj.data.text === "")\r
+ {\r
+ obj.data.text = "";\r
+ }\r
+ if (typeof obj.data.images === 'undefined'\r
+ || obj.data.images === null)\r
+ {\r
+ obj.data.images = "";\r
+ }\r
+\r
+ if (typeof obj.data.image === 'undefined'\r
+ || obj.data.image === null)\r
+ {\r
+ obj.data.image = "";\r
+ }\r
+\r
+ if (typeof obj.data.preview === 'undefined'\r
+ || obj.data.preview === null)\r
+ {\r
+ obj.data.preview = "";\r
+ }\r
+\r
+ return obj;\r
+ };\r
+\r
+ /**\r
+ * Destroy the plugin.\r
+ * \r
+ * @returns {void}\r
+ */\r
var destroy = function() {\r
$('#' + selector).unbind();\r
$('#preview_' + selector).remove();\r
.replace(/\[/g, '[')\r
.replace(/\]/g, ']')\r
.replace(/\'/g, '''); // ''' is not valid HTML 4\r
- }\r
+ };\r
\r
// Initialize LinkPreview \r
init();\r
crawlText: function(text) {\r
crawlText(text);\r
},\r
+ addBBCodeToPreview: function(content) {\r
+ addBBCodeToPreview(content);\r
+ },\r
destroy: function() {\r
destroy();\r
}\r