Sequenzia/lib/assets/javascripts/moe-legacy/post-upload-form.js

248 lines
6.5 KiB
JavaScript
Raw Normal View History

2013-10-27 01:06:58 +02:00
var PostUploadForm = function(form, progress)
{
var XHRLevel2 = "XMLHttpRequest" in window && (new XMLHttpRequest().upload != null);
var SupportsFormData = "FormData" in window;
if(!XHRLevel2 || !SupportsFormData)
return;
this.form_element = form;
this.cancel_element = this.form_element.down(".cancel");
this.progress = progress;
this.document_title = document.documentElement.down("TITLE");
this.document_title_orig = this.document_title.textContent;
this.current_request = null;
this.form_element.on("submit", this.form_submit_event.bindAsEventListener(this));
this.cancel_element.on("click", this.click_cancel.bindAsEventListener(this));
var keypress_event_name = window.opera || Prototype.Browser.Gecko? "keypress":"keydown";
document.on(keypress_event_name, this.document_keydown_event.bindAsEventListener(this));
}
PostUploadForm.prototype.set_progress = function(f)
{
var percent = f * 100;
this.progress.down(".upload-progress-bar-fill").style.width = percent + "%";
this.document_title.textContent = this.document_title_orig + " (" + percent.toFixed(0) + "%)";
}
PostUploadForm.prototype.request_starting = function()
{
this.form_element.down(".submit").hide();
this.cancel_element.show();
this.progress.show();
document.documentElement.addClassName("progress");
}
PostUploadForm.prototype.request_ending = function()
{
this.form_element.down(".submit").show();
this.cancel_element.hide();
this.progress.hide();
this.document_title.textContent = this.document_title_orig;
document.documentElement.removeClassName("progress");
}
PostUploadForm.prototype.document_keydown_event = function(e)
{
var key = e.charCode;
if(!key)
key = e.keyCode; /* Opera */
if(key != Event.KEY_ESC)
return;
this.cancel();
}
PostUploadForm.prototype.click_cancel = function(e)
{
e.stop();
this.cancel();
}
PostUploadForm.prototype.form_submit_event = function(e)
{
/* This submit may have been stopped by User.run_login_onsubmit. */
if(e.stopped)
return;
if(this.current_request != null)
return;
$("post-exists").hide();
$("post-upload-error").hide();
/* If the files attribute isn't supported, or we have no file (source upload), use regular
* form submission. */
var post_file = $("post_file");
if(post_file.files == null || post_file.files.length == 0)
return;
e.stop();
this.set_progress(0);
this.request_starting();
var form_data = new FormData(this.form_element);
var onprogress = function(e)
{
var done = e.loaded;
var total = e.total;
this.set_progress(total? (done/total):1);
}.bind(this);
this.current_request = new Ajax.Request("/post/create.json", {
contentType: null,
method: "post",
postBody: form_data,
onCreate: function(resp)
{
var xhr = resp.request.transport;
xhr.upload.onprogress = onprogress;
},
onComplete: function(resp)
{
this.current_request = null;
this.request_ending();
var json = resp.responseJSON;
if(!json)
return;
if(!json.success)
{
if(json.location)
{
var a = $("post-exists-link");
a.setTextContent("post #" + json.post_id);
a.href = json.location;
$("post-exists").show();
return;
}
$("post-upload-error").setTextContent(json.reason);
$("post-upload-error").show();
return;
}
/* If a post/similar link was given and similar results exists, go to them. Otherwise,
* go to the new post. */
var target = json.location;
if(json.similar_location && json.has_similar_hits)
target = json.similar_location;
window.location.href = target;
}.bind(this)
});
}
/* Cancel the running request, if any. */
PostUploadForm.prototype.cancel = function()
{
if(this.current_request == null)
return;
/* Don't clear this.current_request; it'll be done by the onComplete callback. */
this.current_request.transport.abort();
}
/*
* When file_field is changed to an image, run an image search and put a summary in
* results.
*/
UploadSimilarSearch = function(file_field, results)
{
if(!ThumbnailUserImage)
return;
this.file_field = file_field;
this.results = results;
file_field.on("change", this.field_changed_event.bindAsEventListener(this));
}
UploadSimilarSearch.prototype.field_changed_event = function(event)
{
this.results.hide();
if(this.file_field.files == null || this.file_field.files.length == 0)
return;
this.results.innerHTML = "Searching...";
this.results.show();
var file = this.file_field.files[0];
var similar = new ThumbnailUserImage(file, this.thumbnail_complete.bind(this));
}
UploadSimilarSearch.prototype.thumbnail_complete = function(result)
{
if(!result.success)
{
this.results.innerHTML = "Image load failed.";
this.results.show();
return;
}
/* Grab a data URL from the canvas; this is what we'll send to the server. */
var data_url = result.canvas.toDataURL();
/* Create the FormData containing the thumbnail image we're sending. */
var form_data = new FormData();
form_data.append("url", data_url);
var req = new Ajax.Request("/post/similar.json", {
method: "post",
postBody: form_data,
/* Tell Prototype not to change XHR's contentType; it breaks FormData. */
contentType: null,
onComplete: function(resp)
{
this.results.innerHTML = "";
this.results.show();
var json = resp.responseJSON;
if(!json.success)
{
this.results.innerHTML = json.reason;
return;
}
if(json.posts.length > 0)
{
var posts = [];
var shown_posts = 3;
json.posts.slice(0, shown_posts).each(function(post) {
var url;
if(User.get_use_browser())
url = "/post/browse#" + post.id;
else
url = "/post/show/" + post.id;
var s = "<a href='" + url + "'>post #" + post.id + "</a>";
posts.push(s);
});
var post_links = posts.join(", ");
var see_all = "<a href='/post/similar?search_id=" + json.search_id + "'>(see all)</a>";
var html = "Similar posts " + see_all + ": " + post_links;
if(json.posts.length > shown_posts)
{
var remaining_posts = json.posts.length - shown_posts;
html += " (" + remaining_posts + " more)";
}
this.results.innerHTML = html;
}
else
{
this.results.innerHTML = "No similar posts found.";
}
}.bind(this)
});
}