Merge pull request #380 from DakuTree/patch-3

Misc tweaks/fixes 2 (fixes #349)
This commit is contained in:
jgen 2014-02-21 13:40:52 -05:00
commit bbfba90ad4
34 changed files with 234 additions and 881 deletions

View file

@ -36,7 +36,7 @@ _d("WH_SPLITS", 1); // int how many levels of subfolders to put in
_d("VERSION", 'trunk'); // string shimmie version
_d("TIMEZONE", null); // string timezone
_d("MIN_FREE_SPACE",100*1024*1024); // int disable uploading if there's less than MIN_FREE_SPACE bytes free space
_d("CORE_EXTS", "bbcode,user,mail,upload,image,view,handle_pixel,ext_manager,setup,upgrade,handle_404,comment,tag_list,index,tag_edit,alias_editor,hellban"); // extensions to always enable
_d("CORE_EXTS", "bbcode,user,mail,upload,image,view,handle_pixel,ext_manager,setup,upgrade,handle_404,comment,tag_list,index,tag_edit,alias_editor"); // extensions to always enable
_d("EXTRA_EXTS", ""); // optional extra extensions

View file

@ -164,7 +164,7 @@ class AdminPage extends Extension {
global $page;
$matches = array();
preg_match("#^(?P<proto>\w+)\:(?:user=(?P<user>\w+)(?:;|$)|password=(?P<password>\w+)(?:;|$)|host=(?P<host>[\w\.\-]+)(?:;|$)|dbname=(?P<dbname>[\w_]+)(?:;|$))+#", DATABASE_DSN, $matches);
preg_match("#^(?P<proto>\w+)\:(?:user=(?P<user>\w+)(?:;|$)|password=(?P<password>\w*)(?:;|$)|host=(?P<host>[\w\.\-]+)(?:;|$)|dbname=(?P<dbname>[\w_]+)(?:;|$))+#", DATABASE_DSN, $matches);
$software = $matches['proto'];
$username = $matches['user'];
$password = $matches['password'];
@ -184,6 +184,8 @@ class AdminPage extends Extension {
break;
}
//FIXME: .SQL dump is empty if cmd doesn't exist
$page->set_mode("data");
$page->set_type("application/x-unknown");
$page->set_filename('shimmie-'.date('Ymd').'.sql');
@ -195,67 +197,59 @@ class AdminPage extends Extension {
private function download_all_images() {
global $database, $page;
$zip = new ZipArchive;
$images = $database->get_all("SELECT * FROM images");
$images = $database->get_all("SELECT hash, ext FROM images");
$filename = data_path('imgdump-'.date('Ymd').'.zip');
if($zip->open($filename, 1 ? ZIPARCHIVE::OVERWRITE:ZIPARCHIVE::CREATE) === TRUE){
$zip = new ZipArchive;
if($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE) === TRUE){
foreach($images as $img){
$hash = $img["hash"];
preg_match("^[A-Za-z0-9]{2}^", $hash, $matches);
$img_loc = "images/".$matches[0]."/".$hash;
if(file_exists($img_loc)){
$zip->addFile($img_loc, $hash.".".$img["ext"]);
}
$img_loc = warehouse_path("images", $img["hash"], FALSE);
$zip->addFile($img_loc, $img["hash"].".".$img["ext"]);
}
$zip->close();
}
$page->set_mode("redirect");
$page->set_redirect(make_link($filename)); //Fairly sure there is better way to do this..
//TODO: Delete file after downloaded?
$page->set_redirect(make_link($filename)); //TODO: Delete file after downloaded?
return false; // we do want a redirect, but a manual one
}
private function reset_image_ids() {
global $database;
//This might be a bit laggy on boards with lots of images (?)
//Seems to work fine with 1.2k~ images though.
$i = 0;
$image = $database->get_all("SELECT * FROM images ORDER BY images.id ASC");
/*$score_log = $database->get_all("SELECT message FROM score_log");*/
foreach($image as $img){
$xid = $img[0];
$i = $i + 1;
$table = array( //Might be missing some tables?
"image_tags", "tag_histories", "image_reports", "comments", "user_favorites", "tag_histories",
"numeric_score_votes", "pool_images", "slext_progress_cache", "notes");
//TODO: Make work with PostgreSQL + SQLite
//TODO: Update score_log (Having an optional ID column for score_log would be nice..)
preg_match("#^(?P<proto>\w+)\:(?:user=(?P<user>\w+)(?:;|$)|password=(?P<password>\w*)(?:;|$)|host=(?P<host>[\w\.\-]+)(?:;|$)|dbname=(?P<dbname>[\w_]+)(?:;|$))+#", DATABASE_DSN, $matches);
$sql =
"SET FOREIGN_KEY_CHECKS=0;
UPDATE images
SET id=".$i.
" WHERE id=".$xid.";"; //id for images
if($matches['proto'] == "mysql"){
$tables = $database->get_col("SELECT TABLE_NAME
FROM information_schema.KEY_COLUMN_USAGE
WHERE TABLE_SCHEMA = :db
AND REFERENCED_COLUMN_NAME = 'id'
AND REFERENCED_TABLE_NAME = 'images'", array("db" => $matches['dbname']));
foreach($table as $tbl){
$sql .= "
UPDATE ".$tbl."
SET image_id=".$i."
WHERE image_id=".$xid.";";
$i = 1;
$ids = $database->get_col("SELECT id FROM images ORDER BY images.id ASC");
foreach($ids as $id){
$sql = "SET FOREIGN_KEY_CHECKS=0;
UPDATE images SET id={$i} WHERE image_id={$id};";
foreach($tables as $table){
$sql .= "UPDATE {$table} SET image_id={$i} WHERE image_id={$id};";
}
/*foreach($score_log as $sl){
//This seems like a bad idea.
//TODO: Might be better for log_info to have an $id option (which would then affix the id to the table?)
preg_replace(".Image \\#[0-9]+.", "Image #".$i, $sl);
}*/
$sql .= " SET FOREIGN_KEY_CHECKS=1;";
$database->execute($sql);
$i++;
}
$database->execute("ALTER TABLE images AUTO_INCREMENT=".(count($ids) + 1));
}elseif($matches['proto'] == "pgsql"){
//TODO: Make this work with PostgreSQL
}elseif($matches['proto'] == "sqlite"){
//TODO: Make this work with SQLite
}
$count = (count($image)) + 1;
$database->execute("ALTER TABLE images AUTO_INCREMENT=".$count);
return true;
}
}

View file

@ -39,7 +39,7 @@ class AdminPageTheme extends Themelet {
$html = "";
$html .= $this->button("All tags to lowercase", "lowercase_all_tags", true);
$html .= $this->button("Recount tag use", "recount_tag_use", false);
$html .= $this->button("Download all images", "image_dump", false);
$html .= $this->button("Download all images", "download_all_images", false);
$html .= $this->button("Download database contents", "database_dump", false);
if($database->get_driver_name() == "mysql")
$html .= $this->button("Reset image IDs", "reset_image_ids", true);

View file

@ -31,20 +31,14 @@ class ArrowkeyNavigation extends Extension {
global $page;
$page->add_html_header("<script type=\"text/javascript\">
document.onkeyup=checkKeycode;
function checkKeycode(e)
{
var keycode;
if(window.event) keycode=window.event.keyCode;
else if(e) keycode=e.which;
if (e.srcElement.tagName != \"INPUT\")
{
if(keycode==\"37\") window.location.href='$prev_url';
else if(keycode==\"39\") window.location.href='$next_url';
}
}
</script>");
(function($){
$(document).keyup(function(e) {
if($(e.target).is('input', 'textarea')){ return; }
if (e.keyCode == 37) { window.location.href = '{$prev_url}'; }
else if (e.keyCode == 39) { window.location.href = '{$next_url}'; }
});
})(jQuery);
</script>", 60);
}
# returns info about the current page number
@ -61,7 +55,6 @@ class ArrowkeyNavigation extends Extension {
$total_pages = ceil($database->get_one(
"SELECT COUNT(*) FROM images") / $images_per_page);
}
else { // if there are tags, use pages with tags
$prefix = $event->get_arg(0)."/";
$page_number = (int)$event->get_arg(1);

View file

@ -1,6 +1,6 @@
<?php
/*
* Name: Bulk Remove (Beta)
* Name: [Beta] Bulk Remove
* Author: Drudex Software <support@drudexsoftware.com>
* Link: http://www.drudexsoftware.com/
* License: GPLv2

View file

@ -1,6 +1,6 @@
<?php
/**
* Name: Chatbox (Beta)
* Name: [Beta] Chatbox
* Author: Drudex Software <support@drudexsoftware.com>
* Link: http://www.drudexsoftware.com
* License: GPLv2

View file

@ -1,4 +1,8 @@
<?php
/*
* Name: [Beta] Hellban
*/
class HellBan extends Extension {
public function onPageRequest(PageRequestEvent $event) {
global $page, $user;

View file

@ -1,6 +1,6 @@
$(function() {
if(window.notes) {
$('#main_image').imgNotes(window.notes);
$('#main_image').imgNotes({notes: window.notes});
}
$('#cancelnote').click(function(){

View file

@ -1,6 +1,6 @@
<?php
/*
* Name: [beta] PM triggers
* Name: [Beta] PM triggers
* Author: Shish <webmaster@shishnet.org>
* License: GPLv2
* Description: Send PMs in response to certain events (eg image deletion)

View file

@ -28,7 +28,7 @@ class RandomList extends Extension {
// create html to display images
foreach ($random_images as $image)
$random_html .= $this->build_random_html($image);
$random_html .= $this->theme->build_thumb_html($image);
// display it
$random_html .= "</div>";
@ -50,19 +50,5 @@ class RandomList extends Extension {
$event->panel->add_block($sb);
}
private function build_random_html(Image $image, $query=null) {
$i_id = int_escape($image->id);
$h_view_link = make_link("post/view/$i_id", $query);
$h_thumb_link = $image->get_thumb_link();
$h_tip = html_escape($image->get_tooltip());
$tsize = get_thumbnail_size($image->width, $image->height);
return "
<a href='$h_view_link' class='thumb shm-thumb' data-post-id='$i_id'>
<img id='thumb_$i_id' height='{$tsize[1]}' width='{$tsize[0]}' class='lazy' data-original='$h_thumb_link' src='/lib/static/grey.gif'><noscript>
<img id='thumb_$i_id' height='{$tsize[1]} width='{$tsize[0]} src='$h_thumb_link'></noscript></a>
";
}
}
?>

View file

@ -0,0 +1,4 @@
<?php
/* needed for access to build_thumb_html */
class RandomListTheme extends Themelet {}
?>

4
lib/jquery-1.11.0.min.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1 +0,0 @@
.ac_results{padding:0;border:1px solid black;background-color:white;overflow:hidden;z-index:99999}.ac_results ul{width:100%;list-style-position:outside;list-style:none;padding:0;margin:0}.ac_results li{margin:0;padding:2px 5px;cursor:default;display:block;font:menu;font-size:12px;line-height:16px;overflow:hidden}.ac_loading{background:white url('indicator.gif') right center no-repeat}.ac_odd{background-color:#eee}.ac_over{background-color:#0a246a;color:white}

File diff suppressed because one or more lines are too long

7
lib/jquery.autocomplete-2.4.4.min.css vendored Normal file
View file

@ -0,0 +1,7 @@
/**
* @fileOverview CSS for jquery-autocomplete, the jQuery Autocompleter
* @author <a href="mailto:dylan@dyve.net">Dylan Verheul</a>
* @license MIT | GPL | Apache 2.0, see LICENSE.txt
* @see https://github.com/dyve/jquery-autocomplete
*/
.acResults{padding:0;border:1px solid WindowFrame;background-color:Window;overflow:hidden}.acResults ul{margin:0;padding:0;list-style-position:outside;list-style:none}.acResults ul li{margin:0;padding:2px 5px;cursor:pointer;display:block;font:menu;font-size:12px;overflow:hidden}.acLoading{background:url(indicator.gif) right center no-repeat}.acSelect{background-color:Highlight;color:HighlightText}

9
lib/jquery.autocomplete-2.4.4.min.js vendored Normal file

File diff suppressed because one or more lines are too long

8
lib/jquery.cookie-1.4.0.min.js vendored Normal file
View file

@ -0,0 +1,8 @@
/*!
* jQuery Cookie Plugin v1.4.0
* https://github.com/carhartl/jquery-cookie
*
* Copyright 2013 Klaus Hartl
* Released under the MIT license
*/
(function(e){if(typeof define==="function"&&define.amd){define(["jquery"],e)}else{e(jQuery)}})(function(e){function n(e){return u.raw?e:encodeURIComponent(e)}function r(e){return u.raw?e:decodeURIComponent(e)}function i(e){return n(u.json?JSON.stringify(e):String(e))}function s(e){if(e.indexOf('"')===0){e=e.slice(1,-1).replace(/\\"/g,'"').replace(/\\\\/g,"\\")}try{e=decodeURIComponent(e.replace(t," "))}catch(n){return}try{return u.json?JSON.parse(e):e}catch(n){}}function o(t,n){var r=u.raw?t:s(t);return e.isFunction(n)?n(r):r}var t=/\+/g;var u=e.cookie=function(t,s,a){if(s!==undefined&&!e.isFunction(s)){a=e.extend({},u.defaults,a);if(typeof a.expires==="number"){var f=a.expires,l=a.expires=new Date;l.setDate(l.getDate()+f)}return document.cookie=[n(t),"=",i(s),a.expires?"; expires="+a.expires.toUTCString():"",a.path?"; path="+a.path:"",a.domain?"; domain="+a.domain:"",a.secure?"; secure":""].join("")}var c=t?undefined:{};var h=document.cookie?document.cookie.split("; "):[];for(var p=0,d=h.length;p<d;p++){var v=h[p].split("=");var m=r(v.shift());var g=v.join("=");if(t&&t===m){c=o(g,s);break}if(!t&&(g=o(g))!==undefined){c[m]=g}}return c};u.defaults={};e.removeCookie=function(t,n){if(e.cookie(t)!==undefined){e.cookie(t,"",e.extend({},n,{expires:-1}));return true}return false}});

View file

@ -1 +0,0 @@
jQuery.cookie=function(b,j,m){if(typeof j!="undefined"){m=m||{};if(j===null){j="";m=$.extend({},m);m.expires=-1}var e="";if(m.expires&&(typeof m.expires=="number"||m.expires.toUTCString)){var f;if(typeof m.expires=="number"){f=new Date();f.setTime(f.getTime()+(m.expires*24*60*60*1000))}else{f=m.expires}e="; expires="+f.toUTCString()}var l=m.path?"; path="+(m.path):"";var g=m.domain?"; domain="+(m.domain):"";var a=m.secure?"; secure":"";document.cookie=[b,"=",encodeURIComponent(j),e,l,g,a].join("")}else{var d=null;if(document.cookie&&document.cookie!=""){var k=document.cookie.split(";");for(var h=0;h<k.length;h++){var c=jQuery.trim(k[h]);if(c.substring(0,b.length+1)==(b+"=")){d=decodeURIComponent(c.substring(b.length+1));break}}}return d}};

File diff suppressed because one or more lines are too long

2
lib/jquery.imgnotes-1.0.min.css vendored Normal file
View file

@ -0,0 +1,2 @@
/** imgnotes jQuery plugin v1.0.0 **/
.notesicon{background:url(notes.png) no-repeat #fff;overflow:hidden;position:absolute;height:27px;width:22px;z-index:1000000;cursor:pointer}.note{display:none;background:url(spacer.gif);border:2px solid #fff;overflow:hidden;position:absolute;z-index:0;cursor:default}.notep{display:none;background:#eee;font-size:8pt;margin-top:0;padding:2px;position:absolute;width:175px;cursor:default}#noteform{display:none;position:absolute;width:250px}#noteform textarea{width:100%}

15
lib/jquery.imgnotes-1.0.min.js vendored Normal file
View file

@ -0,0 +1,15 @@
/**
* imgnotes jQuery plugin
* version 1.0
*
* Copyright (c) 2008 - Dr. Tarique Sani <tarique@sanisoft.com>
*
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
* @URL http://www.sanisoft.com/blog/2008/05/26/img-notes-jquery-plugin/
* @Example example.html
*
**/
(function(e){function t(){e(".note").hover(function(){e(".note").show();e(this).next(".notep").show();e(this).next(".notep").css("z-index",1e4)},function(){e(".note").show();e(this).next(".notep").hide();e(this).next(".notep").css("z-index",0)})}function n(t){note_left=parseInt(imgOffset.left)+parseInt(t.x1);note_top=parseInt(imgOffset.top)+parseInt(t.y1);note_p_top=note_top+parseInt(t.height)+5;note_area_div=e("<div class='note'></div>").css({left:note_left+"px",top:note_top+"px",width:t.width+"px",height:t.height+"px"});note_text_div=e('<div class="notep" >'+t.note+"</div>").css({left:note_left+"px",top:note_p_top+"px"});e("body").append(note_area_div);e("body").append(note_text_div)}function r(t){if(true!==t){return}notes_icon_left=parseInt(imgOffset.left)+parseInt(imgWidth)-36;notes_icon_top=parseInt(imgOffset.top)+parseInt(imgHieght)-40;notes_icon_div=note_area_div=e("<div class='notesicon'></div>").css({left:notes_icon_left+"px",top:notes_icon_top+"px"});e("body").append(notes_icon_div);e(".notesicon").toggle(function(){e.fn.imgNotes.showAll()},function(){e.fn.imgNotes.hideAll()})}e.fn.imgNotes=function(i){if(undefined==s){var s}if(undefined!=i.notes){s=i.notes}if(i.url){e.ajaxSetup({async:false});e.getJSON(i.url,function(e){s=e})}image=this;imgOffset=e(image).offset();imgHieght=e(image).height();imgWidth=e(image).width();e(s).each(function(){n(this)});e(image).hover(function(){e(".note").show()},function(){e(".note").hide();e(".notep").hide()});t();r(i.isMobile);e(window).resize(function(){e(".note").remove();e(".notep").remove();e(".notesicon").remove();imgOffset=e(image).offset();imgHieght=e(image).height();imgWidth=e(image).width();e(s).each(function(){n(this)});t();r(i.isMobile)})};e.fn.imgNotes.showAll=function(){e(".note").show();e(".notep").show()};e.fn.imgNotes.hideAll=function(){e(".note").hide();e(".notep").hide()}})(jQuery);

View file

@ -1,15 +0,0 @@
/*
* Lazy Load - jQuery plugin for lazy loading images
*
* Copyright (c) 2007-2012 Mika Tuupola
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/mit-license.php
*
* Project home:
* http://www.appelsiini.net/projects/lazyload
*
* Version: 1.7.2
*
*/
(function(a,b){$window=a(b),a.fn.lazyload=function(c){function f(){var b=0;d.each(function(){var c=a(this);if(e.skip_invisible&&!c.is(":visible"))return;if(!a.abovethetop(this,e)&&!a.leftofbegin(this,e))if(!a.belowthefold(this,e)&&!a.rightoffold(this,e))c.trigger("appear");else if(++b>e.failure_limit)return!1})}var d=this,e={threshold:0,failure_limit:0,event:"scroll",effect:"show",container:b,data_attribute:"original",skip_invisible:!0,appear:null,load:null};return c&&(undefined!==c.failurelimit&&(c.failure_limit=c.failurelimit,delete c.failurelimit),undefined!==c.effectspeed&&(c.effect_speed=c.effectspeed,delete c.effectspeed),a.extend(e,c)),$container=e.container===undefined||e.container===b?$window:a(e.container),0===e.event.indexOf("scroll")&&$container.bind(e.event,function(a){return f()}),this.each(function(){var b=this,c=a(b);b.loaded=!1,c.one("appear",function(){if(!this.loaded){if(e.appear){var f=d.length;e.appear.call(b,f,e)}a("<img />").bind("load",function(){c.hide().attr("src",c.data(e.data_attribute))[e.effect](e.effect_speed),b.loaded=!0;var f=a.grep(d,function(a){return!a.loaded});d=a(f);if(e.load){var g=d.length;e.load.call(b,g,e)}}).attr("src",c.data(e.data_attribute))}}),0!==e.event.indexOf("scroll")&&c.bind(e.event,function(a){b.loaded||c.trigger("appear")})}),$window.bind("resize",function(a){f()}),f(),this},a.belowthefold=function(c,d){var e;return d.container===undefined||d.container===b?e=$window.height()+$window.scrollTop():e=$container.offset().top+$container.height(),e<=a(c).offset().top-d.threshold},a.rightoffold=function(c,d){var e;return d.container===undefined||d.container===b?e=$window.width()+$window.scrollLeft():e=$container.offset().left+$container.width(),e<=a(c).offset().left-d.threshold},a.abovethetop=function(c,d){var e;return d.container===undefined||d.container===b?e=$window.scrollTop():e=$container.offset().top,e>=a(c).offset().top+d.threshold+a(c).height()},a.leftofbegin=function(c,d){var e;return d.container===undefined||d.container===b?e=$window.scrollLeft():e=$container.offset().left,e>=a(c).offset().left+d.threshold+a(c).width()},a.inviewport=function(b,c){return!a.rightofscreen(b,c)&&!a.leftofscreen(b,c)&&!a.belowthefold(b,c)&&!a.abovethetop(b,c)},a.extend(a.expr[":"],{"below-the-fold":function(c){return a.belowthefold(c,{threshold:0,container:b})},"above-the-top":function(c){return!a.belowthefold(c,{threshold:0,container:b})},"right-of-screen":function(c){return a.rightoffold(c,{threshold:0,container:b})},"left-of-screen":function(c){return!a.rightoffold(c,{threshold:0,container:b})},"in-viewport":function(c){return!a.inviewport(c,{threshold:0,container:b})},"above-the-fold":function(c){return!a.belowthefold(c,{threshold:0,container:b})},"right-of-fold":function(c){return a.rightoffold(c,{threshold:0,container:b})},"left-of-fold":function(c){return!a.rightoffold(c,{threshold:0,container:b})}})})(jQuery,window);

View file

@ -1,386 +0,0 @@
/*
* imgAreaSelect jQuery plugin
* version 0.4
*
* Copyright (c) 2008 Michal Wojciechowski (odyniec.net)
*
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
* http://odyniec.net/projects/imgareaselect/
*
*/
jQuery.imgAreaSelect = function (img, options) {
var $area = jQuery('<div></div>'),
$border1 = jQuery('<div></div>'),
$border2 = jQuery('<div></div>'),
$outLeft = jQuery('<div></div>'),
$outTop = jQuery('<div></div>'),
$outRight = jQuery('<div></div>'),
$outBottom = jQuery('<div></div>'),
imgOfs, imgWidth, imgHeight,
zIndex = 0, fixed = false,
startX, startY, moveX, moveY,
resizeMargin = 10, resize = [ ], V = 0, H = 1,
d, aspectRatio,
x1, x2, y1, y2, x, y,
selection = { x1: 0, y1: 0, x2: 0, y2: 0, width: 0, height: 0 };
var $a = $area.add($border1).add($border2);
var $o = $outLeft.add($outTop).add($outRight).add($outBottom);
function getZIndex()
{
var $p = jQuery(img);
while ($p.length && !$p.is('body')) {
if (!isNaN($p.css('z-index')) && $p.css('z-index') > zIndex)
zIndex = $p.css('z-index');
if ($p.css('position') == 'fixed') fixed = true;
$p = $p.parent();
}
}
function areaMouseMove(event)
{
x = event.pageX - selection.x1 - imgOfs.left;
y = event.pageY - selection.y1 - imgOfs.top;
resize = [ ];
if (options.resizable) {
if (y <= resizeMargin)
resize[V] = 'n';
else if (y >= selection.height - resizeMargin)
resize[V] = 's';
if (x <= resizeMargin)
resize[H] = 'w';
else if (x >= selection.width - resizeMargin)
resize[H] = 'e';
}
$border2.css('cursor', resize.length ? resize.join('') + '-resize' :
options.movable ? 'move' : '');
}
function areaMouseDown(event)
{
if (event.which != 1) return false;
if (options.resizable && resize.length > 0) {
jQuery('body').css('cursor', resize.join('') + '-resize');
x1 = (resize[H] == 'w' ? selection.x2 : selection.x1) + imgOfs.left;
y1 = (resize[V] == 'n' ? selection.y2 : selection.y1) + imgOfs.top;
jQuery(document).mousemove(selectingMouseMove);
$border2.unbind('mousemove', areaMouseMove);
jQuery(document).one('mouseup', function () {
resize = [ ];
jQuery('body').css('cursor', '');
if (options.autoHide)
$a.hide();
options.onSelectEnd(img, selection);
jQuery(document).unbind('mousemove', selectingMouseMove);
$border2.mousemove(areaMouseMove);
});
}
else if (options.movable) {
moveX = selection.x1 + imgOfs.left;
moveY = selection.y1 + imgOfs.top;
startX = event.pageX;
startY = event.pageY;
jQuery(document)
.mousemove(movingMouseMove)
.one('mouseup', function () {
options.onSelectEnd(img, selection);
jQuery(document).unbind('mousemove', movingMouseMove);
});
}
else
jQuery(img).mousedown(event);
return false;
}
function aspectRatioXY()
{
x2 = Math.max(imgOfs.left, Math.min(imgOfs.left + imgWidth,
x1 + Math.abs(y2 - y1) * aspectRatio * (x2 > x1 ? 1 : -1)));
y2 = Math.round(Math.max(imgOfs.top, Math.min(imgOfs.top + imgHeight,
y1 + Math.abs(x2 - x1) / aspectRatio * (y2 > y1 ? 1 : -1))));
x2 = Math.round(x2);
}
function aspectRatioYX()
{
y2 = Math.max(imgOfs.top, Math.min(imgOfs.top + imgHeight,
y1 + Math.abs(x2 - x1) / aspectRatio * (y2 > y1 ? 1 : -1)));
x2 = Math.round(Math.max(imgOfs.left, Math.min(imgOfs.left + imgWidth,
x1 + Math.abs(y2 - y1) * aspectRatio * (x2 > x1 ? 1 : -1))));
y2 = Math.round(y2);
}
function selectingMouseMove(event)
{
x2 = !resize.length || resize[H] || aspectRatio ? event.pageX : selection.x2 + imgOfs.left;
y2 = !resize.length || resize[V] || aspectRatio ? event.pageY : selection.y2 + imgOfs.top;
if (options.minWidth && Math.abs(x2 - x1) < options.minWidth) {
x2 = x1 - options.minWidth * (x2 < x1 ? 1 : -1);
if (x2 < imgOfs.left)
x1 = imgOfs.left + options.minWidth;
else if (x2 > imgOfs.left + imgWidth)
x1 = imgOfs.left + imgWidth - options.minWidth;
}
if (options.minHeight && Math.abs(y2 - y1) < options.minHeight) {
y2 = y1 - options.minHeight * (y2 < y1 ? 1 : -1);
if (y2 < imgOfs.top)
y1 = imgOfs.top + options.minHeight;
else if (y2 > imgOfs.top + imgHeight)
y1 = imgOfs.top + imgHeight - options.minHeight;
}
x2 = Math.max(imgOfs.left, Math.min(x2, imgOfs.left + imgWidth));
y2 = Math.max(imgOfs.top, Math.min(y2, imgOfs.top + imgHeight));
if (aspectRatio)
if (Math.abs(x2 - x1) / aspectRatio > Math.abs(y2 - y1))
aspectRatioYX();
else
aspectRatioXY();
if (options.maxWidth && Math.abs(x2 - x1) > options.maxWidth) {
x2 = x1 - options.maxWidth * (x2 < x1 ? 1 : -1);
if (aspectRatio) aspectRatioYX();
}
if (options.maxHeight && Math.abs(y2 - y1) > options.maxHeight) {
y2 = y1 - options.maxHeight * (y2 < y1 ? 1 : -1);
if (aspectRatio) aspectRatioXY();
}
selection.x1 = Math.min(x1, x2) - imgOfs.left;
selection.x2 = Math.max(x1, x2) - imgOfs.left;
selection.y1 = Math.min(y1, y2) - imgOfs.top;
selection.y2 = Math.max(y1, y2) - imgOfs.top;
selection.width = Math.abs(x2 - x1);
selection.height = Math.abs(y2 - y1);
$a.css({
left: (selection.x1 + imgOfs.left) + 'px',
top: (selection.y1 + imgOfs.top) + 'px',
width: Math.max(selection.width - options.borderWidth * 2, 0) + 'px',
height: Math.max(selection.height - options.borderWidth * 2, 0) + 'px'
});
$outLeft.css({ width: selection.x1 + 'px' });
$outTop.css({ left: imgOfs.left + selection.x1 + 'px', width: selection.width + 'px',
height: selection.y1 + 'px' });
$outRight.css({ left: imgOfs.left + selection.x2 + 'px', width: imgWidth - selection.x2 + 'px' });
$outBottom.css({ left: imgOfs.left + selection.x1 + 'px', top: imgOfs.top + selection.y2 + 'px',
width: selection.width + 'px', height: imgHeight - selection.y2 + 'px' });
options.onSelectChange(img, selection);
return false;
}
function movingMouseMove(event)
{
x1 = Math.max(imgOfs.left, Math.min(moveX + event.pageX - startX,
imgOfs.left + imgWidth - selection.width));
y1 = Math.max(imgOfs.top, Math.min(moveY + event.pageY - startY,
imgOfs.top + imgHeight - selection.height));
x2 = x1 + selection.width;
y2 = y1 + selection.height;
selection.x1 = x1 - imgOfs.left;
selection.y1 = y1 - imgOfs.top;
selection.x2 = x2 - imgOfs.left;
selection.y2 = y2 - imgOfs.top;
$a.css({
left: x1 + 'px',
top: y1 + 'px',
width: Math.max(x2 - x1 - options.borderWidth * 2, 0) + 'px',
height: Math.max(y2 - y1 - options.borderWidth * 2, 0) + 'px'
});
$outLeft.css({ width: selection.x1 + 'px' });
$outTop.css({ left: imgOfs.left + selection.x1 + 'px', width: selection.width + 'px',
height: selection.y1 + 'px' });
$outRight.css({ left: imgOfs.left + selection.x2 + 'px', width: imgWidth - selection.x2 + 'px' });
$outBottom.css({ left: imgOfs.left + selection.x1 + 'px', top: imgOfs.top + selection.y2 + 'px',
width: selection.width + 'px', height: imgHeight - selection.y2 + 'px' });
options.onSelectChange(img, selection);
event.preventDefault();
return false;
}
function imgMouseDown(event)
{
if (event.which != 1) return false;
startX = x1 = event.pageX;
startY = y1 = event.pageY;
resize = [ ];
$a.css({ width: '0px', height: '0px', left: x1, top: y1 });
$outLeft.css({ width: x1 - imgOfs.left + 'px' });
$outTop.css({ left: x1 + 'px', height: y1 - imgOfs.top + 'px', width: '0px' });
$outRight.css({ left: x1 + 'px', width: imgOfs.left + imgWidth - x1 + 'px' });
$outBottom.css({ left: x1 + 'px', top: y1 + 'px', width: '0px', height: imgOfs.top + imgHeight - y1 + 'px' });
$a.add($o).show();
jQuery(document).mousemove(selectingMouseMove);
$border2.unbind('mousemove', areaMouseMove);
selection.x1 = selection.x2 = x1 - imgOfs.left;
selection.y1 = selection.y2 = y1 - imgOfs.top;
options.onSelectStart(img, selection);
jQuery(document).one('mouseup', function () {
if (options.autoHide)
$a.add($o).hide();
options.onSelectEnd(img, selection);
jQuery(document).unbind('mousemove', selectingMouseMove);
$border2.mousemove(areaMouseMove);
});
return false;
}
this.setOptions = function(newOptions)
{
options = jQuery.extend(options, newOptions);
if (newOptions.x1 != null) {
x1 = (selection.x1 = newOptions.x1) + imgOfs.left;
y1 = (selection.y1 = newOptions.y1) + imgOfs.top;
x2 = (selection.x2 = newOptions.x2) + imgOfs.left;
y2 = (selection.y2 = newOptions.y2) + imgOfs.top;
selection.width = x2 - x1;
selection.height = y2 - y1;
$a.css({
left: x1 + 'px',
top: y1 + 'px',
width: Math.max(x2 - x1 - options.borderWidth * 2, 0) + 'px',
height: Math.max(y2 - y1 - options.borderWidth * 2, 0) + 'px'
});
$outLeft.css({ width: selection.x1 + 'px' });
$outTop.css({ left: x1 + 'px', width: selection.width + 'px', height: selection.y1 + 'px' });
$outRight.css({ left: x2 + 'px', width: (imgWidth - selection.x2) + 'px' });
$outBottom.css({ left: x1 + 'px', top: y2 + 'px', width: selection.width + 'px', height: (imgHeight - selection.y2) + 'px' });
$a.add($o).show();
options.onSelectChange(img, selection);
}
if (newOptions.hide) {
$a.hide();
$outLeft.hide();
$outRight.hide();
$outTop.hide();
$outBottom.hide();
} else if (newOptions.show) {
$a.show();
$outLeft.hide();
$outRight.hide();
$outTop.hide();
$outBottom.hide();
}
$a.css({ borderWidth: options.borderWidth + 'px' });
$area.css({ backgroundColor: options.selectionColor, opacity: options.selectionOpacity });
$border1.css({ borderStyle: 'solid', borderColor: options.borderColor1 });
$border2.css({ borderStyle: 'dashed', borderColor: options.borderColor2 });
$o.css({ opacity: options.outerOpacity, backgroundColor: options.outerColor });
aspectRatio = options.aspectRatio && (d = options.aspectRatio.split(/:/)) ?
d[0] / d[1] : null;
if (options.disable || options.enable === false) {
$a.unbind('mousemove', areaMouseMove).unbind('mousedown', areaMouseDown);
jQuery(img).add($o).unbind('mousedown', imgMouseDown);
}
else if (options.enable || options.disable === false) {
if (options.resizable || options.movable)
$a.mousemove(areaMouseMove).mousedown(areaMouseDown);
//jQuery(img).add($o).mousedown(imgMouseDown);
}
options.enable = options.disable = undefined;
};
imgWidth = jQuery(img).width();
imgHeight = jQuery(img).height();
imgOfs = jQuery(img).offset();
if (jQuery.browser.msie)
jQuery(img).attr('unselectable', 'on');
getZIndex();
$a.add($o).css({ display: 'none', position: fixed ? 'fixed' : 'absolute', overflow: 'hidden', zIndex: zIndex });
$area.css({ borderStyle: 'solid' });
$outLeft.css({ left: imgOfs.left + 'px', top: imgOfs.top + 'px', height: imgHeight + 'px' });
$outTop.css({ top: imgOfs.top + 'px' });
$outRight.css({ top: imgOfs.top + 'px', height: imgHeight + 'px' });
jQuery('body').append($o);
jQuery('body').append($a);
initOptions = {
borderColor1: '#000',
borderColor2: '#fff',
borderWidth: 1,
movable: true,
resizable: true,
selectionColor: '#fff',
selectionOpacity: 0.2,
outerColor: '#000',
outerOpacity: 0.2,
onSelectStart: function () {},
onSelectChange: function () {},
onSelectEnd: function () {}
};
options = jQuery.extend(initOptions, options);
this.setOptions(options);
};
jQuery.fn.imgAreaSelect = function (options) {
options = options || {};
this.each(function () {
if (jQuery(this).data('imgAreaSelect')){
jQuery(this).data('imgAreaSelect').setOptions(options);
} else {
if (options.enable === undefined && options.disable === undefined)
options.enable = true;
jQuery(this).data('imgAreaSelect', new jQuery.imgAreaSelect(this, options));
}
});
return this;
};

View file

@ -1,91 +0,0 @@
/**
* imgnotes jQuery plugin
* version 0.1
*
* Copyright (c) 2008 Dr. Tarique Sani <tarique@sanisoft.com>
*
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
* @URL http://www.sanisoft.com/blog/2008/05/26/img-notes-jquery-plugin/
* @Example example.html
*
**/
//Wrap in a closure
(function($) {
$.fn.imgNotes = function(n) {
if(undefined != n){
notes = n;
}
image = this;
imgOffset = $(image).offset();
$(notes).each(function(){
appendnote(this);
});
$(image).hover(
function(){
$('.note').show();
},
function(){
$('.note').hide();
}
);
addnoteevents();
$(window).resize(function () {
$('.note').remove();
imgOffset = $(image).offset();
$(notes).each(function(){
appendnote(this);
});
addnoteevents();
});
}
function addnoteevents() {
$('.note').hover(
function(){
$('.note').show();
$(this).next('.notep').show();
$(this).next('.notep').css("z-index", 10000);
},
function(){
$('.note').show();
$(this).next('.notep').hide();
$(this).next('.notep').css("z-index", 0);
}
);
}
function appendnote(note_data){
note_left = parseInt(imgOffset.left) + parseInt(note_data.x1);
note_top = parseInt(imgOffset.top) + parseInt(note_data.y1);
note_p_top = note_top + parseInt(note_data.height)+5;
note_area_div = $("<div class='note'></div>").css({ left: note_left + 'px', top: note_top + 'px', width: note_data.width + 'px', height: note_data.height + 'px' });
note_text_div = $('<div class="notep" >'+ note_data.note.replace(/([^>]?)\n/g, '$1<br />\n') + '</div>').css({ left: note_left + 'px', top: note_p_top + 'px'});
//added by alpha
note_id_div = $('<div class="noteID" >'+note_data.note_id+'</div>').css({ left: note_left + 'px', top: note_p_top + 'px'}).hide();
$('body').append(note_area_div);
$('body').append(note_text_div);
//added by alpha
$('body').append(note_id_div);
}
// End the closure
})(jQuery);

2
lib/jquery.tablesorter-2.0.5.min.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,189 +0,0 @@
/**
* Timeago is a jQuery plugin that makes it easy to support automatically
* updating fuzzy timestamps (e.g. "4 minutes ago" or "about 1 day ago").
*
* @name timeago
* @version 1.1.0
* @requires jQuery v1.2.3+
* @author Ryan McGeary
* @license MIT License - http://www.opensource.org/licenses/mit-license.php
*
* For usage and examples, visit:
* http://timeago.yarp.com/
*
* Copyright (c) 2008-2013, Ryan McGeary (ryan -[at]- mcgeary [*dot*] org)
*/
(function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['jquery'], factory);
} else {
// Browser globals
factory(jQuery);
}
}(function ($) {
$.timeago = function(timestamp) {
if (timestamp instanceof Date) {
return inWords(timestamp);
} else if (typeof timestamp === "string") {
return inWords($.timeago.parse(timestamp));
} else if (typeof timestamp === "number") {
return inWords(new Date(timestamp));
} else {
return inWords($.timeago.datetime(timestamp));
}
};
var $t = $.timeago;
$.extend($.timeago, {
settings: {
refreshMillis: 60000,
allowFuture: false,
localeTitle: false,
cutoff: 0,
strings: {
prefixAgo: null,
prefixFromNow: null,
suffixAgo: "ago",
suffixFromNow: "from now",
seconds: "less than a minute",
minute: "about a minute",
minutes: "%d minutes",
hour: "about an hour",
hours: "about %d hours",
day: "a day",
days: "%d days",
month: "about a month",
months: "%d months",
year: "about a year",
years: "%d years",
wordSeparator: " ",
numbers: []
}
},
inWords: function(distanceMillis) {
var $l = this.settings.strings;
var prefix = $l.prefixAgo;
var suffix = $l.suffixAgo;
if (this.settings.allowFuture) {
if (distanceMillis < 0) {
prefix = $l.prefixFromNow;
suffix = $l.suffixFromNow;
}
}
var seconds = Math.abs(distanceMillis) / 1000;
var minutes = seconds / 60;
var hours = minutes / 60;
var days = hours / 24;
var years = days / 365;
function substitute(stringOrFunction, number) {
var string = $.isFunction(stringOrFunction) ? stringOrFunction(number, distanceMillis) : stringOrFunction;
var value = ($l.numbers && $l.numbers[number]) || number;
return string.replace(/%d/i, value);
}
var words = seconds < 45 && substitute($l.seconds, Math.round(seconds)) ||
seconds < 90 && substitute($l.minute, 1) ||
minutes < 45 && substitute($l.minutes, Math.round(minutes)) ||
minutes < 90 && substitute($l.hour, 1) ||
hours < 24 && substitute($l.hours, Math.round(hours)) ||
hours < 42 && substitute($l.day, 1) ||
days < 30 && substitute($l.days, Math.round(days)) ||
days < 45 && substitute($l.month, 1) ||
days < 365 && substitute($l.months, Math.round(days / 30)) ||
years < 1.5 && substitute($l.year, 1) ||
substitute($l.years, Math.round(years));
var separator = $l.wordSeparator || "";
if ($l.wordSeparator === undefined) { separator = " "; }
return $.trim([prefix, words, suffix].join(separator));
},
parse: function(iso8601) {
var s = $.trim(iso8601);
s = s.replace(/\.\d+/,""); // remove milliseconds
s = s.replace(/-/,"/").replace(/-/,"/");
s = s.replace(/T/," ").replace(/Z/," UTC");
s = s.replace(/([\+\-]\d\d)\:?(\d\d)/," $1$2"); // -04:00 -> -0400
return new Date(s);
},
datetime: function(elem) {
var iso8601 = $t.isTime(elem) ? $(elem).attr("datetime") : $(elem).attr("title");
return $t.parse(iso8601);
},
isTime: function(elem) {
// jQuery's `is()` doesn't play well with HTML5 in IE
return $(elem).get(0).tagName.toLowerCase() === "time"; // $(elem).is("time");
}
});
// functions that can be called via $(el).timeago('action')
// init is default when no action is given
// functions are called with context of a single element
var functions = {
init: function(){
var refresh_el = $.proxy(refresh, this);
refresh_el();
var $s = $t.settings;
if ($s.refreshMillis > 0) {
setInterval(refresh_el, $s.refreshMillis);
}
},
update: function(time){
$(this).data('timeago', { datetime: $t.parse(time) });
refresh.apply(this);
}
};
$.fn.timeago = function(action, options) {
var fn = action ? functions[action] : functions.init;
if(!fn){
throw new Error("Unknown function name '"+ action +"' for timeago");
}
// each over objects here and call the requested function
this.each(function(){
fn.call(this, options);
});
return this;
};
function refresh() {
var data = prepareData(this);
var $s = $t.settings;
if (!isNaN(data.datetime)) {
if ( $s.cutoff == 0 || distance(data.datetime) < $s.cutoff) {
$(this).text(inWords(data.datetime));
}
}
return this;
}
function prepareData(element) {
element = $(element);
if (!element.data("timeago")) {
element.data("timeago", { datetime: $t.datetime(element) });
var text = $.trim(element.text());
if ($t.settings.localeTitle) {
element.attr("title", element.data('timeago').datetime.toLocaleString());
} else if (text.length > 0 && !($t.isTime(element) && element.attr("title"))) {
element.attr("title", text);
}
}
return element.data("timeago");
}
function inWords(date) {
return $t.inWords(distance(date));
}
function distance(date) {
return (new Date().getTime() - date.getTime());
}
// fix for IE6 suckage
document.createElement("abbr");
document.createElement("time");
}));

17
lib/jquery.timeago-1.3.1.min.js vendored Normal file
View file

@ -0,0 +1,17 @@
/**
* Timeago is a jQuery plugin that makes it easy to support automatically
* updating fuzzy timestamps (e.g. "4 minutes ago" or "about 1 day ago").
*
* @name timeago
* @version 1.3.1
* @requires jQuery v1.2.3+
* @author Ryan McGeary
* @license MIT License - http://www.opensource.org/licenses/mit-license.php
*
* For usage and examples, visit:
* http://timeago.yarp.com/
*
* Copyright (c) 2008-2013, Ryan McGeary (ryan -[at]- mcgeary [*dot*] org)
*/
(function(e){if(typeof define==="function"&&define.amd){define(["jquery"],e)}else{e(jQuery)}})(function(e){function r(){var n=i(this);var r=t.settings;if(!isNaN(n.datetime)){if(r.cutoff==0||o(n.datetime)<r.cutoff){e(this).text(s(n.datetime))}}return this}function i(n){n=e(n);if(!n.data("timeago")){n.data("timeago",{datetime:t.datetime(n)});var r=e.trim(n.text());if(t.settings.localeTitle){n.attr("title",n.data("timeago").datetime.toLocaleString())}else if(r.length>0&&!(t.isTime(n)&&n.attr("title"))){n.attr("title",r)}}return n.data("timeago")}function s(e){return t.inWords(o(e))}function o(e){return(new Date).getTime()-e.getTime()}e.timeago=function(t){if(t instanceof Date){return s(t)}else if(typeof t==="string"){return s(e.timeago.parse(t))}else if(typeof t==="number"){return s(new Date(t))}else{return s(e.timeago.datetime(t))}};var t=e.timeago;e.extend(e.timeago,{settings:{refreshMillis:6e4,allowFuture:false,localeTitle:false,cutoff:0,strings:{prefixAgo:null,prefixFromNow:null,suffixAgo:"ago",suffixFromNow:"from now",seconds:"less than a minute",minute:"about a minute",minutes:"%d minutes",hour:"about an hour",hours:"about %d hours",day:"a day",days:"%d days",month:"about a month",months:"%d months",year:"about a year",years:"%d years",wordSeparator:" ",numbers:[]}},inWords:function(t){function l(r,i){var s=e.isFunction(r)?r(i,t):r;var o=n.numbers&&n.numbers[i]||i;return s.replace(/%d/i,o)}var n=this.settings.strings;var r=n.prefixAgo;var i=n.suffixAgo;if(this.settings.allowFuture){if(t<0){r=n.prefixFromNow;i=n.suffixFromNow}}var s=Math.abs(t)/1e3;var o=s/60;var u=o/60;var a=u/24;var f=a/365;var c=s<45&&l(n.seconds,Math.round(s))||s<90&&l(n.minute,1)||o<45&&l(n.minutes,Math.round(o))||o<90&&l(n.hour,1)||u<24&&l(n.hours,Math.round(u))||u<42&&l(n.day,1)||a<30&&l(n.days,Math.round(a))||a<45&&l(n.month,1)||a<365&&l(n.months,Math.round(a/30))||f<1.5&&l(n.year,1)||l(n.years,Math.round(f));var h=n.wordSeparator||"";if(n.wordSeparator===undefined){h=" "}return e.trim([r,c,i].join(h))},parse:function(t){var n=e.trim(t);n=n.replace(/\.\d+/,"");n=n.replace(/-/,"/").replace(/-/,"/");n=n.replace(/T/," ").replace(/Z/," UTC");n=n.replace(/([\+\-]\d\d)\:?(\d\d)/," $1$2");return new Date(n)},datetime:function(n){var r=t.isTime(n)?e(n).attr("datetime"):e(n).attr("title");return t.parse(r)},isTime:function(t){return e(t).get(0).tagName.toLowerCase()==="time"}});var n={init:function(){var n=e.proxy(r,this);n();var i=t.settings;if(i.refreshMillis>0){setInterval(n,i.refreshMillis)}},update:function(n){e(this).data("timeago",{datetime:t.parse(n)});r.apply(this)}};e.fn.timeago=function(e,t){var r=e?n[e]:n.init;if(!r){throw new Error("Unknown function name '"+e+"' for timeago")}this.each(function(){r.call(this,t)});return this};document.createElement("abbr");document.createElement("time")})

File diff suppressed because one or more lines are too long

4
lib/modernizr-2.7.1.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -5,6 +5,8 @@ $(document).ready(function() {
jQuery.timeago.settings.cutoff = 365 * dayMS;
$("time").timeago();
//TODO: Possibly move to using TextExtJS for autocomplete? - http://textextjs.com/
// Also use autocomplete in tag box?
$('.autocomplete_tags').autocomplete(base_href + '/api/internal/tag_list/complete', {
width: 320,
max: 15,
@ -13,12 +15,10 @@ $(document).ready(function() {
multipleSeparator: ' ',
scroll: true,
scrollHeight: 300,
selectFirst: false
});
$("IMG.lazy").show().lazyload({
//effect: "fadeIn",
threshold: 200
selectFirst: false,
queryParamName: 's',
delay: 150,
minChars: 1
});
$("TABLE.sortable").tablesorter();

BIN
lib/spacer.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 B