X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=js%2Futil.js;h=b645e8b0298aa1dc0d5e218acac82f979f02aa6e;hb=63ab20d20bfe2985402f7f66c3679bcb36e497e8;hp=f41cd07699d5938565a6edf5af3bfc634f0f47b2;hpb=b604630a74de6a23404327ef6a723eaf237f0a6f;p=quix0rs-gnu-social.git
diff --git a/js/util.js b/js/util.js
index f41cd07699..b645e8b029 100644
--- a/js/util.js
+++ b/js/util.js
@@ -53,10 +53,20 @@ var SN = { // StatusNet
NoticeDataGeo: 'notice_data-geo',
NoticeDataGeoCookie: 'NoticeDataGeo',
NoticeDataGeoSelected: 'notice_data-geo_selected',
- StatusNetInstance: 'StatusNetInstance'
}
},
+ V: { // Variables
+ // These get set on runtime via inline scripting, so don't put anything here.
+ },
+
+ /**
+ * list of callbacks, categorized into _callbacks['event_name'] = [ callback_function_1, callback_function_2 ]
+ *
+ * @access private
+ */
+ _callbacks: {},
+
/**
* Map of localized message strings exported to script from the PHP
* side via Action::getScriptMessages().
@@ -216,6 +226,27 @@ var SN = { // StatusNet
return url;
},
+ FormNoticeUniqueID: function (form) {
+ var oldId = form.attr('id');
+ var newId = 'form_notice_' + Math.floor(Math.random()*999999999);
+ var attrs = ['name', 'for', 'id'];
+ for (var key in attrs) {
+ if (form.attr(attrs[key]) === undefined) {
+ continue;
+ }
+ form.attr(attrs[key], form.attr(attrs[key]).replace(oldId, newId));
+ }
+ for (var key in attrs) {
+ form.find("[" + attrs[key] + "*='" + oldId + "']").each(function () {
+ if ($(this).attr(attrs[key]) === undefined) {
+ return; // since we're inside the each(function () { ... });
+ }
+ var newAttr = $(this).attr(attrs[key]).replace(oldId, newId);
+ $(this).attr(attrs[key], newAttr);
+ });
+ }
+ },
+
/**
* Grabs form data and submits it asynchronously, with 'ajax=1'
* parameter added to the rest.
@@ -319,21 +350,6 @@ var SN = { // StatusNet
// Make sure we don't have a mixed HTTP/HTTPS submission...
form.attr('action', SN.U.RewriteAjaxAction(form.attr('action')));
- /**
- * Show a response feedback bit under the new-notice dialog.
- *
- * @param {String} cls: CSS class name to use ('error' or 'success')
- * @param {String} text
- * @access private
- */
- var showFeedback = function (cls, text) {
- form.append(
- $('
')
- .addClass(cls)
- .text(text)
- );
- };
-
/**
* Hide the previous response feedback, if any.
*/
@@ -343,7 +359,7 @@ var SN = { // StatusNet
form.ajaxForm({
dataType: 'xml',
- timeout: '60000',
+ timeout: SN.V.xhrTimeout,
beforeSend: function (formData) {
if (form.find('.notice_data-text:first').val() == '') {
form.addClass(SN.C.S.Warning);
@@ -368,7 +384,7 @@ var SN = { // StatusNet
removeFeedback();
if (textStatus == 'timeout') {
// @fixme i18n
- showFeedback('error', 'Sorry! We had trouble sending your notice. The servers are overloaded. Please try again, and contact the site administrator if this problem persists.');
+ SN.U.showFeedback(form, 'error', 'Sorry! We had trouble sending your notice. The servers are overloaded. Please try again, and contact the site administrator if this problem persists.');
} else {
var response = SN.U.GetResponseXML(xhr);
if ($('.' + SN.C.S.Error, response).length > 0) {
@@ -381,7 +397,7 @@ var SN = { // StatusNet
SN.U.FormNoticeEnhancements(form);
} else {
// @fixme i18n
- showFeedback('error', '(Sorry! We had trouble sending your notice (' + xhr.status + ' ' + xhr.statusText + '). Please report the problem to the site administrator if this happens again.');
+ SN.U.showFeedback(form, 'error', '(Sorry! We had trouble sending your notice (' + xhr.status + ' ' + xhr.statusText + '). Please report the problem to the site administrator if this happens again.');
}
}
}
@@ -390,59 +406,9 @@ var SN = { // StatusNet
removeFeedback();
var errorResult = $('#' + SN.C.S.Error, data);
if (errorResult.length > 0) {
- showFeedback('error', errorResult.text());
+ SN.U.showFeedback(form, 'error', errorResult.text());
} else {
- var commandResult = $('#' + SN.C.S.CommandResult, data);
- if (commandResult.length > 0) {
- showFeedback('success', commandResult.text());
- } else {
- // New notice post was successful. If on our timeline, show it!
- var notice = document._importNode($('li', data)[0], true);
- var notices = $('#notices_primary .notices:first');
- var replyItem = form.closest('li.notice-reply');
-
- if (replyItem.length > 0) {
- // If this is an inline reply, remove the form...
- var list = form.closest('.threaded-replies');
-
- var id = $(notice).attr('id');
- if ($('#' + id).length == 0) {
- $(notice).insertBefore(replyItem);
- } // else Realtime came through before us...
-
- replyItem.remove();
-
- } else if (notices.length > 0 && SN.U.belongsOnTimeline(notice)) {
- // Not a reply. If on our timeline, show it at the top!
-
- if ($('#' + notice.id).length === 0) {
- var notice_irt_value = form.find('[name=inreplyto]').val();
- var notice_irt = '#notices_primary #notice-' + notice_irt_value;
- if ($('body')[0].id == 'conversation') {
- if (notice_irt_value.length > 0 && $(notice_irt + ' .notices').length < 1) {
- $(notice_irt).append('
');
- }
- $($(notice_irt + ' .notices')[0]).append(notice);
- } else {
- notices.prepend(notice);
- }
- $('#' + notice.id)
- .css({display: 'none'})
- .fadeIn(2500);
- SN.U.NoticeWithAttachment($('#' + notice.id));
- SN.U.switchInputFormTab(null);
- }
- } else {
- // Not on a timeline that this belongs on?
- // Just show a success message.
- // @fixme inline
- showFeedback('success', $('title', data).text());
- }
- }
- form.resetForm();
- form.find('[name=inreplyto]').val('');
- form.find('.attach-status').remove();
- SN.U.FormNoticeEnhancements(form);
+ SN.E.ajaxNoticePosted(form, data, textStatus);
}
},
complete: function (xhr, textStatus) {
@@ -590,8 +556,12 @@ var SN = { // StatusNet
$(document).on('click', '.notice-options > a.popup', function (e) {
e.preventDefault();
var noticeEl = $(this).closest('.notice');
- $.get($(this).attr('href'), {ajax: 1}, function (data, textStatus, xhr) {
- SN.U.NoticeOptionPopup(data, noticeEl);
+ $.ajax({
+ url: $(this).attr('href'),
+ data: {ajax: 1},
+ success: function (data, textStatus, xhr) {
+ SN.U.NoticeOptionPopup(data, noticeEl);
+ },
});
return false;
});
@@ -655,6 +625,12 @@ var SN = { // StatusNet
if (list.length == 0) {
list = notice.closest('.threaded-replies');
}
+ if (list.length == 0) {
+ list = $('
');
+ notice.append(list);
+ list = notice.find('.threaded-replies');
+ }
+
var nextStep = function () {
// Override...?
replyForm.find('input[name=inreplyto]').val(id);
@@ -689,22 +665,38 @@ var SN = { // StatusNet
var replyItem = $('li.notice-reply', list);
if (replyItem.length == 0) {
replyItem = $('');
-
- // Fetch a fresh copy of the notice form over AJAX.
- var url = $('#input_form_status > form').attr('action');
- $.get(url, {ajax: 1, inreplyto: id}, function (data, textStatus, xhr) {
- var formEl = document._importNode($('form', data)[0], true);
- replyItem.append(formEl);
- list.append(replyItem);
-
- replyForm = $(formEl);
- SN.Init.NoticeFormSetup(replyForm);
- nextStep();
- });
- } else {
- replyForm = replyItem.children('form');
- nextStep();
}
+ replyForm = replyItem.children('form');
+ if (replyForm.length == 0) {
+ // Let's try another trick to avoid fetching by URL
+ var noticeForm = $('#input_form_status > form');
+ if (noticeForm.length == 0) {
+ // No notice form found on the page, so let's just
+ // fetch a fresh copy of the notice form over AJAX.
+ $.ajax({
+ url: SN.V.urlNewNotice,
+ data: {ajax: 1, inreplyto: id},
+ success: function (data, textStatus, xhr) {
+ var formEl = document._importNode($('form', data)[0], true);
+ replyForm = $(formEl);
+ replyItem.append(replyForm);
+ list.append(replyItem);
+
+ SN.Init.NoticeFormSetup(replyForm);
+ nextStep();
+ },
+ });
+ // We do everything relevant in 'success' above
+ return;
+ }
+ replyForm = noticeForm.clone();
+ SN.Init.NoticeFormSetup(replyForm);
+ replyItem.append(replyForm);
+ list.append(replyItem);
+ }
+ // replyForm is set, we're not fetching by URL...
+ // Next setp is to configure in-reply-to etc.
+ nextStep();
},
/**
@@ -717,11 +709,15 @@ var SN = { // StatusNet
$(document).on('click', 'li.notice-reply-comments a', function () {
var url = $(this).attr('href');
var area = $(this).closest('.threaded-replies');
- $.get(url, {ajax: 1}, function (data, textStatus, xhr) {
- var replies = $('.threaded-replies', data);
- if (replies.length) {
- area.replaceWith(document._importNode(replies[0], true));
- }
+ $.ajax({
+ url: url,
+ data: {ajax: 1},
+ success: function (data, textStatus, xhr) {
+ var replies = $('.threaded-replies', data);
+ if (replies.length) {
+ area.replaceWith(document._importNode(replies[0], true));
+ }
+ },
});
return false;
});
@@ -775,7 +771,7 @@ var SN = { // StatusNet
form
.addClass('dialogbox')
- .append('')
+ .append('')
.closest('.notice-options')
.addClass('opaque');
@@ -852,27 +848,29 @@ var SN = { // StatusNet
NDA.change(function (event) {
form.find('.attach-status').remove();
- var filename = $(this).val();
- if (!filename) {
- // No file -- we've been tricked!
- return false;
- }
-
- var attachStatus = $('
');
+ form.append(attachStatus);
// Some newer browsers will let us fetch the files for preview.
for (i = 0; i < this.files.length; i++) {
SN.U.PreviewAttach(form, this.files[i]);
}
+ } else {
+ var filename = $(this).val();
+ if (!filename) {
+ // No file -- we've been tricked!
+ return false;
+ }
+
+ var attachStatus = $('
');
+ attachStatus.find('code').text(filename);
+ attachStatus.find('button').click(function () {
+ attachStatus.remove();
+ NDA.val('');
+
+ return false;
+ });
+ form.append(attachStatus);
}
});
},
@@ -968,12 +966,15 @@ var SN = { // StatusNet
if (preview) {
blobAsDataURL(file, function (url) {
+ var fileentry = $('');
+ fileentry.append($('' + file.name + ''));
var img = $('')
.attr('title', tooltip)
.attr('alt', tooltip)
.attr('src', url)
.attr('style', 'height: 120px');
- form.find('.attach-status').append(img);
+ fileentry.append(img);
+ form.find('.attach-status').append(fileentry);
});
} else {
var img = $('').text(tooltip);
@@ -1085,12 +1086,12 @@ var SN = { // StatusNet
label.attr('title', label.text());
check.change(function () {
- if (check.prop('checked') === true || $.cookie(SN.C.S.NoticeDataGeoCookie) === null) {
+ if (check.prop('checked') === true || $.cookie(SN.C.S.NoticeDataGeoCookie) === undefined) {
label
.attr('title', NoticeDataGeo_text.ShareDisable)
.addClass('checked');
- if ($.cookie(SN.C.S.NoticeDataGeoCookie) === null || $.cookie(SN.C.S.NoticeDataGeoCookie) == 'disabled') {
+ if ($.cookie(SN.C.S.NoticeDataGeoCookie) === undefined || $.cookie(SN.C.S.NoticeDataGeoCookie) == 'disabled') {
if (navigator.geolocation) {
SN.U.NoticeGeoStatus(form, 'Requesting location from browser...');
navigator.geolocation.getCurrentPosition(
@@ -1255,56 +1256,6 @@ var SN = { // StatusNet
return date;
},
- /**
- * Some sort of object interface for storing some structured
- * information in a cookie.
- *
- * Appears to be used to save the last-used login nickname?
- * That's something that browsers usually take care of for us
- * these days, do we really need to do it? Does anything else
- * use this interface?
- *
- * @fixme what is this?
- * @fixme should this use non-cookie local storage when available?
- */
- StatusNetInstance: {
- /**
- * @fixme what is this?
- */
- Set: function (value) {
- var SNI = SN.U.StatusNetInstance.Get();
- if (SNI !== null) {
- value = $.extend(SNI, value);
- }
-
- $.cookie(
- SN.C.S.StatusNetInstance,
- JSON.stringify(value),
- {
- path: '/',
- expires: SN.U.GetFullYear(2029, 0, 1)
- });
- },
-
- /**
- * @fixme what is this?
- */
- Get: function () {
- var cookieValue = $.cookie(SN.C.S.StatusNetInstance);
- if (cookieValue !== undefined) {
- return JSON.parse(cookieValue);
- }
- return null;
- },
-
- /**
- * @fixme what is this?
- */
- Delete: function () {
- $.cookie(SN.C.S.StatusNetInstance, null);
- }
- },
-
/**
* Check if the current page is a timeline where the current user's
* posts should be displayed immediately on success.
@@ -1388,9 +1339,106 @@ var SN = { // StatusNet
var extended = $(selector);
extended.removeClass('extended_menu');
return void(0);
+ },
+
+ /**
+ * Show a response feedback bit under a form.
+ *
+ * @param {Element} form: the new-notice form usually
+ * @param {String} cls: CSS class name to use ('error' or 'success')
+ * @param {String} text
+ * @access public
+ */
+ showFeedback: function (form, cls, text) {
+ form.append(
+ $('')
+ .addClass(cls)
+ .text(text)
+ );
+ },
+
+ addCallback: function (ename, callback) {
+ // initialize to array if it's undefined
+ if (typeof SN._callbacks[ename] === 'undefined') {
+ SN._callbacks[ename] = [];
+ }
+ SN._callbacks[ename].push(callback);
+ },
+
+ runCallbacks: function (ename, data) {
+ if (typeof SN._callbacks[ename] === 'undefined') {
+ return;
+ }
+ for (cbname in SN._callbacks[ename]) {
+ SN._callbacks[ename][cbname](data);
+ }
}
},
+ E: { /* Events */
+ /* SN.E.ajaxNoticePosted, called when a notice has been posted successfully via an AJAX form
+ @param form the originating form element
+ @param data data from success() callback
+ @param textStatus textStatus from success() callback
+ */
+ ajaxNoticePosted: function (form, data, textStatus) {
+ var commandResult = $('#' + SN.C.S.CommandResult, data);
+ if (commandResult.length > 0) {
+ SN.U.showFeedback(form, 'success', commandResult.text());
+ } else {
+ // New notice post was successful. If on our timeline, show it!
+ var notice = document._importNode($('li', data)[0], true);
+ var notices = $('#notices_primary .notices:first');
+ var replyItem = form.closest('li.notice-reply');
+
+ if (replyItem.length > 0) {
+ // If this is an inline reply, remove the form...
+ var list = form.closest('.threaded-replies');
+
+ var id = $(notice).attr('id');
+ if ($('#' + id).length == 0) {
+ $(notice).insertBefore(replyItem);
+ } // else Realtime came through before us...
+
+ replyItem.remove();
+
+ } else if (notices.length > 0 && SN.U.belongsOnTimeline(notice)) {
+ // Not a reply. If on our timeline, show it at the top!
+
+ if ($('#' + notice.id).length === 0) {
+ var notice_irt_value = form.find('[name=inreplyto]').val();
+ var notice_irt = '#notices_primary #notice-' + notice_irt_value;
+ if ($('body')[0].id == 'conversation') {
+ if (notice_irt_value.length > 0 && $(notice_irt + ' .notices').length < 1) {
+ $(notice_irt).append('
');
+ }
+ $($(notice_irt + ' .notices')[0]).append(notice);
+ } else {
+ notices.prepend(notice);
+ }
+ $('#' + notice.id)
+ .css({display: 'none'})
+ .fadeIn(2500);
+ SN.U.NoticeWithAttachment($('#' + notice.id));
+ SN.U.switchInputFormTab(null);
+ }
+ } else {
+ // Not on a timeline that this belongs on?
+ // Just show a success message.
+ // @fixme inline
+ SN.U.showFeedback(form, 'success', $('title', data).text());
+ }
+ }
+ form.resetForm();
+ form.find('[name=inreplyto]').val('');
+ form.find('.attach-status').remove();
+ SN.U.FormNoticeEnhancements(form);
+
+ SN.U.runCallbacks('notice_posted', {"notice": notice});
+ },
+ },
+
+
Init: {
/**
* If user is logged in, run setup code for the new notice form:
@@ -1447,6 +1495,7 @@ var SN = { // StatusNet
return false;
}
SN.U.NoticeLocationAttach(form);
+ SN.U.FormNoticeUniqueID(form);
SN.U.FormNoticeXHR(form);
SN.U.FormNoticeEnhancements(form);
SN.U.NoticeDataAttach(form);
@@ -1500,28 +1549,6 @@ var SN = { // StatusNet
}
},
- /**
- * Run setup code for login form:
- *
- * - loads saved last-used-nickname from cookie
- * - sets event handler to save nickname to cookie on submit
- *
- * @fixme is this necessary? Browsers do their own form saving these days.
- */
- Login: function () {
- if (SN.U.StatusNetInstance.Get() !== null) {
- var nickname = SN.U.StatusNetInstance.Get().Nickname;
- if (nickname !== null) {
- $('#form_login #nickname').val(nickname);
- }
- }
-
- $('#form_login').on('submit', function () {
- SN.U.StatusNetInstance.Set({Nickname: $('#form_login #nickname').val()});
- return true;
- });
- },
-
/**
* Run setup for the ajax people tags editor
*
@@ -1650,9 +1677,6 @@ $(function () {
if ($('#content .entity_actions').length > 0) {
SN.Init.EntityActions();
}
- if ($('#form_login').length > 0) {
- SN.Init.Login();
- }
if ($('#profile_search_results').length > 0) {
SN.Init.ProfileSearch();
}