1/** 2 * Copyright (c) 2014 Leonardo Cardoso (http://leocardz.com) 3 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 4 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. 5 * 6 * Version: 1.3.0 7 */ 8(function ($) { 9 $.fn.linkPreview = function (options) { 10 11 var defaults = { 12 placeholder: "What's in your mind", 13 imageQuantity: -1 // illimited 14 }; 15 16 var opts = jQuery.extend(defaults, options); 17 18 function trim(str) { 19 return str.replace(/^\s+|\s+$/g, ""); 20 } 21 22 var selector = $(this).selector; 23 selector = selector.substr(1); 24 25 $(this).append('<div id="previewLoading_' + selector + '" class="previewLoading"></div> <div style="float: left;"> <textarea type="text" id="text_' + selector + '" style="text-align: left" placeholder="' + opts.placeholder + '" class="text" style="text-align: left"/></textarea> <div style="clear: both"></div> </div> <div id="preview_' + selector + '" class="preview"> <div id="previewImages_' + selector + '" class="previewImages"> <div id="previewImage_' + selector + '" class="previewImage"><img src="img/loader.gif" style="margin-left: 43%; margin-top: 39%;"/> </div> <input type="hidden" id="photoNumber_' + selector + '" class="photoNumber" value="0" /> </div> <div id="previewContent_' + selector + '" class="previewContent"> <div id="closePreview_' + selector + '" title="Remove" class="closePreview" ></div> <div id="previewTitle_' + selector + '" class="previewTitle"></div> <div id="previewUrl_' + selector + '" class="previewUrl"></div> <div id="previewDescription_' + selector + '" class="previewDescription"></div> <div id="hiddenDescription_' + selector + '" class="hiddenDescription"></div> <div id="previewButtons_' + selector + '" class="previewButtons" > <div id="previewPreviousImg_' + selector + '" class="buttonLeftDeactive" ></div> <div id="previewNextImg_' + selector + '" class="buttonRightDeactive" ></div> <div id="photoNumbers_' + selector + '" class="photoNumbers" ></div> <div id="chooseThumbnail_' + selector + '" class="chooseThumbnail"> Choose a thumbnail </div> </div> <div class="nT" id="nT_' + selector + '" > <span id="noThumbDiv_' + selector + '" class="noThumbDiv" ><input type="checkbox" id="noThumb_' + selector + '" class="noThumb noThumbCb" /> No thumbnail</span> </div> </div> <div style="clear: both"></div> </div> <div style="clear: both"></div> <div id="postPreview_' + selector + '" class="postPreview"> <input id="postPreviewButton_' + selector + '" class="postPreviewButton" type="submit" value="Post" /> <div style="clear: both"></div> </div> <div class="previewPostedList" id="previewPostedList_' + selector + '"></div>'); 26 27 var text; 28 var urlRegex = /(https?\:\/\/|\s)[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})(\/+[a-z0-9_.\:\;-]*)*(\?[\&\%\|\+a-z0-9_=,\.\:\;-]*)?([\&\%\|\+&a-z0-9_=,\:\;\.-]*)([\!\#\/\&\%\|\+a-z0-9_=,\:\;\.-]*)}*/i; 29 var block = false; 30 var blockTitle = false; 31 var blockDescription = false; 32 var contentWidth = 355; 33 var content = ""; 34 var image = ""; 35 var images = ""; 36 var title = ""; 37 var url = ""; 38 var video = "no"; 39 var videoPlay = ""; 40 var description = ""; 41 var hrefUrl = ""; 42 var videoIframe = ""; 43 var leftSideContent = ""; 44 var photoNumber = 0; 45 var firstPosted = false; 46 var firstPosting = false; 47 var nT = false; 48 var imageId = ""; 49 var imageIdArray = ""; 50 var pTP = ""; 51 var pDP = ""; 52 var fancyUrl = ''; 53 var allowPosting = false; 54 var isCrawling = false; 55 var defaultTitle = "Enter a title"; 56 var defaultDescription = "Enter a description"; 57 58 var textText = ""; 59 $('#text_' + selector).focus(function () { 60 if (trim($('#text_' + selector).val()) === textText) { 61 $(this).val(''); 62 $(this).css({ 63 'color': 'black' 64 }); 65 } 66 }).blur(function () { 67 if (trim($('#text_' + selector).val()) === "") { 68 $(this).val(textText); 69 $(this).css({ 70 'color': 'grey' 71 }); 72 } 73 }); 74 75 function resetPreview() { 76 $('#previewPreviousImg_' + selector).removeClass('buttonLeftActive'); 77 $('#previewPreviousImg_' + selector).addClass('buttonLeftDeactive'); 78 $('#previewNextImg_' + selector).removeClass('buttonRightActive'); 79 $('#previewNextImg_' + selector).addClass('buttonRightDeactive'); 80 $('#previewButtons_' + selector).show(); 81 contentWidth = 355; 82 photoNumber = 0; 83 $('#previewContent_' + selector).css({ 84 'width': '355px' 85 }); 86 $('#noThumb_' + selector).show(); 87 $('#nT_' + selector).show(); 88 $('#noThumb_' + selector).removeAttr('checked'); 89 images = ""; 90 } 91 92 93 function noThumbAction(inputCheckbox, src) { 94 95 var value = src === 'parent' ? !inputCheckbox.prop("checked") : inputCheckbox.prop("checked"); 96 97 inputCheckbox.prop('checked', value); 98 99 $('#imagePreview_' + selector + '_' + photoNumber).css({ 100 'display': !value ? 'block' : 'none' 101 }); 102 $('#whiteImage_' + selector).css({ 103 'display': !value ? 'none' : 'block' 104 }); 105 $('#previewContent_' + selector).css({ 106 'width': !value ? '355px' : '500px' 107 }); 108 109 if (value === true) { 110 $('#previewButtons_' + selector).hide(); 111 } else { 112 $('#previewButtons_' + selector).show(); 113 114 } 115 116 } 117 118 function iframenize(obj) { 119 120 var oldId = obj.prop("id"); 121 var currentId = oldId.substring(3); 122 pTP = "pTP" + currentId; 123 pDP = "pDP" + currentId; 124 oldId = "#" + oldId; 125 currentId = "#" + currentId; 126 $(oldId).css({ 127 'display': 'none' 128 }); 129 $(currentId).css({ 130 'display': 'block' 131 }); 132 $('#' + pTP).css({ 133 'width': '495px' 134 }); 135 $('#' + pDP).css({ 136 'width': '495px' 137 }); 138 139 } 140 141 142 var crawlText = function () { 143 144 allowPosting = true; 145 block = false; 146 hrefUrl = ''; 147 fancyUrl = ''; 148 images = ''; 149 video = ''; 150 151 text = " " + $('#text_' + selector).val(); 152 if (trim(text) !== "") { 153 video = "no"; 154 videoPlay = ""; 155 if (block === false && urlRegex.test(text)) { 156 block = true; 157 $('#preview_' + selector).hide(); 158 $('#previewButtons_' + selector).hide(); 159 $('#previewLoading_' + selector).html("<img src='img/loader.gif' />"); 160 $('#photoNumber_' + selector).val(0); 161 162 allowPosting = false; 163 isCrawling = true; 164 165 $.post('php/textCrawler.php', { 166 text: text, 167 imagequantity: opts.imageQuantity 168 }, function (answer) { 169 170 if (answer.url === null) 171 answer.url = ""; 172 if (answer.pageUrl === null) 173 answer.pageUrl = ""; 174 if (answer.title === null || answer.title === "") 175 answer.title = defaultTitle; 176 if (answer.description === null || answer.description === "") 177 answer.description = defaultDescription; 178 if (answer.canonicalUrl === null) 179 answer.canonicalUrl = ""; 180 if (answer.images === null) 181 answer.images = ""; 182 if (answer.video === null) 183 answer.video = ""; 184 if (answer.videoIframe === null) 185 answer.videoIframe = ""; 186 resetPreview(); 187 $('#previewLoading_' + selector).html(""); 188 $('#preview_' + selector).show(); 189 $('#previewTitle_' + selector).html("<span id='previewSpanTitle_" + selector + "' class='previewSpanTitle' >" + answer.title + "</span><input type='text' value='" + answer.title + "' id='previewInputTitle_" + selector + "' class='previewInputTitle inputPreview' style='display: none;'/>"); 190 $('#text_' + selector).css({
191 "border": "1px solid #b3b3b3", 192 "border-bottom": "1px dashed #b3b3b3" 193 }); 194 195 $('#previewUrl_' + selector).html(answer.url); 196 $('#previewDescription_' + selector).html("<span id='previewSpanDescription_" + selector + "' class='previewSpanDescription' >" + answer.description + "</span><textarea id='previewInputDescription_" + selector + "' class='previewInputDescription' style='display: none;' class='inputPreview' >" + answer.description + "</textarea>"); 197 title = "<a href='" + answer.pageUrl + "' target='_blank'>" + $('#previewTitle_' + selector).html() + "</a>"; 198 url = "<a href='http://" + answer.canonicalUrl + "' target='_blank'>" + answer.canonicalUrl + "</a>"; 199 fancyUrl = answer.canonicalUrl; 200 hrefUrl = answer.url; 201 description = $('#previewDescription_' + selector).html(); 202 video = answer.video; 203 videoIframe = answer.videoIframe; 204 try { 205 images = (answer.images).split("|"); 206 $('#previewImages_' + selector).show(); 207 $('#previewButtons_' + selector).show(); 208 } catch (err) { 209 $('#previewImages_' + selector).hide(); 210 $('#previewButtons_' + selector).hide(); 211 } 212 images.length = parseInt(images.length); 213 var appendImage = ""; 214 for (i = 0; i < images.length; i++) { 215 if (i === 0) 216 appendImage += "<img id='imagePreview_" + selector + "_" + i + "' src='" + images[i] + "' style='width: 130px; height: auto' ></img>"; 217 else 218 appendImage += "<img id='imagePreview_" + selector + "_" + i + "' src='" + images[i] + "' style='width: 130px; height: auto; display: none' ></img>"; 219 } 220 $('#previewImage_' + selector).html("<a href='" + answer.pageUrl + "' target='_blank'>" + appendImage + "</a><div id='whiteImage' style='width: 130px; color: transparent; display:none;'>...</div>"); 221 $('#photoNumbers_' + selector).html("1 of " + images.length); 222 if (images.length > 1) { 223 $('#previewNextImg_' + selector).removeClass('buttonRightDeactive'); 224 $('#previewNextImg_' + selector).addClass('buttonRightActive'); 225 226 if (firstPosted === false) { 227 firstPosted = true; 228 $('#previewPreviousImg_' + selector).unbind('click').click(function (e) { 229 e.stopPropagation(); 230 if (images.length > 1) { 231 photoNumber = parseInt($('#photoNumber_' + selector).val()); 232 $('#imagePreview_' + selector + '_' + photoNumber).css({ 233 'display': 'none' 234 }); 235 photoNumber -= 1; 236 if (photoNumber === -1) 237 photoNumber = 0; 238 $('#previewNextImg_' + selector).removeClass('buttonRightDeactive'); 239 $('#previewNextImg_' + selector).addClass('buttonRightActive'); 240 if (photoNumber === 0) { 241 photoNumber = 0; 242 $('#previewPreviousImg_' + selector).removeClass('buttonLeftActive'); 243 $('#previewPreviousImg_' + selector).addClass('buttonLeftDeactive'); 244 } 245 $('#imagePreview_' + selector + '_' + photoNumber).css({ 246 'display': 'block' 247 }); 248 $('#photoNumber_' + selector).val(photoNumber); 249 $('#photoNumbers_' + selector).html(parseInt(photoNumber + 1) + " of " + images.length); 250 } 251 }); 252 $('#previewNextImg_' + selector).unbind('click').click(function (e) { 253 e.stopPropagation(); 254 if (images.length > 1) { 255 photoNumber = parseInt($('#photoNumber_' + selector).val()); 256 $('#imagePreview_' + selector + '_' + photoNumber).css({ 257 'display': 'none' 258 }); 259 photoNumber += 1; 260 if (photoNumber === images.length) 261 photoNumber = images.length - 1; 262 $('#previewPreviousImg_' + selector).removeClass('buttonLeftDeactive'); 263 $('#previewPreviousImg_' + selector).addClass('buttonLeftActive'); 264 if (photoNumber === images.length - 1) { 265 photoNumber = images.length - 1; 266 $('#previewNextImg_' + selector).removeClass('buttonRightActive'); 267 $('#previewNextImg_' + selector).addClass('buttonRightDeactive'); 268 } 269 $('#imagePreview_' + selector + '_' + photoNumber).css({ 270 'display': 'block' 271 }); 272 $('#photoNumber_' + selector).val(photoNumber); 273 $('#photoNumbers_' + selector).html(parseInt(photoNumber + 1) + " of " + images.length); 274 } 275 }); 276 } 277 } else if (images.length === 0) { 278 $('#closePreview_' + selector).css({ 279 "margin-right": "-206px" 280 }); 281 $('#previewTitle_' + selector).css({ 282 "width": "495px" 283 }); 284 $('#previewDescription_' + selector).css({ 285 "width": "495px" 286 }); 287 $('#previewInputDescription_' + selector).css({ 288 "width": "495px" 289 }); 290 contentWidth = 495; 291 $('#previewButtons_' + selector).hide(); 292 $('#noThumb_' + selector).hide(); 293 $('#nT_' + selector).hide(); 294 } 295 $('#nT_' + selector).unbind('click').click(function (e) { 296 e.stopPropagation(); 297 noThumbAction($('#noThumb_' + selector), 'parent'); 298 }); 299 $('#noThumb_' + selector).unbind('click').click(function (e) { 300 e.stopPropagation(); 301 noThumbAction($(this), 'input'); 302 }); 303 $('#previewSpanTitle_' + selector).unbind('click').click(function (e) { 304 e.stopPropagation(); 305 if (blockTitle === false) { 306 blockTitle = true; 307 $('#previewSpanTitle_' + selector).hide(); 308 $('#previewInputTitle_' + selector).show(); 309 $('#previewInputTitle_' + selector).val($('#previewInputTitle_' + selector).val()); 310 $('#previewInputTitle_' + selector).focus().select(); 311 } 312 }); 313 $('#previewInputTitle_' + selector).blur(function () { 314 blockTitle = false; 315 $('#previewSpanTitle_' + selector).html($('#previewInputTitle_' + selector).val()); 316 $('#previewSpanTitle_' + selector).show(); 317 $('#previewInputTitle_' + selector).hide(); 318 }); 319 $('#previewInputTitle_' + selector).keypress(function (e) { 320 if (e.which === 13) { 321 blockTitle = false; 322 $('#previewSpanTitle_' + selector).html($('#previewInputTitle_' + selector).val()); 323 $('#previewSpanTitle_' + selector).show(); 324 $('#previewInputTitle_' + selector).hide(); 325 } 326 }); 327 $('#previewSpanDescription_' + selector).unbind('click').click(function (e) { 328 e.stopPropagation(); 329 if (blockDescription === false) { 330 blockDescription = true; 331 $('#previewSpanDescription_' + selector).hide(); 332 $('#previewInputDescription_' + selector).show(); 333 $('#previewInputDescription_' + selector).val($('#previewInputDescription_' + selector).val()); 334 $('#previewInputDescription_' + selector).focus().select(); 335 } 336 }); 337 $('#previewInputDescription_' + selector).blur(function () { 338 blockDescription = false; 339 $('#previewSpanDescription_' + selector).html($('#previewInputDescription_' + selector).val()); 340 $('#previewSpanDescription_' + selector).show(); 341 $('#previewInputDescription_' + selector).hide(); 342 }); 343 $('#previewInputDescription_' + selector).keypress(function (e) { 344 if (e.which === 13) { 345 blockDescription = false; 346 $('#previewSpanDescription_' + selector).html($('#previewInputDescription_' + selector).val()); 347 $('#previewSpanDescription_' + selector).show(); 348 $('#previewInputDescription_' + selector).hide(); 349 } 350 }); 351 $('#previewSpanTitle_' + selector).mouseover(function () { 352 $('#previewSpanTitle_' + selector).css({ 353 "background-color": "#ff9" 354 }); 355 }); 356 $('#previewSpanTitle_' + selector).mouseout(function () { 357 $('#previewSpanTitle_' + selector).css({ 358 "background-color": "transparent" 359 }); 360 }); 361 $('#previewSpanDescription_' + selector).mouseover(function () { 362 $('#previewSpanDescription_' + selector).css({ 363 "background-color": "#ff9" 364 }); 365 }); 366 $('#previewSpanDescription_' + selector).mouseout(function () { 367 $('#previewSpanDescription_' + selector).css({ 368 "background-color": "transparent" 369 }); 370 }); 371 $('#closePreview_' + selector).unbind('click').click(function (e) { 372 e.stopPropagation(); 373 block = false; 374 hrefUrl = ''; 375 fancyUrl = ''; 376 images = ''; 377 video = ''; 378 $('#preview_' + selector).fadeOut("fast", function () { 379 $('#text_' + selector).css({
380 "border": "1px solid #b3b3b3", 381 "border-bottom": "1px solid #e6e6e6" 382 }); 383 $('#previewImage_' + selector).html(""); 384 $('#previewTitle_' + selector).html(""); 385 $('#previewUrl_' + selector).html(""); 386 $('#previewDescription_' + selector).html(""); 387 }); 388 389 }); 390 if (firstPosting === false) { 391 firstPosting = true; 392 } 393 allowPosting = true; 394 isCrawling = false; 395 }, "json"); 396 } 397 } 398 }; 399 400 $('#text_' + selector).bind({ 401 paste: function () { 402 setTimeout(function () { 403 crawlText(); 404 }, 100); 405 }, 406 keyup: function (e) { 407 if ((e.which === 13 || e.which === 32 || e.which === 17)) { 408 crawlText(); 409 } 410 } 411 }); 412 413 414 $('#postPreviewButton_' + selector).unbind('click').click(function (e) { 415 e.stopPropagation(); 416 417 imageId = ""; 418 pTP = ""; 419 pDP = ""; 420 text = " " + $('#text_' + selector).val(); 421 title = $('#previewTitle_' + selector).html(); 422 description = $('#previewDescription_' + selector).html(); 423 424 if (((trim(text) !== "") || (trim(text) === "" && trim(hrefUrl) !== "")) && (allowPosting === true && isCrawling === false)) { 425 $.get('php/highlightUrls.php', { 426 text: text, 427 description: description 428 }, function (urls) { 429 430 if ($('#noThumb_' + selector).prop('checked') || images.length === 0) { 431 contentWidth = 495; 432 leftSideContent = ""; 433 } else if (images || video) { 434 if (video === "yes") { 435 var pattern = /id="(.+?)"/i; 436 imageIdArray = videoIframe.match(pattern); 437 imageId = imageIdArray[1]; 438 pTP = "pTP" + imageId; 439 pDP = "pDP" + imageId; 440 var imageIdPrefixed = "img" + imageId; 441 image = "<img id='" + imageIdPrefixed + "' src='" + $('#imagePreview_' + selector + '_' + photoNumber).prop("src") + "' class='imgIframe' style='width: 130px; height: auto; float: left;' ></img>"; 442 videoPlay = '<span class="videoPostPlay" id="videoPostPlay' + imageId + '"></span>'; 443 leftSideContent = image + videoPlay; 444 } else { 445 image = "<img src='" + $('#imagePreview_' + selector + '_' + photoNumber).prop("src") + "' style='width: 130px; height: auto; float: left;' ></img>"; 446 leftSideContent = '<a href="' + hrefUrl + '" target="_blank">' + image + '</a>'; 447 } 448 } 449 450 if (title.indexOf(defaultTitle) != -1) { 451 title = title.replace(defaultTitle, ""); 452 } 453 454 if (urls.description.indexOf(defaultDescription) != -1) { 455 urls.description = replaceAll(defaultDescription, '', urls.description); 456 } 457 458 459 /** Database insert */ 460 $.post('php/save.php', { 461 text: $('#text_' + selector).val(), 462 image: $('#noThumb_' + selector).prop("checked") ? '' : $('#imagePreview_' + selector + '_' + photoNumber).prop("src"), 463 title: title, 464 canonicalUrl: fancyUrl, 465 url: hrefUrl, 466 description: $('#previewSpanDescription_' + selector).html(), 467 iframe: videoIframe 468 }, function (response) { 469 470 // console.log(response); 471 472 var id = !isNaN(response) ? response : Math.floor((Math.random() * 1000000000) + 1); 473 474 content = '<div class="previewPosted" id="contentWrap' + id + '" >' + '<div class="previewTextPosted">' + urls.urls + '</div>' + videoIframe + '<div class="previewImagesPosted">' + '<div class="previewImagePosted">' + leftSideContent + '</div>' + '</div>' + '<div class="previewContentPosted">' + '<div class="previewTitlePosted" id="' + pTP + '" style="width: ' + contentWidth + 'px" ><a href="' + hrefUrl + '" target="_blank">' + title + '</a></div>' + '<div class="previewUrlPosted">' + fancyUrl + '</div>' + '<div class="previewDescriptionPosted" id="' + pDP + '" style="width: ' + contentWidth + 'px" >' + urls.description + '</div>' + '</div><div style="clear: both"><span style="color: red; cursor: pointer; float: right" id="delete_action_' + id + '" ref="' + id + '">delete</span></div></div>'; 475 476 $('#preview_' + selector).fadeOut("fast", function () { 477 478 // Vine video needs to be preloaded 479 if (hrefUrl.indexOf("vine.co") != -1) { 480 setTimeout(function () { 481 $('#' + imageId).hide(); 482 }, 50); 483 484 } 485 486 $('#text_' + selector).css({
487 "border": "1px solid #b3b3b3", 488 "border-bottom": "1px solid #e6e6e6" 489 }); 490 $('#text_' + selector).val(""); 491 hrefUrl = ""; 492 $('#previewImage_' + selector).html(""); 493 $('#previewTitle_' + selector).html(""); 494 $('#previewUrl_' + selector).html(""); 495 $('#previewDescription_' + selector).html(""); 496 $(content).hide().prependTo('#previewPostedList_' + selector).fadeIn("fast"); 497 $(".imgIframe").unbind('click').click(function (e) { 498 e.stopPropagation(); 499 iframenize($(this)); 500 }); 501 $('#videoPostPlay' + imageId).click(function (e) { 502 e.stopPropagation(); 503 iframenize($(this).parent().find(".imgIframe")); 504 }); 505 506 $("#delete_action_" + id).click(function () { 507 var id = $(this).attr("ref"); 508 $.post('php/delete.php', {id: id}, function (answer) { 509 // console.log(answer); 510 $("#contentWrap" + id).remove(); 511 }); 512 }); 513 514 515 }); 516 517 }); 518 519 }, "json"); 520 text = ""; 521 } 522 }); 523 524 function replaceAll(find, replace, str) { 525 return str.replace(new RegExp(find, 'g'), replace); 526 } 527 528 }; 529 530})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.