diff --git a/data/config.ini b/data/config.ini index ec8b4010..0e3e4310 100644 --- a/data/config.ini +++ b/data/config.ini @@ -1,14 +1,11 @@ -[chibi] -enableCache=1 - [main] dbDriver = "sqlite" dbLocation = "./data/db.sqlite" dbUser = "test" dbPass = "test" filesPath = "./data/files/" -thumbsPath = "./data/thumbs/" -logsPath = "./data/logs/" +thumbsPath = "./public_html/thumbs/" +logsPath = "./data/logs/{yyyy}-{mm}.log" mediaPath = "./public_html/media/" title = "szurubooru" salt = "1A2/$_4xVa" @@ -17,6 +14,7 @@ salt = "1A2/$_4xVa" featuredPostMaxDays=7 debugQueries=0 logAnonymousUploads=1 +githubLink = http://github.com/rr-/szurubooru [help] title=Help @@ -42,6 +40,14 @@ showDislikedPostsDefault=1 maxSearchTokens=4 maxRelatedPosts=50 +[tags] +minLength = 1 +maxLength = 64 +regex = "/^[()\[\]a-zA-Z0-9_.-]+$/i" + +[posts] +maxSourceLength = 200 + [comments] minLength = 5 maxLength = 2000 @@ -70,17 +76,31 @@ passwordResetEmailSubject = "{host} - password reset" passwordResetEmailBody = "Hello,{nl}{nl}You received this e-mail because someone requested a password reset for user with this e-mail address at {host}. If it's you, visit {link} to finish password reset process, otherwise you may ignore and delete this e-mail.{nl}{nl}Kind regards,{nl}{host} mailing system" [privileges] -uploadPost=registered +registerAccount=anonymous +;registerAccount=nobody + listPosts=anonymous +listPosts.safe=anonymous listPosts.sketchy=registered listPosts.unsafe=registered listPosts.hidden=moderator viewPost=anonymous +viewPost.safe=anonymous viewPost.sketchy=registered viewPost.unsafe=registered viewPost.hidden=moderator retrievePost=anonymous favoritePost=registered + +addPost=registered +addPostSafety=registered +addPostTags=registered +addPostThumb=power-user +addPostSource=registered +addPostRelations=power-user +addPostContent=registered + +editPost=registered editPostSafety.own=registered editPostSafety.all=moderator editPostTags=registered @@ -88,7 +108,8 @@ editPostThumb=moderator editPostSource=moderator editPostRelations.own=registered editPostRelations.all=moderator -editPostFile=moderator +editPostContent=moderator + massTag.own=registered massTag.all=power-user hidePost=moderator @@ -99,16 +120,17 @@ flagPost=registered listUsers=registered viewUser=registered -viewUserEmail.all=admin viewUserEmail.own=registered -changeUserPassword.own=registered -changeUserPassword.all=admin -changeUserEmail.own=registered -changeUserEmail.all=admin -changeUserAccessRank=admin -changeUserName=moderator -changeUserSettings.all=nobody -changeUserSettings.own=registered +viewUserEmail.all=admin +editUserPassword.own=registered +editUserPassword.all=admin +editUserEmail.own=registered +editUserEmail.all=admin +editUserEmailNoConfirm=admin +editUserAccessRank=admin +editUserName=moderator +editUserSettings.own=registered +editUserSettings.all=nobody acceptUserRegistration=moderator banUser.own=nobody banUser.all=admin diff --git a/data/help.md b/data/help.md index 80a1d8b8..c0ff3a65 100644 --- a/data/help.md +++ b/data/help.md @@ -39,8 +39,8 @@ Command | Description [search]id:1,2,3[/search] | having specific post ID | `ids` | [search]idmin:5[/search] | posts with ID greater than or equal to @5 | `id_min` | [search]idmax:5[/search] | posts with ID less than or equal to @5 | `id_max` | -[search]type:img[/search] | only image posts | - | -[search]type:swf[/search] | only Flash posts | - | +[search]type:img[/search] | only image posts | `type:image` | +[search]type:flash[/search] | only Flash posts | `type:swf` | [search]type:yt[/search] | only Youtube posts | `type:youtube` | [search]special:liked[/search] | posts liked by currently logged in user | `special:likes`, `special:like` | [search]special:disliked[/search] | posts disliked by currently logged in user | `special:dislikes`, `special:dislike` | diff --git a/data/privacy.md b/data/privacy.md index 21ebc3e2..0b253a3e 100644 --- a/data/privacy.md +++ b/data/privacy.md @@ -8,4 +8,4 @@ Your actions related to posts (uploading, tagging, etc.) are logged, along with # Cookies -Cookies are used to store your session data and browsing preferences, such as endless scrolling or visibility of NSFW posts. +Cookies are used to store your session data in order to keep you logged in and personalize your web experience. diff --git a/init.php b/init.php index 6102642a..6849d60c 100644 --- a/init.php +++ b/init.php @@ -1,6 +1,6 @@ main->mediaPath . DS . 'fonts'); $libPath = TextHelper::absolutePath($config->main->mediaPath . DS . 'lib'); @@ -26,6 +26,9 @@ function download($source, $destination = null) return $content; } +$version = exec('git describe --tags --always --dirty'); +$branch = exec('git rev-parse --abbrev-ref HEAD'); +PropertyModel::set(PropertyModel::EngineVersion, $version . '@' . $branch); //jQuery diff --git a/lib/chibi-core b/lib/chibi-core index 45c662d0..a6c610e5 160000 --- a/lib/chibi-core +++ b/lib/chibi-core @@ -1 +1 @@ -Subproject commit 45c662d0a4b32e09399b5b68ac53aaa3f1a29911 +Subproject commit a6c610e5c68220cf672debe765752662807c0d39 diff --git a/lib/chibi-sql b/lib/chibi-sql index 22910a18..6bb18c1c 160000 --- a/lib/chibi-sql +++ b/lib/chibi-sql @@ -1 +1 @@ -Subproject commit 22910a186efbcb9bc86a3ae3eb6f4aff34096406 +Subproject commit 6bb18c1c6ed7ea952ae7a8dab792d5364a334201 diff --git a/public_html/.htaccess b/public_html/.htaccess index 725416c0..4dc8c6ec 100644 --- a/public_html/.htaccess +++ b/public_html/.htaccess @@ -1,10 +1,14 @@ DirectorySlash Off Options -Indexes +ErrorDocument 403 /fatal-error/403 +ErrorDocument 404 /fatal-error/404 +ErrorDocument 500 /fatal-error/500 + RewriteEngine On -ErrorDocument 403 /dispatch.php?request=error/http&code=403 -ErrorDocument 404 /dispatch.php?request=error/http&code=404 -ErrorDocument 500 /dispatch.php?request=error/http&code=500 +RewriteCond %{DOCUMENT_ROOT}/thumbs/$1.thumb -f +RewriteRule ^/?post/(.*)/thumb/?$ /thumbs/$1.thumb +RewriteRule ^/?thumbs/(.*).thumb - [L,T=image/jpeg] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d diff --git a/public_html/dispatch.php b/public_html/dispatch.php index 281f5100..7a8f9dd1 100644 --- a/public_html/dispatch.php +++ b/public_html/dispatch.php @@ -1,211 +1,5 @@ startTime = $startTime; -$context->query = $query; - -function renderView() -{ - $context = getContext(); - \Chibi\View::render($context->layoutName, $context); -} - -function getContext() -{ - global $context; - return $context; -} - -$context->simpleControllerName = null; -$context->simpleActionName = null; - -\Chibi\Router::setObserver(function($route, $args) -{ - $context = getContext(); - $context->route = $route; - list ($className, $methodName) = $route->destination; - - $context->simpleControllerName = TextCaseConverter::convert( - str_replace('Controller', '', $className), - TextCaseConverter::CAMEL_CASE, - TextCaseConverter::SPINAL_CASE); - - $context->simpleActionName = TextCaseConverter::convert( - str_replace('Action', '', $methodName), - TextCaseConverter::CAMEL_CASE, - TextCaseConverter::SPINAL_CASE); - - $context->viewName = sprintf( - '%s-%s', - $context->simpleControllerName, - $context->simpleActionName); -}); - -foreach (['GET', 'POST'] as $method) -{ - \Chibi\Router::register(['IndexController', 'indexAction'], $method, ''); - \Chibi\Router::register(['IndexController', 'indexAction'], $method, '/index'); - \Chibi\Router::register(['IndexController', 'helpAction'], $method, '/help'); - \Chibi\Router::register(['IndexController', 'helpAction'], $method, '/help/{tab}'); - \Chibi\Router::register(['LogController', 'listAction'], $method, '/logs'); - \Chibi\Router::register(['LogController', 'viewAction'], $method, '/log/{name}', ['name' => '[0-9a-zA-Z._-]+']); - \Chibi\Router::register(['LogController', 'viewAction'], $method, '/log/{name}/{page}', ['name' => '[0-9a-zA-Z._-]+', 'page' => '\d*']); - \Chibi\Router::register(['LogController', 'viewAction'], $method, '/log/{name}/{page}/{filter}', ['name' => '[0-9a-zA-Z._-]+', 'page' => '\d*', 'filter' => '.*']); - \Chibi\Router::register(['AuthController', 'loginAction'], $method, '/auth/login'); - \Chibi\Router::register(['AuthController', 'logoutAction'], $method, '/auth/logout'); - \Chibi\Router::register(['AuthController', 'loginAction'], 'POST', '/auth/login'); - \Chibi\Router::register(['AuthController', 'logoutAction'], 'POST', '/auth/logout'); - \Chibi\Router::register(['CommentController', 'listAction'], $method, '/comments'); - \Chibi\Router::register(['CommentController', 'listAction'], $method, '/comments/{page}', ['page' => '\d+']); - \Chibi\Router::register(['CommentController', 'addAction'], $method, '/post/{postId}/add-comment', ['postId' => '\d+']); - \Chibi\Router::register(['CommentController', 'deleteAction'], $method, '/comment/{id}/delete', ['id' => '\d+']); - \Chibi\Router::register(['CommentController', 'editAction'], $method, '/comment/{id}/edit', ['id' => '\d+']); - - $postValidation = - [ - 'tag' => '[^\/]*', - 'enable' => '0|1', - 'source' => 'posts|mass-tag', - 'query' => '[^\/]*', - 'additionalInfo' => '[^\/]*', - 'score' => '-1|0|1', - ]; - - \Chibi\Router::register(['PostController', 'uploadAction'], $method, '/posts/upload', $postValidation); - \Chibi\Router::register(['PostController', 'listAction'], $method, '/{source}', $postValidation); - \Chibi\Router::register(['PostController', 'listAction'], $method, '/{source}/{query}', $postValidation); - \Chibi\Router::register(['PostController', 'listAction'], $method, '/{source}/{query}/{page}', $postValidation); - \Chibi\Router::register(['PostController', 'listAction'], $method, '/{source}/{additionalInfo}/{query}/{page}', $postValidation); - \Chibi\Router::register(['PostController', 'toggleTagAction'], $method, '/post/{id}/toggle-tag/{tag}/{enable}', $postValidation); - \Chibi\Router::register(['PostController', 'favoritesAction'], $method, '/favorites', $postValidation); - \Chibi\Router::register(['PostController', 'favoritesAction'], $method, '/favorites/{page}', $postValidation); - \Chibi\Router::register(['PostController', 'upvotedAction'], $method, '/upvoted', $postValidation); - \Chibi\Router::register(['PostController', 'upvotedAction'], $method, '/upvoted/{page}', $postValidation); - \Chibi\Router::register(['PostController', 'randomAction'], $method, '/random', $postValidation); - \Chibi\Router::register(['PostController', 'randomAction'], $method, '/random/{page}', $postValidation); - \Chibi\Router::register(['PostController', 'viewAction'], $method, '/post/{id}', $postValidation); - \Chibi\Router::register(['PostController', 'retrieveAction'], $method, '/post/{name}/retrieve', $postValidation); - \Chibi\Router::register(['PostController', 'thumbAction'], $method, '/post/{name}/thumb', $postValidation); - \Chibi\Router::register(['PostController', 'removeFavoriteAction'], $method, '/post/{id}/rem-fav', $postValidation); - \Chibi\Router::register(['PostController', 'addFavoriteAction'], $method, '/post/{id}/add-fav', $postValidation); - \Chibi\Router::register(['PostController', 'deleteAction'], $method, '/post/{id}/delete', $postValidation); - \Chibi\Router::register(['PostController', 'hideAction'], $method, '/post/{id}/hide', $postValidation); - \Chibi\Router::register(['PostController', 'unhideAction'], $method, '/post/{id}/unhide', $postValidation); - \Chibi\Router::register(['PostController', 'editAction'], $method, '/post/{id}/edit', $postValidation); - \Chibi\Router::register(['PostController', 'flagAction'], $method, '/post/{id}/flag', $postValidation); - \Chibi\Router::register(['PostController', 'featureAction'], $method, '/post/{id}/feature', $postValidation); - \Chibi\Router::register(['PostController', 'scoreAction'], $method, '/post/{id}/score/{score}', $postValidation); - - $tagValidation = - [ - 'page' => '\d*', - 'filter' => '[^\/]+', - ]; - - \Chibi\Router::register(['TagController', 'listAction'], $method, '/tags', $tagValidation); - \Chibi\Router::register(['TagController', 'listAction'], $method, '/tags/{filter}', $tagValidation); - \Chibi\Router::register(['TagController', 'listAction'], $method, '/tags/{page}', $tagValidation); - \Chibi\Router::register(['TagController', 'listAction'], $method, '/tags/{filter}/{page}', $tagValidation); - \Chibi\Router::register(['TagController', 'autoCompleteAction'], $method, '/tags-autocomplete', $tagValidation); - \Chibi\Router::register(['TagController', 'relatedAction'], $method, '/tags-related', $tagValidation); - \Chibi\Router::register(['TagController', 'mergeAction'], $method, '/tags-merge', $tagValidation); - \Chibi\Router::register(['TagController', 'renameAction'], $method, '/tags-rename', $tagValidation); - \Chibi\Router::register(['TagController', 'massTagRedirectAction'], $method, '/mass-tag-redirect', $tagValidation); - - $userValidations = - [ - 'name' => '[^\/]+', - 'page' => '\d*', - 'tab' => 'favs|uploads', - 'filter' => '[^\/]+', - ]; - - \Chibi\Router::register(['UserController', 'registrationAction'], $method, '/register', $userValidations); - \Chibi\Router::register(['UserController', 'viewAction'], $method, '/user/{name}/{tab}', $userValidations); - \Chibi\Router::register(['UserController', 'viewAction'], $method, '/user/{name}/{tab}/{page}', $userValidations); - \Chibi\Router::register(['UserController', 'listAction'], $method, '/users', $userValidations); - \Chibi\Router::register(['UserController', 'listAction'], $method, '/users/{page}', $userValidations); - \Chibi\Router::register(['UserController', 'listAction'], $method, '/users/{filter}', $userValidations); - \Chibi\Router::register(['UserController', 'listAction'], $method, '/users/{filter}/{page}', $userValidations); - \Chibi\Router::register(['UserController', 'flagAction'], $method, '/user/{name}/flag', $userValidations); - \Chibi\Router::register(['UserController', 'banAction'], $method, '/user/{name}/ban', $userValidations); - \Chibi\Router::register(['UserController', 'unbanAction'], $method, '/user/{name}/unban', $userValidations); - \Chibi\Router::register(['UserController', 'acceptRegistrationAction'], $method, '/user/{name}/accept-registration', $userValidations); - \Chibi\Router::register(['UserController', 'deleteAction'], $method, '/user/{name}/delete', $userValidations); - \Chibi\Router::register(['UserController', 'settingsAction'], $method, '/user/{name}/settings', $userValidations); - \Chibi\Router::register(['UserController', 'editAction'], $method, '/user/{name}/edit', $userValidations); - \Chibi\Router::register(['UserController', 'activationAction'], $method, '/activation/{token}', $userValidations); - \Chibi\Router::register(['UserController', 'activationProxyAction'], $method, '/activation-proxy', $userValidations); - \Chibi\Router::register(['UserController', 'activationProxyAction'], $method, '/activation-proxy/{token}', $userValidations); - \Chibi\Router::register(['UserController', 'passwordResetAction'], $method, '/password-reset/{token}', $userValidations); - \Chibi\Router::register(['UserController', 'passwordResetProxyAction'], $method, '/password-reset-proxy', $userValidations); - \Chibi\Router::register(['UserController', 'passwordResetProxyAction'], $method, '/password-reset-proxy/{token}', $userValidations); - \Chibi\Router::register(['UserController', 'toggleSafetyAction'], $method, '/user/toggle-safety/{safety}', $userValidations); -} - -Assets::setTitle($config->main->title); - -$context->handleExceptions = false; -$context->json = isset($_GET['json']); -$context->layoutName = $context->json - ? 'layout-json' - : 'layout-normal'; -$context->viewName = ''; -$context->transport = new StdClass; - -session_start(); -if (!Auth::isLoggedIn()) - Auth::tryAutoLogin(); - -register_shutdown_function(function() -{ - $error = error_get_last(); - if ($error !== null) - \Chibi\Util\Headers::setCode(400); -}); - -try -{ - try - { - \Chibi\Router::run($query); - renderView(); - AuthController::observeWorkFinish(); - } - catch (\Chibi\UnhandledRouteException $e) - { - throw new SimpleNotFoundException($query . ' not found.'); - } -} -catch (\Chibi\MissingViewFileException $e) -{ - $context->json = true; - $context->layoutName = 'layout-json'; - renderView(); -} -catch (SimpleException $e) -{ - if ($e instanceof SimpleNotFoundException) - \Chibi\Util\Headers::setCode(404); - else - \Chibi\Util\Headers::setCode(400); - Messenger::message($e->getMessage(), false); - if (!$context->handleExceptions) - $context->viewName = 'message'; - renderView(); -} -catch (Exception $e) -{ - \Chibi\Util\Headers::setCode(400); - Messenger::message($e->getMessage()); - $context->transport->exception = $e; - $context->transport->queries = \Chibi\Database::getLogs(); - $context->viewName = 'error-exception'; - renderView(); -} +$dispatcher = new Dispatcher(); +$dispatcher->run(); diff --git a/public_html/media/css/core.css b/public_html/media/css/core.css index cff6ad70..e587f43e 100644 --- a/public_html/media/css/core.css +++ b/public_html/media/css/core.css @@ -145,6 +145,12 @@ footer span:not(:last-of-type):after { footer a { color: silver; } +footer .left { + float: left; +} +footer .right { + float: right; +} @@ -254,12 +260,12 @@ button { box-sizing: border-box !important; vertical-align: middle; line-height: 24px; - height: 34px; + padding: 3px 5px; + height: 30px; } label, input, select { - padding: 5px; font-family: inherit; font-size: 11pt; } @@ -290,7 +296,7 @@ button:hover { } .form-row { - margin: 0.25em 0; + margin: 0 0 0.5em 0; clear: left; } .input-wrapper { @@ -313,12 +319,19 @@ ul.tagit { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; + min-height: 32px; +} +ul.tagit li.tagit-new { + padding: 1px 0 !important; +} +ul.tagit li.tagit-choice { + padding: 1px 20px 1px 5px !important; } ul.tagit input { border: 0 !important; line-height: auto !important; height: auto !important; - margin: -4px 0 !important; + padding: 0 !important; } .related-tags { padding: 0.5em; diff --git a/public_html/media/css/post-upload.css b/public_html/media/css/post-upload.css index 61f6ecfe..64446bd7 100644 --- a/public_html/media/css/post-upload.css +++ b/public_html/media/css/post-upload.css @@ -74,7 +74,7 @@ .post .ops a { cursor: pointer; - margin-left: 0.5em; + margin-left: 1.5em; vertical-align: middle; } .post a span { @@ -117,11 +117,11 @@ .post .file-name strong { overflow: hidden; text-overflow: ellipsis; - max-width: 50%; + max-width: 100%; white-space: pre; display: inline-block; - vertical-align: middle; - padding: 0.5em 0; + vertical-align: text-bottom; + line-height: 30px; } .safety-safe { @@ -155,6 +155,9 @@ ul.tagit { .post .form-wrapper { overflow: hidden; } +.post form { + margin-top: 0; +} #lightbox { display: none; diff --git a/public_html/media/css/post-view.css b/public_html/media/css/post-view.css index 97be76a2..029b61df 100644 --- a/public_html/media/css/post-view.css +++ b/public_html/media/css/post-view.css @@ -23,13 +23,17 @@ embed { margin: 0; padding: 0; } -#sidebar .tags li { +#sidebar .tags li a { overflow: hidden; text-overflow: ellipsis; + display: inline-block; + max-width: 90%; + vertical-align: text-bottom; } #sidebar .tags li .count { padding-left: 0.5em; color: silver; + vertical-align: text-bottom; } #around { diff --git a/public_html/media/css/static-api.css b/public_html/media/css/static-api.css new file mode 100644 index 00000000..2a31b85a --- /dev/null +++ b/public_html/media/css/static-api.css @@ -0,0 +1,18 @@ +#content pre { + background: ghostwhite; + padding: 0.5em; + border-left: 0.2em solid silver; +} + +#content table { + border-spacing: 0; + border-collapse: collapsue; +} +#content th, +#content td { + text-align: left; + padding: 0.2em 0.5em; +} +#content tbody:nth-child(2n) { + background: #fafafa; +} diff --git a/public_html/media/css/index-help.css b/public_html/media/css/static-help.css similarity index 100% rename from public_html/media/css/index-help.css rename to public_html/media/css/static-help.css diff --git a/public_html/media/css/index-index.css b/public_html/media/css/static-main.css similarity index 100% rename from public_html/media/css/index-index.css rename to public_html/media/css/static-main.css diff --git a/public_html/media/js/comment-edit.js b/public_html/media/js/comment-edit.js index 5023067f..c8a3d920 100644 --- a/public_html/media/js/comment-edit.js +++ b/public_html/media/js/comment-edit.js @@ -20,7 +20,7 @@ $(function() formDom.addClass('inactive'); formDom.find(':input').attr('readonly', true); - var url = formDom.attr('action') + '?json'; + var url = formDom.attr('action'); var fd = new FormData(formDom[0]); var preview = false; @@ -36,7 +36,6 @@ $(function() data: fd, processData: false, contentType: false, - type: 'POST', success: function(data) { @@ -51,7 +50,7 @@ $(function() formDom.find('.preview').hide(); var cb = function() { - $.get(window.location.href, function(data) + $.get(window.location.href).success(function(data) { $('.comments-wrapper').replaceWith($(data).find('.comments-wrapper')); $('body').trigger('dom-update'); @@ -84,7 +83,7 @@ $(function() } }; - $.ajax(ajaxData); + postJSON(ajaxData); }); $('.comment .edit a').bindOnce('edit-comment', 'click', function(e) @@ -100,7 +99,7 @@ $(function() if (formDom.length == 0) { - $.get($(this).attr('href'), function(data) + $.get($(this).attr('href')).success(function(data) { var otherForm = $(data).find('form.edit-comment'); otherForm.hide(); diff --git a/public_html/media/js/core.js b/public_html/media/js/core.js index 41ff3972..d029c3e4 100644 --- a/public_html/media/js/core.js +++ b/public_html/media/js/core.js @@ -32,6 +32,24 @@ function rememberLastSearchQuery() } //core functionalities, prototypes +function getJSON(data) +{ + if (typeof(data.headers) === 'undefined') + data.headers = {}; + data.headers['X-Ajax'] = '1'; + data.type = 'GET'; + return $.ajax(data); +}; + +function postJSON(data) +{ + if (typeof(data.headers) === 'undefined') + data.headers = {}; + data.headers['X-Ajax'] = '1'; + data.type = 'POST'; + return $.ajax(data); +}; + $.fn.hasAttr = function(name) { return this.attr(name) !== undefined; @@ -50,34 +68,6 @@ $.fn.bindOnce = function(name, eventName, callback) -//safety trigger -$(function() -{ - $('.safety a').click(function(e) - { - e.preventDefault(); - - var aDom = $(this); - if (aDom.hasClass('inactive')) - return; - aDom.addClass('inactive'); - - var url = $(this).attr('href') + '?json'; - $.get(url).success(function(data) - { - window.location.reload(); - }).error(function(xhr) - { - alert(xhr.responseJSON - ? xhr.responseJSON.message - : 'Fatal error'); - aDom.removeClass('inactive'); - }); - }); -}); - - - //basic event listeners $(function() { @@ -111,8 +101,8 @@ $(function() return; aDom.addClass('inactive'); - var url = $(this).attr('href') + '?json'; - $.post(url, {submit: 1}).success(function(data) + var url = $(this).attr('href'); + postJSON({ url: url }).success(function(data) { if (aDom.hasAttr('data-redirect-url')) window.location.href = aDom.attr('data-redirect-url'); @@ -201,21 +191,26 @@ function split(val) function retrieveTags(searchTerm, cb) { - var options = { search: searchTerm }; - $.getJSON('/tags-autocomplete?json', options, function(data) + var options = { - var tags = $.map(data.tags.slice(0, 15), function(tag) + url: '/tags-autocomplete', + data: { search: searchTerm } + }; + getJSON(options) + .success(function(data) { - var ret = + var tags = $.map(data.tags.slice(0, 15), function(tag) { - label: tag.name + ' (' + tag.count + ')', - value: tag.name, - }; - return ret; - }); + var ret = + { + label: tag.name + ' (' + tag.count + ')', + value: tag.name, + }; + return ret; + }); - cb(tags); - }); + cb(tags); + }); } $(function() @@ -277,8 +272,17 @@ function attachTagIt(target) { var targetTagit = ui.tag.parents('.tagit'); var context = target.tagit('assignedTags'); - options = { context: context, tag: ui.tagLabel }; - if (targetTagit.siblings('.related-tags:eq(0)').data('for') == options.tag) + var options = + { + url: '/tags-related', + data: + { + context: context, + tag: ui.tagLabel + } + }; + + if (targetTagit.siblings('.related-tags:eq(0)').data('for') == options.data.tag) { targetTagit.siblings('.related-tags').slideUp(function() { @@ -287,7 +291,7 @@ function attachTagIt(target) return; } - $.getJSON('/tags-related?json', options, function(data) + getJSON(options).success(function(data) { var list = $('