2019-02-12 10:29:50 +00:00
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt Expat
2019-02-12 12:59:33 +00:00
// @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL
2019-02-12 10:29:50 +00:00
/ * *
2024-08-24 12:15:18 +00:00
* SPDX - FileCopyrightText : 2014 Leonardo Cardoso ( http : //leocardz.com), Rabuzarus to use it in the decentralized social network Friendica (https://friendi.ca).
*
2024-08-25 06:45:08 +00:00
* SPDX - License - Identifier : MIT OR GPL - 2.0 - only
2024-08-24 12:15:18 +00:00
*
2019-02-12 10:29:50 +00:00
* Dual licensed under the MIT ( http : //www.opensource.org/licenses/mit-license.php)
* and GPL ( http : //www.opensource.org/licenses/gpl-license.php) licenses.
*
* Restructured by Rabzuarus ( https : //friendica.kommune4.de/profile/rabuzarus)
* to use it in the decentralized social network Friendica ( https : //friendi.ca).
*
* Version : 1.4 . 0
* /
( function ( $ ) {
$ . fn . linkPreview = function ( options ) {
var opts = jQuery . extend ( { } , $ . fn . linkPreview . defaults , options ) ;
2019-11-28 17:48:59 +00:00
var id = $ ( this ) . attr ( 'id' ) ;
2019-02-12 10:29:50 +00:00
var previewTpl = ' \
2019-11-28 17:48:59 +00:00
< div id = "preview_' + id + '" class = "preview {0}" > \
2019-02-12 10:29:50 +00:00
{ 1 } \
2019-11-28 17:48:59 +00:00
< input type = "hidden" name = "has_attachment" id = "hasAttachment_' + id + '" value = "{2}" / > \
< input type = "hidden" name = "attachment_url" id = "attachmentUrl_' + id + '" value = "{3}" / > \
< input type = "hidden" name = "attachment_type" id = "attachmentType_' + id + '" value = "{4}" / > \
2019-02-12 10:29:50 +00:00
< / d i v > ' ;
var attachmentTpl = ' \
< hr class = "previewseparator" > \
2019-11-28 17:48:59 +00:00
< div id = "closePreview_' + id + '" title = "Remove" class = "closePreview" > \
2019-02-12 10:29:50 +00:00
< button type = "button" class = "previewActionBtn" > × < / b u t t o n > \
< / d i v > \
2019-11-28 17:48:59 +00:00
< div id = "previewImages_' + id + '" class = "previewImages" > \
< div id = "previewImgBtn_' + id + '" class = "previewImgBtn" > \
2023-03-26 22:08:34 +00:00
< button type = "button" id = "previewChangeImg_' + id + '" class = "buttonChangeDeactivate previewActionBtn" style = "display: none" > \
2019-02-12 10:29:50 +00:00
< i class = "fa fa-exchange" aria - hidden = "true" > < / i > \
< / b u t t o n > \
< / d i v > \
2019-11-28 17:48:59 +00:00
< div id = "previewImage_' + id + '" class = "previewImage" > \
2019-02-12 10:29:50 +00:00
< / d i v > \
2019-11-28 17:48:59 +00:00
< input type = "hidden" id = "photoNumber_' + id + '" class = "photoNumber" value = "0" / > \
< input type = "hidden" name = "attachment_img_src" id = "attachmentImageSrc_' + id + '" value = "" / > \
< input type = "hidden" name = "attachment_img_width" id = "attachmentImageWidth_' + id + '" value = "0" / > \
< input type = "hidden" name = "attachment_img_height" id = "attachmentImageHeight_' + id + '" value = "0" / > \
2019-02-12 10:29:50 +00:00
< / d i v > \
2019-11-28 17:48:59 +00:00
< div id = "previewContent_' + id + '" class = "previewContent" > \
< h4 id = "previewTitle_' + id + '" class = "previewTitle" > < / h 4 > \
< blockquote id = "previewDescription_' + id + '" class = "previewDescription" > < / b l o c k q u o t e > \
< div id = "hiddenDescription_' + id + '" class = "hiddenDescription" > < / d i v > \
< sup id = "previewUrl_' + id + '" class = "previewUrl" > < / s u p > \
2019-02-12 10:29:50 +00:00
< / d i v > \
< div class = "clear" > < / d i v > \
< hr class = "previewseparator" > ' ;
var text ;
var binurl ;
var block = false ;
var blockTitle = false ;
var blockDescription = false ;
var cache = { } ;
var images = "" ;
var isExtern = false ;
var photoNumber = 0 ;
var firstPosted = false ;
var isActive = false ;
var isCrawling = false ;
var defaultTitle = opts . defaultTitle ;
var defaultDescription = opts . defaultDescription ;
/ * *
* Initialize the plugin
*
* @ returns { void }
* /
var init = function ( ) {
2019-11-28 17:48:59 +00:00
$ ( '#' + id ) . bind ( {
2019-02-12 10:29:50 +00:00
paste : function ( ) {
setTimeout ( function ( ) {
crawlText ( ) ;
} , 100 ) ;
} ,
keyup : function ( e ) {
// on enter, space, ctrl
if ( ( e . which === 13 || e . which === 32 || e . which === 17 ) ) {
crawlText ( ) ;
}
}
} ) ;
// Check if we have already attachment bbcode in the textarea
// and add it to the attachment preview.
2019-11-28 17:48:59 +00:00
var content = $ ( '#' + id ) . val ( ) ;
2019-02-12 10:29:50 +00:00
addBBCodeToPreview ( content ) ;
} ;
/ * *
* Reset some values .
*
* @ returns { void }
* /
var resetPreview = function ( ) {
2019-11-28 17:48:59 +00:00
$ ( '#hasAttachment_' + id ) . val ( 0 ) ;
2019-02-12 10:29:50 +00:00
photoNumber = 0 ;
images = "" ;
} ;
/ * *
* Crawl a text string if it contains an url and try
* to attach it .
*
* If no text is passed to crawlText ( ) we take
* the previous word before the cursor of the textarea .
*
* @ param { string } text ( optional )
* @ returns { void }
* /
var crawlText = function ( text ) {
block = false ;
images = '' ;
isExtern = false ;
// If no text is passed to crawlText() we
// take the previous word before the cursor.
if ( typeof text === 'undefined' ) {
2019-11-28 17:48:59 +00:00
text = getPrevWord ( id ) ;
2019-02-12 10:29:50 +00:00
} else {
isExtern = true ;
}
2023-03-22 04:08:07 +00:00
// Don't process the textarea input if we have already
2019-02-12 10:29:50 +00:00
// an attachment preview.
if ( ! isExtern && isActive ) {
return ;
}
2019-08-30 01:12:46 +00:00
if ( trim ( text ) !== "" && block === false && urlRegex . test ( text ) ) {
binurl = bin2hex ( text ) ;
block = true ;
2019-02-12 10:29:50 +00:00
2019-08-30 01:12:46 +00:00
isCrawling = true ;
$ ( '#profile-rotator' ) . show ( ) ;
2019-02-12 10:29:50 +00:00
2019-08-30 01:12:46 +00:00
if ( binurl in cache ) {
isCrawling = false ;
processContentData ( cache [ binurl ] ) ;
} else {
getContentData ( binurl , processContentData ) ;
2019-02-12 10:29:50 +00:00
}
}
} ;
/ * *
* Process the attachment data according to
* its content type ( image , audio , video , attachment )
*
* @ param { object } result
* @ returns { void }
* /
var processContentData = function ( result ) {
if ( result . contentType === 'image' ) {
insertImage ( result . data ) ;
}
if ( result . contentType === 'audio' ) {
insertAudio ( result . data ) ;
}
if ( result . contentType === 'video' ) {
insertVideo ( result . data ) ;
}
if ( result . contentType === 'attachment' ) {
insertAttachment ( result . data ) ;
}
$ ( '#profile-rotator' ) . hide ( ) ;
} ;
/ * *
* Fetch the content of link which should be attached .
*
* @ param { string } binurl Link which should be attached as hexadecimal string .
* @ param { type } callback
* @ returns { void }
* /
var getContentData = function ( binurl , callback ) {
2021-02-16 15:20:51 +00:00
$ . get ( 'parseurl?binurl=' + binurl + '&format=json' , function ( answer ) {
2019-02-12 10:29:50 +00:00
obj = sanitizeInputData ( answer ) ;
// Put the data into a cache
cache [ binurl ] = obj ;
callback ( obj ) ;
isCrawling = false ;
} ) ;
} ;
/ *
* Add a [ img ] bbtag with the image url to the jot editor .
*
* @ param { type } data
* @ returns { void }
* /
var insertImage = function ( data ) {
if ( ! isExtern ) {
return ;
}
2024-06-15 12:30:00 +00:00
var bbcode = '\n[img=' + data . url + '][/img]\n' ;
2019-02-12 10:29:50 +00:00
addeditortext ( bbcode ) ;
} ;
/ *
* Add a [ audio ] bbtag with the audio url to the jot editor .
*
* @ param { type } data
* @ returns { void }
* /
var insertAudio = function ( data ) {
if ( ! isExtern ) {
return ;
}
var bbcode = '\n[audio]' + data . url + '[/audio]\n' ;
addeditortext ( bbcode ) ;
} ;
/ *
* Add a [ video ] bbtag with the video url to the jot editor .
*
* @ param { type } data
* @ returns { void }
* /
var insertVideo = function ( data ) {
if ( ! isExtern ) {
return ;
}
2019-04-11 19:37:58 +00:00
var bbcode = '\n[video]' + data . url + '[/video]\n' ;
2019-02-12 10:29:50 +00:00
addeditortext ( bbcode ) ;
} ;
/ * *
2023-03-22 04:08:07 +00:00
* Process all attachment data and show up a html
2019-02-12 10:29:50 +00:00
* attachment preview .
*
* @ param { obj } data Attachment data .
* @ returns { void }
* /
var insertAttachment = function ( data ) {
// If we have already a preview, leaver here.
// Note: if we finish the Preview of other media content type,
2023-03-22 03:16:53 +00:00
// we can move this condition to the beginning of crawlText();
2019-02-12 10:29:50 +00:00
if ( isActive ) {
$ ( '#profile-rotator' ) . hide ( ) ;
return ;
}
if ( data . type !== 'link' && data . type !== 'video' && data . type !== 'photo' || data . url === data . title ) {
$ ( '#profile-rotator' ) . hide ( ) ;
return ;
}
2019-11-28 17:48:59 +00:00
$ ( '#photoNumber_' + id ) . val ( 0 ) ;
2019-02-12 10:29:50 +00:00
resetPreview ( ) ;
processAttachmentTpl ( data , 'type-' + data . type ) ;
addTitleDescription ( data ) ;
addHostToAttachment ( data . url ) ;
addImagesToAttachment ( data . images ) ;
processEventListener ( ) ;
$ ( '#profile-rotator' ) . hide ( ) ;
} ;
/ * *
* Construct the attachment html from the attachment template and
* add it to the DOM .
*
* @ param { object } data Attachment data .
* @ returns { void }
* /
var processAttachmentTpl = function ( data ) {
2023-03-22 03:16:47 +00:00
// Load and add the template if it isn't already loaded.
2019-11-28 17:48:59 +00:00
if ( $ ( '#preview_' + id ) . length === 0 ) {
2019-02-12 10:29:50 +00:00
var tpl = previewTpl . format (
'type-' + data . type ,
attachmentTpl ,
1 ,
bin2hex ( data . url ) ,
data . type
) ;
2019-11-28 17:48:59 +00:00
$ ( '#' + id ) . after ( tpl ) ;
2019-02-12 10:29:50 +00:00
}
isActive = true ;
} ;
/ * *
* Add the attachment title and the description
* to the attachment preview .
*
* @ param { object } data Attachment data .
* @ returns { void }
* /
var addTitleDescription = function ( data ) {
var description = data . text ;
if ( description === '' ) {
description = defaultDescription ;
}
2019-11-28 17:48:59 +00:00
$ ( '#previewTitle_' + id ) . html ( " \
< span id = 'previewSpanTitle_" + id + "' class = 'previewSpanTitle' > " + escapeHTML(data.title) + " < / s p a n > \
< input type = 'text' name = 'attachment_title' value = '" + escapeHTML(data.title) + "' id = 'previewInputTitle_" + id + "' class = 'previewInputTitle inputPreview' style = 'display: none;' / > "
2019-02-12 10:29:50 +00:00
) ;
2019-11-28 17:48:59 +00:00
$ ( '#previewDescription_' + id ) . html ( " \
< span id = 'previewSpanDescription_" + id + "' class = 'previewSpanDescription' > " + escapeHTML(description) + " < / s p a n > \ n \
< textarea id = 'previewInputDescription_" + id + "' name = 'attachment_text' class = 'previewInputDescription' style = 'display: none;' class = 'inputPreview' > " + escapeHTML(data.text) + " < / t e x t a r e a > "
2019-02-12 10:29:50 +00:00
) ;
} ;
/ * *
* Add the host to the attachment preview .
*
* @ param { string } url The url of the link attachment .
* @ returns { void }
* /
var addHostToAttachment = function ( url ) {
if ( url ) {
var regexpr = "(https?://)([^:^/]*)(:\\d*)?(.*)?" ;
var regResult = url . match ( regexpr ) ;
var urlHost = regResult [ 1 ] + regResult [ 2 ] ;
2019-11-28 17:48:59 +00:00
$ ( '#previewUrl_' + id ) . html ( "<a href='" + url + "'>" + urlHost + "</a>" ) ;
2019-02-12 10:29:50 +00:00
}
} ;
/ * *
* Add preview images to the attachment .
*
* @ param { array } images
*
* @ returns { void }
* /
var addImagesToAttachment = function ( images ) {
var imageClass = 'attachment-preview' ;
if ( Array . isArray ( images ) ) {
2019-11-28 17:48:59 +00:00
$ ( '#previewImages_' + id ) . show ( ) ;
$ ( '#attachmentImageSrc_' + id ) . val ( bin2hex ( images [ photoNumber ] . src ) ) ;
$ ( '#attachmentImageWidth_' + id ) . val ( images [ photoNumber ] . width ) ;
$ ( '#attachmentImageHeight_' + id ) . val ( images [ photoNumber ] . height ) ;
2019-02-12 10:29:50 +00:00
} else {
2019-11-28 17:48:59 +00:00
$ ( '#previewImages_' + id ) . hide ( ) ;
2019-02-12 10:29:50 +00:00
}
images . length = parseInt ( images . length ) ;
var appendImage = "" ;
for ( i = 0 ; i < images . length ; i ++ ) {
// For small preview images we use a smaller attachment format.
2020-01-19 20:21:13 +00:00
///@todo here we need to add a check for !DI::config()->get('system', 'always_show_preview').
2019-02-12 10:29:50 +00:00
if ( images [ i ] . width >= 500 && images [ i ] . width >= images [ i ] . height ) {
imageClass = 'attachment-image' ;
}
if ( i === 0 ) {
2019-11-28 17:48:59 +00:00
appendImage += "<img id='imagePreview_" + id + "_" + i + "' src='" + images [ i ] . src + "' class='" + imageClass + "' ></img>" ;
2019-02-12 10:29:50 +00:00
} else {
2019-11-28 17:48:59 +00:00
appendImage += "<img id='imagePreview_" + id + "_" + i + "' src='" + images [ i ] . src + "' class='" + imageClass + "' style='display: none;'></img>" ;
2019-02-12 10:29:50 +00:00
}
}
2019-11-28 17:48:59 +00:00
$ ( '#previewImage_' + id ) . html ( appendImage + "<div id='whiteImage' style='color: transparent; display:none;'>...</div>" ) ;
2019-02-12 10:29:50 +00:00
// More than just one image.
if ( images . length > 1 ) {
2023-03-21 03:13:56 +00:00
// Enable the button to change the preview pictures.
2019-11-28 17:48:59 +00:00
$ ( '#previewChangeImg_' + id ) . show ( ) ;
2019-02-12 10:29:50 +00:00
if ( firstPosted === false ) {
firstPosted = true ;
2019-11-28 17:48:59 +00:00
$ ( '#previewChangeImg_' + id ) . unbind ( 'click' ) . click ( function ( e ) {
2019-02-12 10:29:50 +00:00
e . stopPropagation ( ) ;
if ( images . length > 1 ) {
2019-11-28 17:48:59 +00:00
$ ( '#imagePreview_' + id + '_' + photoNumber ) . css ( {
2019-02-12 10:29:50 +00:00
'display' : 'none'
} ) ;
photoNumber += 1 ;
// If have reached the last image, begin with the first image.
if ( photoNumber === images . length ) {
photoNumber = 0 ;
}
2019-11-28 17:48:59 +00:00
$ ( '#imagePreview_' + id + '_' + photoNumber ) . css ( {
2019-02-12 10:29:50 +00:00
'display' : 'block'
} ) ;
2019-11-28 17:48:59 +00:00
$ ( '#photoNumber_' + id ) . val ( photoNumber ) ;
$ ( '#attachmentImageSrc_' + id ) . val ( bin2hex ( images [ photoNumber ] . src ) ) ;
$ ( '#attachmentImageWidth_' + id ) . val ( images [ photoNumber ] . width ) ;
$ ( '#attachmentImageHeight_' + id ) . val ( images [ photoNumber ] . height ) ;
2019-02-12 10:29:50 +00:00
}
} ) ;
}
}
} ;
/ * *
* Add event listener to control the attachment preview .
*
* @ returns { void }
* /
var processEventListener = function ( ) {
2019-11-28 17:48:59 +00:00
$ ( '#previewSpanTitle_' + id ) . unbind ( 'click' ) . click ( function ( e ) {
2019-02-12 10:29:50 +00:00
e . stopPropagation ( ) ;
if ( blockTitle === false ) {
blockTitle = true ;
2019-11-28 17:48:59 +00:00
$ ( '#previewSpanTitle_' + id ) . hide ( ) ;
$ ( '#previewInputTitle_' + id ) . show ( ) ;
$ ( '#previewInputTitle_' + id ) . val ( $ ( '#previewInputTitle_' + id ) . val ( ) ) ;
$ ( '#previewInputTitle_' + id ) . focus ( ) . select ( ) ;
2019-02-12 10:29:50 +00:00
}
} ) ;
2019-11-28 17:48:59 +00:00
$ ( '#previewInputTitle_' + id ) . blur ( function ( ) {
2019-02-12 10:29:50 +00:00
blockTitle = false ;
2019-11-28 17:48:59 +00:00
$ ( '#previewSpanTitle_' + id ) . html ( $ ( '#previewInputTitle_' + id ) . val ( ) ) ;
$ ( '#previewSpanTitle_' + id ) . show ( ) ;
$ ( '#previewInputTitle_' + id ) . hide ( ) ;
2019-02-12 10:29:50 +00:00
} ) ;
2019-11-28 17:48:59 +00:00
$ ( '#previewInputTitle_' + id ) . keypress ( function ( e ) {
2019-02-12 10:29:50 +00:00
if ( e . which === 13 ) {
blockTitle = false ;
2019-11-28 17:48:59 +00:00
$ ( '#previewSpanTitle_' + id ) . html ( $ ( '#previewInputTitle_' + id ) . val ( ) ) ;
$ ( '#previewSpanTitle_' + id ) . show ( ) ;
$ ( '#previewInputTitle_' + id ) . hide ( ) ;
2019-02-12 10:29:50 +00:00
}
} ) ;
2019-11-28 17:48:59 +00:00
$ ( '#previewSpanDescription_' + id ) . unbind ( 'click' ) . click ( function ( e ) {
2019-02-12 10:29:50 +00:00
e . stopPropagation ( ) ;
if ( blockDescription === false ) {
blockDescription = true ;
2019-11-28 17:48:59 +00:00
$ ( '#previewSpanDescription_' + id ) . hide ( ) ;
$ ( '#previewInputDescription_' + id ) . show ( ) ;
$ ( '#previewInputDescription_' + id ) . val ( $ ( '#previewInputDescription_' + id ) . val ( ) ) ;
$ ( '#previewInputDescription_' + id ) . focus ( ) . select ( ) ;
2019-02-12 10:29:50 +00:00
}
} ) ;
2019-11-28 17:48:59 +00:00
$ ( '#previewInputDescription_' + id ) . blur ( function ( ) {
2019-02-12 10:29:50 +00:00
blockDescription = false ;
2019-11-28 17:48:59 +00:00
$ ( '#previewSpanDescription_' + id ) . html ( $ ( '#previewInputDescription_' + id ) . val ( ) ) ;
$ ( '#previewSpanDescription_' + id ) . show ( ) ;
$ ( '#previewInputDescription_' + id ) . hide ( ) ;
2019-02-12 10:29:50 +00:00
} ) ;
2019-11-28 17:48:59 +00:00
$ ( '#previewInputDescription_' + id ) . keypress ( function ( e ) {
2019-02-12 10:29:50 +00:00
if ( e . which === 13 ) {
blockDescription = false ;
2019-11-28 17:48:59 +00:00
$ ( '#previewSpanDescription_' + id ) . html ( $ ( '#previewInputDescription_' + id ) . val ( ) ) ;
$ ( '#previewSpanDescription_' + id ) . show ( ) ;
$ ( '#previewInputDescription_' + id ) . hide ( ) ;
2019-02-12 10:29:50 +00:00
}
} ) ;
2019-11-28 17:48:59 +00:00
$ ( '#previewSpanTitle_' + id ) . mouseover ( function ( ) {
$ ( '#previewSpanTitle_' + id ) . css ( {
2019-02-12 10:29:50 +00:00
"background-color" : "#ff9"
} ) ;
} ) ;
2019-11-28 17:48:59 +00:00
$ ( '#previewSpanTitle_' + id ) . mouseout ( function ( ) {
$ ( '#previewSpanTitle_' + id ) . css ( {
2019-02-12 10:29:50 +00:00
"background-color" : "transparent"
} ) ;
} ) ;
2019-11-28 17:48:59 +00:00
$ ( '#previewSpanDescription_' + id ) . mouseover ( function ( ) {
$ ( '#previewSpanDescription_' + id ) . css ( {
2019-02-12 10:29:50 +00:00
"background-color" : "#ff9"
} ) ;
} ) ;
2019-11-28 17:48:59 +00:00
$ ( '#previewSpanDescription_' + id ) . mouseout ( function ( ) {
$ ( '#previewSpanDescription_' + id ) . css ( {
2019-02-12 10:29:50 +00:00
"background-color" : "transparent"
} ) ;
} ) ;
2019-11-28 17:48:59 +00:00
$ ( '#closePreview_' + id ) . unbind ( 'click' ) . click ( function ( e ) {
2019-02-12 10:29:50 +00:00
e . stopPropagation ( ) ;
block = false ;
images = '' ;
isActive = false ;
firstPosted = false ;
2019-11-28 17:48:59 +00:00
$ ( '#preview_' + id ) . fadeOut ( "fast" , function ( ) {
$ ( '#preview_' + id ) . remove ( ) ;
2019-02-12 10:29:50 +00:00
$ ( '#profile-rotator' ) . hide ( ) ;
2019-11-28 17:48:59 +00:00
$ ( '#' + id ) . focus ( ) ;
2019-02-12 10:29:50 +00:00
} ) ;
} ) ;
} ;
/ * *
2023-03-22 03:16:50 +00:00
* Convert attachment bbcode into an array .
2019-02-12 10:29:50 +00:00
*
* @ param { string } content Text content with the attachment bbcode .
* @ returns { object || null }
* /
var getAttachmentData = function ( content ) {
var data = { } ;
2019-02-13 21:26:56 +00:00
var match = content . match ( /([\s\S]*)\[attachment([\s\S]*?)\]([\s\S]*?)\[\/attachment\]([\s\S]*)/im ) ;
2019-02-12 10:29:50 +00:00
if ( match === null || match . length < 5 ) {
return null ;
}
var attributes = match [ 2 ] ;
data . text = trim ( match [ 1 ] ) ;
var type = '' ;
2019-02-13 21:26:56 +00:00
var matches = attributes . match ( /type='([\s\S]*?)'/im ) ;
2019-02-12 10:29:50 +00:00
if ( matches !== null && typeof matches [ 1 ] !== 'undefined' ) {
type = matches [ 1 ] . toLowerCase ( ) ;
}
2019-02-13 21:26:56 +00:00
matches = attributes . match ( /type="([\s\S]*?)"/im ) ;
2019-02-12 10:29:50 +00:00
if ( matches !== null && typeof matches [ 1 ] !== 'undefined' ) {
type = matches [ 1 ] . toLowerCase ( ) ;
}
if ( type === '' ) {
return null ;
}
if (
type !== 'link'
&& type !== 'audio'
&& type !== 'photo'
&& type !== 'video' )
{
return null ;
}
if ( type !== '' ) {
data . type = type ;
}
var url = '' ;
2019-02-13 21:26:56 +00:00
matches = attributes . match ( /url='([\s\S]*?)'/im ) ;
2019-02-12 10:29:50 +00:00
if ( matches !== null && typeof matches [ 1 ] !== 'undefined' ) {
2023-03-19 01:52:53 +00:00
url = matches [ 1 ] ;
2019-02-12 10:29:50 +00:00
}
2019-02-13 21:26:56 +00:00
matches = attributes . match ( /url="([\s\S]*?)"/im ) ;
2019-02-12 10:29:50 +00:00
if ( matches !== null && typeof matches [ 1 ] !== 'undefined' ) {
2023-03-19 01:52:53 +00:00
url = matches [ 1 ] ;
2019-02-12 10:29:50 +00:00
}
if ( url !== '' ) {
data . url = escapeHTML ( url ) ;
}
var title = '' ;
2019-02-13 21:26:56 +00:00
matches = attributes . match ( /title='([\s\S]*?)'/im ) ;
2019-02-12 10:29:50 +00:00
if ( matches !== null && typeof matches [ 1 ] !== 'undefined' ) {
2023-03-19 01:52:53 +00:00
title = trim ( matches [ 1 ] ) ;
2019-02-12 10:29:50 +00:00
}
2019-02-13 21:26:56 +00:00
matches = attributes . match ( /title="([\s\S]*?)"/im ) ;
2019-02-12 10:29:50 +00:00
if ( matches !== null && typeof matches [ 1 ] !== 'undefined' ) {
2023-03-19 01:52:53 +00:00
title = trim ( matches [ 1 ] ) ;
2019-02-12 10:29:50 +00:00
}
if ( title !== '' ) {
data . title = escapeHTML ( title ) ;
}
var image = '' ;
2019-02-13 21:26:56 +00:00
matches = attributes . match ( /image='([\s\S]*?)'/im ) ;
2019-02-12 10:29:50 +00:00
if ( matches !== null && typeof matches [ 1 ] !== 'undefined' ) {
2023-03-19 01:52:53 +00:00
image = trim ( matches [ 1 ] ) ;
2019-02-12 10:29:50 +00:00
}
2019-02-13 21:26:56 +00:00
matches = attributes . match ( /image="([\s\S]*?)"/im ) ;
2019-02-12 10:29:50 +00:00
if ( matches !== null && typeof matches [ 1 ] !== 'undefined' ) {
2023-03-19 01:52:53 +00:00
image = trim ( matches [ 1 ] ) ;
2019-02-12 10:29:50 +00:00
}
if ( image !== '' ) {
data . image = escapeHTML ( image ) ;
}
var preview = '' ;
2019-02-13 21:26:56 +00:00
matches = attributes . match ( /preview='([\s\S]*?)'/im ) ;
2019-02-12 10:29:50 +00:00
if ( matches !== null && typeof matches [ 1 ] !== 'undefined' ) {
2023-03-19 01:52:53 +00:00
preview = trim ( matches [ 1 ] ) ;
2019-02-12 10:29:50 +00:00
}
2019-02-13 21:26:56 +00:00
matches = attributes . match ( /preview="([\s\S]*?)"/im ) ;
2019-02-12 10:29:50 +00:00
if ( matches !== null && typeof matches [ 1 ] !== 'undefined' ) {
2023-03-19 01:52:53 +00:00
preview = trim ( matches [ 1 ] ) ;
2019-02-12 10:29:50 +00:00
}
if ( preview !== '' ) {
data . preview = escapeHTML ( preview ) ;
}
data . text = trim ( match [ 3 ] ) ;
data . after = trim ( match [ 4 ] ) ;
return data ;
} ;
/ * *
* Process txt content and if it contains attachment bbcode
* add it to the attachment preview .
*
* @ param { string } content
* @ returns { void }
* /
var addBBCodeToPreview = function ( content ) {
var attachmentData = getAttachmentData ( content ) ;
if ( attachmentData ) {
reAddAttachment ( attachmentData ) ;
// Remove the attachment bbcode from the textarea.
2019-02-13 21:26:56 +00:00
var content = content . replace ( /\[attachment[\s\S]*\[\/attachment]/im , '' ) ;
2019-11-28 17:48:59 +00:00
$ ( '#' + id ) . val ( content ) ;
$ ( '#' + id ) . focus ( ) ;
2019-02-12 10:29:50 +00:00
}
} ;
/ * *
* Add an Attachment with data from an old bbcode
* generated attachment .
*
* @ param { object } json The attachment data .
* @ returns { void }
* /
var reAddAttachment = function ( json ) {
if ( isActive ) {
$ ( '#profile-rotator' ) . hide ( ) ;
return ;
}
if ( json . type !== 'link' && json . type !== 'video' && json . type !== 'photo' || json . url === json . title ) {
$ ( '#profile-rotator' ) . hide ( ) ;
return ;
}
var obj = { data : json } ;
obj = sanitizeInputData ( obj ) ;
var data = obj . data ;
resetPreview ( ) ;
processAttachmentTpl ( data ) ;
addTitleDescription ( data ) ;
addHostToAttachment ( data . url ) ;
// Since we don't have an array of image data,
// we need to add the preview images in a different way
// than in function addImagesToAttachment().
var imageClass = 'attachment-preview' ;
var image = '' ;
if ( data . image !== '' ) {
imageClass = 'attachment-image' ;
image = data . image ;
} else {
image = data . preview ;
}
if ( image !== '' ) {
2019-11-28 17:48:59 +00:00
var appendImage = "<img id='imagePreview_" + id + "' src='" + image + "' class='" + imageClass + "' ></img>"
$ ( '#previewImage_' + id ) . html ( appendImage ) ;
$ ( '#attachmentImageSrc_' + id ) . val ( bin2hex ( image ) ) ;
2019-02-12 10:29:50 +00:00
2023-03-22 04:08:59 +00:00
// We need to add the image width and height when it is
2019-02-12 10:29:50 +00:00
// loaded.
$ ( '<img/>' , {
load : function ( ) {
2019-11-28 17:48:59 +00:00
$ ( '#attachmentImageWidth_' + id ) . val ( this . width ) ;
$ ( '#attachmentImageHeight_' + id ) . val ( this . height ) ;
2019-02-12 10:29:50 +00:00
} ,
src : image
} ) ;
}
processEventListener ( ) ;
$ ( '#profile-rotator' ) . hide ( ) ;
} ;
/ * *
* Add missing default properties to the input data object .
*
* @ param { object } obj Input data .
* @ returns { object }
* /
var sanitizeInputData = function ( obj ) {
if ( typeof obj . contentType === 'undefined'
|| obj . contentType === null )
{
obj . contentType = "" ;
}
if ( typeof obj . data . url === 'undefined'
|| obj . data . url === null )
{
obj . data . url = "" ;
}
if ( typeof obj . data . title === 'undefined'
|| obj . data . title === null
|| obj . data . title === "" )
{
obj . data . title = defaultTitle ;
}
if ( typeof obj . data . text === 'undefined'
|| obj . data . text === null
|| obj . data . text === "" )
{
obj . data . text = "" ;
}
if ( typeof obj . data . images === 'undefined'
|| obj . data . images === null )
{
obj . data . images = "" ;
}
if ( typeof obj . data . image === 'undefined'
|| obj . data . image === null )
{
obj . data . image = "" ;
}
if ( typeof obj . data . preview === 'undefined'
|| obj . data . preview === null )
{
obj . data . preview = "" ;
}
return obj ;
} ;
/ * *
* Destroy the plugin .
*
* @ returns { void }
* /
var destroy = function ( ) {
2019-11-28 17:48:59 +00:00
$ ( '#' + id ) . unbind ( ) ;
$ ( '#preview_' + id ) . remove ( ) ;
2019-02-12 10:29:50 +00:00
binurl ;
block = false ;
blockTitle = false ;
blockDescription = false ;
cache = { } ;
images = "" ;
isExtern = false ;
photoNumber = 0 ;
firstPosted = false ;
isActive = false ;
isCrawling = false ;
2019-11-28 17:48:59 +00:00
id = "" ;
2019-02-12 10:29:50 +00:00
} ;
var trim = function ( str ) {
return str . replace ( /^\s+|\s+$/g , "" ) ;
} ;
var escapeHTML = function ( unsafe _str ) {
return unsafe _str
. replace ( /&/g , '&' )
. replace ( /</g , '<' )
. replace ( />/g , '>' )
. replace ( /\"/g , '"' )
. replace ( /\[/g , '[' )
. replace ( /\]/g , ']' )
. replace ( /\'/g , ''' ) ; // ''' is not valid HTML 4
} ;
// Initialize LinkPreview
init ( ) ;
return {
// make crawlText() accessable from the outside.
crawlText : function ( text ) {
crawlText ( text ) ;
} ,
addBBCodeToPreview : function ( content ) {
addBBCodeToPreview ( content ) ;
} ,
destroy : function ( ) {
destroy ( ) ;
}
} ;
} ;
$ . fn . linkPreview . defaults = {
defaultDescription : "Enter a description" ,
defaultTitle : "Enter a title"
} ;
/ * *
* Get in a textarea the previous word before the cursor .
*
2023-03-22 03:17:34 +00:00
* @ param { object } text Textarea element .
2019-02-12 10:29:50 +00:00
* @ param { integer } caretPos Cursor position .
*
* @ returns { string } Previous word .
* /
function returnWord ( text , caretPos ) {
var index = text . indexOf ( caretPos ) ;
var preText = text . substring ( 0 , caretPos ) ;
2023-03-22 03:17:02 +00:00
// If the last character is a space or enter remove it
2019-02-12 10:29:50 +00:00
// We need this in friendica for the url preview.
var lastChar = preText . slice ( - 1 )
if ( lastChar === " "
|| lastChar === "\n"
|| lastChar === "\r"
)
{
preText = preText . substring ( 0 , preText . length - 1 ) ;
}
// Replace new line with space.
preText = preText . replace ( /\n/g , " " ) ;
if ( preText . indexOf ( " " ) > 0 ) {
var words = preText . split ( " " ) ;
return words [ words . length - 1 ] ; //return last word
}
else {
return preText ;
}
}
/ * *
* Get in a textarea the previous word before the cursor .
*
* @ param { string } id The ID of a textarea element .
* @ returns { sting | null } Previous word or null if no word is available .
* /
function getPrevWord ( id ) {
var text = document . getElementById ( id ) ;
var caretPos = getCaretPosition ( text ) ;
var word = returnWord ( text . value , caretPos ) ;
if ( word != null ) {
return word
}
}
/ * *
2023-03-22 04:08:02 +00:00
* Get the cursor position in an text element .
2019-02-12 10:29:50 +00:00
*
2023-03-22 03:17:34 +00:00
* @ param { object } ctrl Textarea element .
2019-02-12 10:29:50 +00:00
* @ returns { integer } Position of the cursor .
* /
function getCaretPosition ( ctrl ) {
var CaretPos = 0 ; // IE Support
if ( document . selection ) {
ctrl . focus ( ) ;
var Sel = document . selection . createRange ( ) ;
Sel . moveStart ( 'character' , - ctrl . value . length ) ;
CaretPos = Sel . text . length ;
}
// Firefox support
else if ( ctrl . selectionStart || ctrl . selectionStart == '0' ) {
CaretPos = ctrl . selectionStart ;
}
return ( CaretPos ) ;
}
} ) ( jQuery ) ;
// @license-end