edgware/edgware/static/js/editor.js
2011-07-12 20:24:39 +05:30

1789 lines
50 KiB
JavaScript

var ARTICLE_ID = 0;
var BASE_URL = "http://edgwareroad.org/edit/"
var edgeArticle = window.edgeArticle = [];
var loadArticle = function(id) {
// console.log("load article fired");
$.getJSON("/edit/article/json/", {
'id': id
}, function(json) {
// console.log(json);
for (var i=0; i < json.length; i++) {
new Canvas({}, json[i]);
}
startPoller();
});
}
//is used by the poller to call itself 1 second in the future. not sure why im doing this. FIXME: function name at least?
function delayedRecursion(time) {
// console.log("delayed recursion called" + time);
POLLER = setTimeout(startPoller, time);
}
function startPoller() {
// console.log("poller called");
$.getJSON("/edit/poll_changes/", {
'article_id': ARTICLE_ID,
'rev_no': REVISION_NO,
'uuid': UUID
}, function(data) {
if (data.ok == 'ok') {
delayedRecursion(1000);
} else {
REVISION_NO = data.rev_id;
clearTimeout(POLLER);
delayedRecursion(1000);
var arr = data.revs;
for (var a in arr) {
if (arr.hasOwnProperty(a)) {
handleRevision(arr[a]);
}
}
}
});
}
function addHistoryObject(data) {
var e = $('<div />').addClass("historyItem").data("data", data).hide();
var userHtml = "edit by <span class='historyUsername'>" + data.username + "</span>";
var userLine = $('<div />').addClass("historyUser").html(userHtml).appendTo(e);
$('.historyItems').prepend(e);
e.fadeIn();
}
$('.historyUser').live("click", function() {
var parent = $(this).parent();
if (parent.children('.historyData').length > 0 && parent.children('.historyData').is(":visible")) {
parent.children(".historyData").slideUp();
} else {
var data = parent.data('data');
data['page_no'] = getCanvasById(data.page_id).index + 1;
var html = tmpl("tmpl_historyData", data);
$('<div />').addClass('historyData').html(html).hide().appendTo(parent).slideDown();
}
});
//Refer to editor/models.py -> Revisions
function handleRevision(json) {
// console.log(json);
var canvas = json.prop == 'new_page' ? {} : getCanvasById(json.page_id);
addHistoryObject(json);
switch (json.prop) {
case "new_page":
var j = JSON.parse(json.new_val);
new Canvas({}, j);
break;
case "move_page":
var page_id = json.box_id;
var c = getCanvasById(page_id);
c.movePage(json.new_val - 1, true);
break;
case "delete_page":
var c = getCanvasById(json.new_val);
c.deleteme(true);
break;
case "new_box":
if (json.box_type == 'image') {
var j = JSON.parse(json.new_val);
new ImageBox(canvas, j.resource, j);
break;
}
else if (json.box_type == 'text') {
var j = JSON.parse(json.new_val);
new TextBox(canvas, j);
break;
}
else {
break;
}
case "delete_box":
var box = canvas.getBox(json);
box.jq.hide().remove();
break;
case "image_resize":
var box = canvas.getBox(json);
var img = JSON.parse(json.new_val);
box.resize({'width': img.width, 'height': img.height}, false);
box.jq.find("img").attr("src", img.path);
break;
case "image_crop":
var box = canvas.getBox(json);
var img = JSON.parse(json.new_val);
box.resize({'width': img.width, 'height': img.height}, false);
box.jq.find('.edgeImage').attr("src", img.path);
break;
default:
var box = canvas.getBox(json);
if (json.prop == 'html') {
box.jq.find('.textbox_canvas_content').html(json.new_val);
} else {
var d = {};
var noPxArr = ['opacity', 'z-index', 'background', 'border-color', 'border-style'];
if ($.inArray(noPxArr, json.prop)) {
var val = json.new_val;
} else {
var val = toPx(json.new_val);
}
d[json.prop] = val;
//dont try and animate properties like 'transparent', it will fail.
if (d[json.prop] == 'transparent' || json.old_val == 'transparent') {
box.jq.css(d);
} else {
box.jq.animate(d, "fast");
}
break;
}
}
return true;
}
$(document).ready(function() {
if ($.browser.msie) {
alert("Sorry, this does not currently work in Internet Explorer.");
window.location.href = "/";
return false;
}
if (ARTICLE_ID != 0) {
loadArticle(ARTICLE_ID);
} else {
c = new Canvas();
}
/*
edgeCanvas = new Canvas();
edgeBin = new Bin();
$('#newTextBox').click(function() {
var index = edgeCanvas.textBoxes.length;
var t = new TextBox(index, edgeCanvas);
t.create();
});
*/
$('.newTextBox').tooltip();
$('#newPage').click(function(e) {
e.preventDefault();
c = new Canvas();
});
$('.prevPage').click(function() {
edgeBin.prevPage();
});
$('.nextPage').click(function() {
edgeBin.nextPage();
});
$('.searchBin').keyup(function() {
edgeBin.searchString($(this).val());
});
});
function getCanvasById(id) {
for (var e in edgeArticle) {
if (edgeArticle.hasOwnProperty(e)) {
if (edgeArticle[e].id == id) {
return edgeArticle[e];
}
}
}
return false;
}
var Canvas = function(opts, json) {
var that = this;
var defaults = {
'index': edgeArticle.length,
'id': 0,
'height': ARTICLE_HEIGHT,
'width': ARTICLE_WIDTH,
'parentID': 'canvasContainer'
}
var o = $.extend(defaults, opts);
if (typeof json != 'undefined') {
o.id = json.id;
}
this.index = o.index;
this.parent = $('#' + o.parentID);
if (o.id == 0) {
$.getJSON("/edit/new_page/", {
'article_id': ARTICLE_ID,
'uuid': UUID
}, function(data) {
that.id = data.id;
});
} else {
this.id = o.id;
}
var that = this;
this.textBoxes = [];
this.imageBoxes = [];
this.jq = { };
this.height = o.height;
this.width = o.width;
edgeArticle.push(that);
this.init();
if (typeof json != 'undefined') {
this.loadFromJSON(json);
} else {
}
return this;
}
Canvas.prototype.getBox = function(json) {
if (json.box_type == 'image') {
for (var i in this.imageBoxes) {
if (this.imageBoxes.hasOwnProperty(i)) {
if (this.imageBoxes[i].id == json.box_id) {
return this.imageBoxes[i];
}
}
}
return false;
} else {
for (var t in this.textBoxes) {
if (this.textBoxes.hasOwnProperty(t)) {
if (this.textBoxes[t].id == json.box_id) {
return this.textBoxes[t];
}
}
}
return false;
}
return false;
}
Canvas.prototype.init = function() {
var that = this;
var heightPx = toPx(that.height);
var widthPx = toPx(that.width);
var json = {
'index': that.index
}
var html = tmpl("tmpl_canvas", json);
this.parent.append(html);
this.jq = $('#' + 'canvas' + that.index.toString());
this.jq.css({'height': heightPx, 'width': widthPx});
this.jq.find('.ruler_vert').draggable({
snap: '.box',
containment: 'parent',
axis: 'x'
});
this.jq.find('.ruler_horiz').draggable({
snap: '.box',
containment: 'parent',
axis: 'y'
});
this.jq.droppable({accept:'.resource, .newTextBox',
drop: function(ev, ui) {
var box = $(this).getBox().jq;
c = edgeArticle[$(this).attr('data-index')];
if ($(ui.draggable).attr('class') == 'resource ui-draggable') {
r = edgeBin.allResources[$(ui.draggable).attr("data-index")];
if (r.mime == 'image') {
var top = $(this).position().top;
var left = $(this).position().left;
var height = parseInt(r.height) / 2;
// console.log("heightFOO: " + height);
var width = parseInt(r.width) / 2;
highest_index = getHighestIndex(c.jq);
new_index = parseInt(highest_index) + 1;
// console.log('index: ' + new_index);
i = new ImageBox(c, r, {css: {'z-index': "" + new_index, 'top':toPx((ev.pageY - top) - height), 'left': toPx((ev.pageX - left) - width)}});
} else if (r.mime == 'audio' || r.mime == 'video') {
that.addMedia(r);
}
} else {
var elem = $(ui.draggable);
var top = $(this).position().top;
var left = $(this).position().left;
if (elem.hasClass('arabic')) {
t = new TextBox(c, {'html': '<p class="textbox_canvas_text">انقر على مربع التحرير</p>', 'css': {'direction': 'rtl'}});
} else {
t = new TextBox(c);
}
width = parseInt(t.jq.css('width') / 2);
height = parseInt(t.jq.css('height') / 2);
t.setCSS({'top':toPx((ev.pageY - top) - height), 'left': toPx((ev.pageX - left) - width)});
highest_index = getHighestIndex(c.jq);
new_index = parseInt(highest_index) + 1;
t.setCSS({'z-index': new_index});
}
// console.log('dropper');
}
});
return this;
}
Canvas.prototype.addMedia = function(resource) {
var that = this;
$.getJSON("/edit/add_media/", {
resource_id: resource.id,
page_id: that.id
}, function(response) {
that.addMediaIcon(resource);
});
}
Canvas.prototype.addMediaIcon = function(resource) {
var typ = resource.mime;
var media_box = this.jq.find('.audio_video');
$('<img />').addClass('media_icon').addClass(typ + '_icon').attr("src", "/static/images/icons/" + typ + ".png").attr("title", resource.title).data("resource", resource).appendTo(media_box);
}
Canvas.prototype.loadFromJSON = function(json) {
// alert(JSON.stringify(json));
// GLOBALFOO = json;
var imageBoxes = json.imageBoxes;
var textBoxes = json.textBoxes;
var videos = json.videos;
var audios = json.audios;
// alert(audios.length);
var that = this;
for (var i=0; i < imageBoxes.length; i++) {
var resource = imageBoxes[i].resource;
var b = new ImageBox(that, resource, imageBoxes[i]);
// that.imageBoxes.append(b);
}
for (var t=0; t < textBoxes.length; t++) {
var b = new TextBox(that, textBoxes[t]);
// that.textBoxes.append(b);
}
for (var v=0; v < videos.length; v++) {
var video = videos[v];
that.addMediaIcon(video);
}
for (var a=0; a < audios.length; a++) {
var audio = audios[a];
that.addMediaIcon(audio);
}
}
Canvas.prototype.toObj = function() {
var that = this;
var obj = {
'imageBoxes': that.imageBoxes,
'textBoxes': that.textBoxes,
}
return obj;
// console.log(json);
}
//this function is not used. FIXME: remove
Canvas.prototype.save = function() {
var that = this;
var url = "/editor/canvas/save/";
$.getJSON(url, {
json: JSON.stringify(that.toObj()),
id: that.id
}, function() {
alert("saved");
});
}
Canvas.prototype.appendBox = function(box) {
this.jq.append(box.jq);
if (box instanceof TextBox) {
this.textBoxes.push(box);
} else if (box instanceof ImageBox) {
this.imageBoxes.push(box);
}
return this;
}
Canvas.prototype.movePage = function(newOrder, dontSave) {
var that = this;
if (typeof(dontSave) === 'undefined') {
dontSave = false;
}
var currentIndex = this.jq.index('.canvas');
if (newOrder == 0) {
this.jq.remove().insertBefore($('.canvas').eq(0));
} else if (newOrder < currentIndex) {
var prevCanvas = $('.canvas').eq(newOrder - 1);
this.jq.remove().insertAfter(prevCanvas);
} else {
var prevCanvas = $('.canvas').eq(newOrder);
this.jq.remove().insertAfter(prevCanvas);
}
reorderEdgeArticle();
if (!dontSave) {
var url = "/edit/move_page/";
$.getJSON(url, {
'id': that.id,
'new_order': newOrder + 1,
'uuid': UUID
}, function(response) {
// console.log(response);
});
}
}
Canvas.prototype.deleteme = function(dontSave) {
var that = this;
this.jq.remove();
edgeArticle.splice(that.index,1);
reorderEdgeArticle();
if (typeof(dontSave) == 'undefined') {
dontSave = false;
}
if (!dontSave) {
var url = "/edit/delete_page/";
$.getJSON(url, {
'id': that.id
}, function(response) {
// console.log(response);
});
}
}
function reorderEdgeArticle() {
edgeArticle.sort(function(a,b) {
var aIndex = a.jq.index('.canvas');
var bIndex = b.jq.index('.canvas');
return aIndex - bIndex;
});
$('.canvas').each(function() {
var thisIndex = $(this).index('.canvas');
$(this).attr("data-index", thisIndex);
var c = $(this).children().eq(0).getCanvas();
c.index = thisIndex;
});
}
function getHighestIndex(canvas) {
page_boxes = canvas.find('.box');
if (page_boxes.length == 0) {
return 0;
} else {
page_boxes = $(page_boxes).sort(compareZIndex);
highest = $(page_boxes[0]).css('z-index');
return highest;
}
}
function getLowestIndex(canvas) {
page_boxes = canvas.find('.box');
page_boxes = $(page_boxes).sort(compareZIndex);
length = page_boxes.length - 1;
lowest = $(page_boxes[length]).css('z-index');
return lowest;
}
function reSortBoxes (canvas) {
var page_boxes = canvas.find('.box');
page_boxes = $(page_boxes).sort(compareZIndex);
// console.log(page_boxes);
for (var i=0; i < page_boxes.length; i++) {
var boxObj = $(page_boxes[i]).find('*').getBox();
boxObj.setCSS({'z-index': page_boxes.length - i});
}
}
function compareZIndex(a, b) {
return parseInt($(b).css('z-index')) - parseInt($(a).css('z-index'));
// console.log('gjugg');
// console.log($(b).css('z-index'));
// console.log('mugg');
}
/*
>>> t = new TextBox(0); t.index;
0
@constructor
@class TextBox TextBox class
@property {Int} id Id of the box in the back-end. If the id is set to 0, it calls the db and sets the id in the create() method.
@property {String} html The raw html of the contents of the text box.
@property {Object} css Key value pairs representing the css for the text box.
@property {Object} resource The resource in the database this box is based on. For text-boxes, it is not really used, but may be good to have anyway.
@property {jQuery Object} jq Object representing text box on page. So you can do things like t.jq.css({'background', '#000'}); to change the background color of TextBox t to black.
*/
var TextBox = function(canvas, json, index) {
this.index = index || canvas.textBoxes.length;
this.id = 0;
this.html = '';
this.css = { };
this.resource = { };
this.jq = {};
this.canvas = canvas;
this.create(json);
};
/*
Call this function to create a new Text Box - if passed json, the TextBox is instantiated from the JSON, else it uses defaults.
>>> t.create(); t.jq.length == 1;
true
*/
TextBox.prototype.create = function(json) {
var that = this;
var defaults = {
'id': 0,
'html': '<p class="textbox_canvas_text">Click to edit textbox</p>',
'resource_id': 0,
'css': {
'direction': 'ltr',
'height': '300px',
'width': '300px',
'background-color': '#ffffff',
'border-style': 'dotted',
'border-width': '1px',
'border-color': '#000000',
'top': '100px',
'left': '100px',
'padding-top': '0px',
'padding-left': '0px',
'padding-right': '0px',
'padding-bottom': '0px',
'opacity': '1',
'z-index': '1',
'border-radius': '0px'
}
};
var opts = $.extend(true, defaults, json);
// console.log(opts);
this.id = opts.id;
this.html = opts.html;
this.css = opts.css;
if (this.id == 0) {
// Create new TextBox in db:
var optsString = JSON.stringify(opts);
// console.log(this.id);
$.getJSON("/edit/textbox/new/", {'json': optsString, 'page_id': that.canvas.id, 'uuid': UUID}, function(response) {
var id = response.id;
that.id = id;
that.jq.attr("data-id", id);
// REVISION_NO = response.rev_id;
});
}
var elem = this.init();
this.jq = elem;
this.canvas.appendBox(that);
// edgeCanvas.textBoxes.push(this)
};
/*
This method is called by create(); it should generally not be called from the outside. Here is where the actual element is created and event handlers added.
>>> t.init(); t.jq.attr("data-index");
0
*/
TextBox.prototype.init = function() {
var that = this;
var e = $('<div />');
e.html(tmpl('tmpl_textbox', {'html': that.html})).attr("data-id", that.id).attr("data-index", that.index).css(that.css).addClass("box").addClass("textBox");
/* Workaround for strange webkit behaviour */
if (e.css("position") == "relative" || e.css("position") == '') {
e.css("position", "absolute");
}
// console.log(e.css("position"));
// GLOB = e.css("position");
// e.append($('<div />').addClass("boxText"));
e.draggable({
snap: '.box, .ruler',
snapMode: 'outer',
containment: 'parent',
stop: function(event, ui) {
var top = parseInt($(this).position().top).toString();
var left = parseInt($(this).position().left).toString();
that.setCSS({'top': top, 'left': left});
/*
var id = $(this).attr("data-id");
var css = {
'id': id,
'top': top,
'left': left
}
$.get(url, css, function(response) { });
var i = parseInt($(this).attr("data-index"));
*/
// var thisBox = edgeCanvas.textBoxes[i];
// thisBox.updateCSS(css);
}
}).resizable({
// containment: '#' + that.canvas.jq.attr("id"),
containment: that.canvas.jq,
handles: 'nw, ne, se, sw, n, s, w, e',
stop: function(event, ui) {
var top = parseInt($(this).position().top).toString();
var left = parseInt($(this).position().left).toString();
var height = $(this).height().toString();
var width = $(this).width().toString();
that.setCSS({'height': height, 'width': width, 'top': top, 'left': left});
/*
var id = $(this).attr("data-id");
var json = {
'id': id,
'height': height,
'width': width
};
var i = parseInt($(this).attr("data-index"));
var thisBox = edgeCanvas.textBoxes[i];
*/
// thisBox.updateCSS(css);
}
});
return e;
};
/*
Called by setCSS to send the ajax call to the back-end to update the Css - if called from the outside, it will send the request to the back-end, but not update client-side.
>>> t.updateCSS({'background': '#000'}); t.jq.css("background-color");
'#000000'
*/
TextBox.prototype.updateCSS = function(css) {
css.id = this.id;
css.uuid = UUID;
// console.log(css);
// isAjaxActive = true;
$.getJSON("/edit/textbox/update_css/", css, function(response) {
if (response.status == 1) {
// REVISION_NO = response.rev_id;
return true;
} else {
return false;
}
// isAjaxActive = false;
});
};
/*
Call this from the outside to update CSS both client and server-side. css can be any number of key value pairs of css properties to update.
>>> t.setCSS({'padding-bottom': '10px', 'padding-top': '15px'}); t.jq.css("padding-bottom")
"10px"
*/
TextBox.prototype.setCSS = function(css, callServer) {
/* for (var c in css) {
if (css.hasOwnProperty(c)) {
this.css[c] = css[c];
}
}
*/
this.jq.css(css);
var srv = callServer == undefined ? true : callServer;
if (srv) {
this.updateCSS(css);
}
};
TextBox.prototype.setHTML = function(html) {
// console.log(html);
var that = this;
$.getJSON("/edit/textbox/set_html/", {'html': html, 'id': that.id, 'uuid': UUID}, function(response) {
if (response.status == 1) {
// REVISION_NO = response.rev_id;
return true;
} else {
return false;
}
});
}
TextBox.prototype.deleteme = function() {
var that = this;
this.jq.remove();
$.get("/edit/textbox/delete/", {
'id': that.id,
'uuid': UUID
}, function(response) {
// REVISION_NO = response;
});
}
/*
refer TextBox -- except here resource is this damned resource object that image boxes need.
*/
var ImageBox = function(canvas, resource, json) {
var that = this;
this.index = canvas.imageBoxes.length;
this.id = 0;
this.css = { };
this.resource = resource;
this.jq = {};
this.css.width = toPx(that.resource.width);
this.css.height = toPx(that.resource.height);
this.canvas = canvas;
this.create(json);
};
ImageBox.prototype.create = function(json) {
var that = this;
var defaults = {
'id': 0,
'html': tmpl('tmpl_imagebox', {}),
'resource_id': that.resource.id,
'page_id': that.canvas.id,
'css': {
'height': that.css.height,
'width': that.css.width,
'border-style': 'solid',
'border-width': '0px',
'border-color': '#000000',
'z-index': '1',
'top': '100px',
'left': '100px',
'opacity': '1'
}
};
var opts = $.extend(true, defaults, json);
this.id = opts.id;
this.html = opts.html;
this.css = opts.css;
// console.log(opts.css);
if (this.id == 0) {
// Create new TextBox in db:
var jsonString = JSON.stringify(opts);
$.getJSON("/edit/imagebox/new/", {'json': jsonString, 'uuid': UUID}, function(response) {
var id = response.id;
that.id = id;
that.jq.attr("data-id", id);
// REVISION_NO = response.rev_id;
});
}
this.init();
// var elem = this.init();
};
//TextBox.prototype.init = function() {
// var that = this;
// var e = $('<div />');
// e.html(that.html).attr("data-id", that.id).attr("data-index", that.index).css(that.css).addClass("box").addClass("textBox");
// e.append($('<div />').addClass("boxText"));
ImageBox.prototype.init = function() {
var that = this;
var e = $('<div />');
e.attr('data-index', that.index.toString()).attr('data-id', that.id).addClass('box').addClass("imageBox");
e.css(that.css);
e.html(that.html);
var img = $('<img />').addClass("edgeImage").attr("src", that.resource.resized).attr('width', that.resource.width).attr('height', that.resource.height);
e.append(img);
this.jq = e;
this.canvas.appendBox(that);
this.addEventHandlers();
}
ImageBox.prototype.addEventHandlers = function() {
var that = this; var e = this.jq;
e.draggable({
snap: '.box, .ruler',
snapMode: 'outer',
containment: 'parent',
stop: function(event, ui) {
var top = parseInt($(this).position().top).toString();
var left = parseInt($(this).position().left).toString();
that.setCSS({'top': top, 'left': left});
}
}).resizable({
containment: that.canvas.jq,
handles: 'nw, se, ne, sw, n, s, w, e',
aspectRatio: true,
resize: function (event, ui) {
var height = $(this).height().toString();
var width = $(this).width().toString();
$(this).find('.edgeImage').attr("width", width);
$(this).find('.edgeImage').attr("height", height);
},
stop: function(event, ui) {
var top = parseInt($(this).position().top).toString();
var left = parseInt($(this).position().left).toString();
var height = $(this).height().toString();
var width = $(this).width().toString();
that.resize({'height': height, 'width': width});
that.setCSS({'top': top, 'left': left});
}
});
}
ImageBox.prototype.getHtml = function() {
}
ImageBox.prototype.fromJson = function() {
}
ImageBox.prototype.updateCSS = function(css) {
css.id = this.id;
css.uuid = UUID;
$.getJSON("/edit/imagebox/update_css/", css, function(response) {
if (response.status == 1) {
// REVISION_NO = response.rev_id;
return true;
} else {
return false;
}
});
};
ImageBox.prototype.setCSS = function(css, doUpdate) {
var update = doUpdate == undefined ? true : doUpdate;
this.jq.css(css);
if (update) {
this.updateCSS(css);
}
return this;
};
ImageBox.prototype.resize = function(dimensions) {
var that = this;
this.setCSS({
'width': toPx(dimensions.width),
'height': toPx(dimensions.height)
}, false);
this.jq.find('.edgeImage').attr("width", dimensions.width);
this.jq.find('.edgeImage').attr("height", dimensions.height);
dimensions.id = this.id;
dimensions.uuid = UUID;
if (arguments[1] == false) { return true; }
$.getJSON("/edit/imagebox/resize/", dimensions, function(response) {
// console.log(response);
if (response.status == 1) {
var path = $.trim(response.path);
that.jq.find('.edgeImage').attr("src", path);
// REVISION_NO = response.rev_id;
return true;
} else {
return false;
}
});
};
ImageBox.prototype.deleteme = function() {
var that = this;
this.jq.remove();
$.get("/edit/imagebox/delete/",
{'id': that.id, 'uuid': UUID}, function(response) {
// REVISION_NO = response;
});
}
/*
@constructor
@class Bin Bin class to deal with loading various categories into a bin to pick from into your own bin
@property {Array} resources Resource objects that belong to this bin.
@divid {String} Id of DOM node.
@jq {jQuery Object} Jquery object representing Bin
*/
var Bin = function() {
this.resources = [];
this.divid = 'bin';
var that = this;
this.size = 6;
this.start_index = 0;
this.jq = $('#' + that.divid);
this.allResources = [];
};
Bin.prototype.loadCategory = function(catid, type) {
var that = this;
this.jq.find('.resource').remove();
this.resources = [];
$.getJSON("/edit/category/json/", {'id': catid, 'type': type}, function(json) {
var resources = json.resources;
for (r in resources) {
if (resources.hasOwnProperty(r)) {
thisResource = new Resource(resources[r], r);
that.resources.push(thisResource);
}
}
that.allResources = that.resources;
that.init();
});
};
/*
This function is a very good idea. You would send a json object with parameters to the back-end to filter results by, allowing search to get a lot better.
Bin.prototype.loadResources = function(url, params) {
var that = this;
this.jq.find('.resource').remove();
this.resources = [];
}
*/
Bin.prototype.searchString = function(str) {
var that = this;
this.resources = [];
// console.log(that.allResources);
for (var i = 0; i < that.allResources.length; i++) {
var r = that.allResources[i];
r.hide();
if ((r.title.toLowerCase().indexOf(str.toLowerCase()) != -1) || (r.description.toLowerCase().indexOf(str.toLowerCase()) != -1)) {
this.resources.push(r);
// console.log(r);
r.show();
}
}
this.init();
}
Bin.prototype.init = function() {
var that = this;
this.start_index = 0;
for (var i=0; i < this.resources.length; i++) {
if (i >= this.size) {
this.resources[i].hide();
} else {
this.resources[i].show();
}
}
var end_index = that.resources.length < that.size ? that.resources.length : that.size;
that.jq.find('.prevPage').hide();
that.jq.find('.nextPage').show();
that.jq.find('.totalResources').html(that.resources.length.toString());
that.jq.find('.start_index').html('1');
that.jq.find('.end_index').html(end_index.toString());
}
Bin.prototype.nextPage = function() {
var that = this;
var curr_index = this.start_index + this.size;
var end_index = curr_index + this.size > that.resources.length ? that.resources.length : curr_index + that.size;
for (var i = this.start_index; i < end_index; i++) {
if (i < curr_index) {
this.resources[i].hide();
} else {
this.resources[i].show();
}
}
this.start_index = curr_index;
// console.log(that.start_index + that.size);
if (this.start_index + this.size >= this.resources.length) {
this.jq.find('.nextPage').hide();
}
this.jq.find('.prevPage').show();
this.jq.find('.start_index').html((curr_index + 1).toString());
this.jq.find('.end_index').html(end_index.toString());
}
Bin.prototype.prevPage = function() {
var that = this;
var curr_start = this.start_index;
var end_index = this.start_index + this.size > this.resources.length ? this.resources.length - 1 : (this.start_index + this.size) - 1;
for (var j = 0; j < this.resources.length; j++) {
this.resources[j].hide();
}
for (var i = end_index; i > this.start_index - this.size; i--) {
// console.log(end_index);
if (i > this.start_index) {
// this.resources[i].hide();
} else {
this.resources[i].show();
}
}
this.start_index = curr_start - this.size;
if (this.start_index <= 0) {
this.start_index = 0;
this.jq.find('.prevPage').hide();
}
this.jq.find('.nextPage').show();
this.jq.find('.start_index').html((that.start_index + 1).toString());
this.jq.find('.end_index').html(curr_start.toString());
}
/*
@constructor
@class MyBin Class to deal with personal bins.
@property {String} name Name user assigns to bin to be uniquely identifiable
@property {Int} creator User id of user who created this bin. Might be useful to determine permissions.
CURRENTLY NOT USED.
*/
var MyBin = function() {
this.resources = [];
this.divid = 'mybin';
var that = this;
this.jq = $('#' + that.divid);
this.id = 0;
this.name = '';
this.creator = 0;
}
/*
Method to load bin from json
*/
MyBin.prototype.load = function(json) {
}
/*
Method to save bin to the database
*/
MyBin.prototype.save = function() {
}
/*
CURRENTLY NOT USED.
*/
var MyResource = function(json, index) {
this.index = index;
this.id = json.id;
this.divid = 'myresource' + this.index.toString();
this.type = json.type;
this.file = json.file;
this.description = json.description;
this.tags = json.tags;
this.mime = json.mime; //inaccurately called 'mime' - this is either image, text, audio or video, as a string.
this.icon = json.icon;
this.added = json.added;
this.addToBin();
}
MyResource.prototype.addToBin = function() {
}
var Resource = function(json, index) {
this.index = index;
this.id = json.id;
this.media_id = json.media_id;
this.divid = "resource" + this.index.toString();
this.type = json.type;
this.file = json.file;
this.title = json.title;
this.description = json.description;
this.tags = json.tags;
this.mime = json.mime;
this.icon = json.icon;
this.added = json.added;
this.width = json.width;
this.height = json.height;
this.tooltip = "<span class='resourceTitle'>" + this.title + "</span><br /><span class='resourceDescription'>" + this.description + "</span>";
this.resized = $.trim(json.resized);
this.displayed = true;
this.addToBin();
this.hide = function() {
this.displayed = false;
this.jq.hide();
}
this.show = function() {
this.displayed = true;
this.jq.show();
}
};
Resource.prototype.addToBin = function() {
var that = this;
var e = this.getBinElem();
edgeBin.jq.find('.binResources').append(e);
this.jq = $('#' + that.divid);
this.addEventHandlers();
};
Resource.prototype.getBinElem = function() {
var that = this;
var e = $('<div />');
e.html(that.getBinHtml());
e.attr("id", that.divid);
e.attr("data-index", that.index.toString());
e.attr("data-id", that.id.toString());
e.attr("title", that.tooltip);
e.addClass("resource");
e.css({'display': 'none'});
return e;
};
Resource.prototype.getBinHtml = function() {
var that = this;
var html = "<img src='" + that.icon + "' alt='foo' />";
return html
};
Resource.prototype.addEventHandlers = function() {
var that = this;
this.jq.tooltip();
var mim2tmpl = {
'image': "tmpl_resource_image",
'video': "tmpl_resource_av",
'audio': "tmpl_resource_av",
'text': "tmpl_resource_doc"
}
this.jq.hover(function() {
var tmpl_id = mim2tmpl[that.mime];
var html = tmpl(tmpl_id, {});
that.jq.append(html);
}, function() {
that.jq.find(".resourceMenu").remove();
});
/*
this.jq.dblclick(function() {
// console.log("foo");
var e = that.jq.clone().attr("id", that.jq.attr("id").replace("resource", "myresource"));
console.log(e);
$('#userBin').append(e);
});
*/
this.jq.draggable({ revert: true, helper: 'clone'});
};
function toPx(i) {
if (typeof i == 'string' && i.charAt(0) == '#') {
return i;
}
var inty = parseInt(i);
if (inty != NaN) {
var str = inty.toString() + "px";
return str;
} else {
return str + "px";
}
}
jQuery.fn.getResource = function() {
var jq = this.parents('.resource');
var resourceIndex = parseInt(jq.attr("data-index"));
return edgeBin.resources[resourceIndex];
}
jQuery.fn.getCanvas = function() {
var index = parseInt(this.parents('.canvas').attr("data-index"));
return edgeArticle[index];
}
jQuery.fn.getBox = function() {
var boxJq = this.parents('.box');
var boxIndex = parseInt(boxJq.attr("data-index"));
var canvasIndex = boxJq.parents('.canvas').attr("data-index");
if (boxJq.hasClass("textBox")) {
return edgeArticle[canvasIndex].textBoxes[boxIndex];
}
else if (boxJq.hasClass("imageBox")) {
return edgeArticle[canvasIndex].imageBoxes[boxIndex];
}
else {
return false;
}
}
/*
function getCanvasByElem(e) {
var index = parseInt(e.parents('.canvas').attr("data-index"));
return edgeArticle[index];
}
function getBoxByElem(e) {
var boxJq = e.parents('.box');
var boxIndex = parseInt(boxJq.attr("data-index"));
var canvasIndex = boxJq.parents('.canvas').attr("data-index");
if (boxJq.hasClass("textBox")) {
return edgeArticle[canvasIndex].textBoxes[boxIndex];
} else if (boxJq.hasClass("imageBox")) {
return edgeArticle[canvasIndex].imageBoxes[boxIndex];
} else {
return false;
}
}
*/
function loadArticle(json) {
for (j in json) {
if (json.hasOwnProperty(j)) {
new Canvas({}, json[j]);
}
}
}
/*
window.onload = function()
{
};
*/
$(document).ready(function(){
$(".newTextBox").draggable({ revert: true, helper: 'clone'});
});
/*
$(".box").live("dblclick", function(){
// $ ('.save_text').hide();
// element = $(this).find('.textbox_canvas_content');
// replaceDiv( element[0] );
// box = $(element).getBox().jq;
// box.draggable( 'disable' );
// box.resizable( 'disable' );
// $(element).parent().siblings('.save_text').show();
});
*/
var editor;
function removeEditor(element) {
if ( !editor )
return;
$(element).toggle();
box = $(element).getBox();
box.setHTML(editor.getData());
box.jq.draggable( 'enable' );
box.jq.resizable( 'enable' );
// Destroy the editor.
editor.destroy();
editor = null;
text_edit_mode = false;
box.jq.css('z-index', this_org_z);
}
function replaceDiv( div ) {
if ( editor )
editor.destroy();
// CKEDITOR.plugins.add('mysave',{
// init:function(a){
// var cmd = a.addCommand('mysave',{exec:CKsaveAjax})
// a.ui.addButton('MySave',{
// label:'Save',
// command:'mysave',
// icon:this.path+"images/save.png"
// })
// }
// })
// console.log(div);
// alert($(div).attr('classname'));
height = parseInt($(div).css('height'));
height = toPx(height);
width = parseInt($(div).css('width'));
width = toPx(width);
editor = CKEDITOR.replace( div,
{
width: width,
height: height,
toolbar : 'Basic',
uiColor : '#9AB8F3',
resize_enabled: false,
toolbarStartupExpanded: false,
skin: 'v2'
});
}
/*
height = parseInt($(div).css('height')) - 6;
height = toPx(height);
width = parseInt($(div).css('width')) - 6;
width = toPx(width);
editor = CKEDITOR.replace( div,
{
height: height,
toolbar : 'Basic',
uiColor : '#9AB8F3',
resize_enabled: false,
toolbarStartupExpanded: false,
skin: 'v2'
});
}
$(".box").live("mouseover", function(){
// if (!editor)
// $(this).find(".textbox_canvas_toolbox").show();
});
$(".box").live("mouseout", function(){
// $(this).find(".textbox_canvas_toolbox").hide();
});
*/
function cropImage(c)
{
crop_url = '/edit/imagebox/crop/?x1=' + c.x + '&y1=' + c.y + '&x2=' + c.x2 + '&y2=' + c.y2 + '&width=' + c.w + '&height=' + c.h + '&id=' + this_imagebox_id + '&uuid=' + UUID;
crop_dimensions = c;
};
text_edit_mode = false;
$(".box").live("click", function(e){
if (text_edit_mode) {
return false;
}
e.preventDefault();
var top = parseInt($(this).css('top'));
var left = parseInt($(this).css('left'));
var box = $(this).find('*').getBox().jq;
var boxObj = $(this).find('*').getBox();
if ($(".properties").length == 0) {
// console.log($(this).attr('class'))
if ($(this).hasClass("textBox")) {
$('body').append(tmpl('tmpl_textbox_properties', {}));
}
else if ($(this).hasClass("imageBox")) {
$('body').append(tmpl('tmpl_imagebox_properties', {}));
}
var canvas = $(this).getCanvas().jq;
canvas_top = parseInt(canvas.offset().top);
canvas_left = parseInt(canvas.offset().left);
$(".properties").css('top', toPx((e.pageY)));
$(".properties").css('left', toPx((e.pageX)));
} else {
$(".properties").remove();
//BAD HACK: removes the nudge binder if present. Got to be a better way to do this -- potentially bind to document using a custom nudge event, but not sure.
$(document).unbind("keydown");
//This should click itself, to then display properties wherever it is clicked, but it does not work:(
// $(this).trigger("click");
}
// i.setCSS({'top':toPx((ev.pageY - top) - height), 'left': toPx((ev.pageX - left) - width)});
current_val = box.css('background-color');
// console.log('current val: ' + current_val)
$('.properties').find('.backgroundColorSelector div').css('background-color', current_val);
$(".properties").find('.backgroundColorSelector').ColorPicker({
color: current_val,
onShow: function (colpkr) {
$(colpkr).fadeIn(500);
return false;
},
onHide: function (colpkr) {
$(colpkr).fadeOut(500);
boxObj.setCSS({'background-color': '#' + GLOBAL_HEX});
return false;
},
onChange: function (hsb, hex, rgb) {
$('.properties').find('.backgroundColorSelector div').css('background-color', '#' + hex);
box.css('background-color', '#' + hex);
GLOBAL_HEX = hex;
},
onBeforeShow: function () {
current_val = box.children('div').css('background-color');
$(this).ColorPickerSetColor(current_val);
}
});
var current_val = box.css('border-right-color');
$('.properties').find('.borderColorSelector div').css('background-color', current_val);
$(".properties").find('.borderColorSelector').ColorPicker({
color: current_val,
onShow: function (colpkr) {
$(colpkr).fadeIn(500);
return false;
},
onHide: function (colpkr) {
$(colpkr).fadeOut(500);
boxObj.setCSS({'border-color': '#' + GLOBAL_HEX});
return false;
},
onChange: function (hsb, hex, rgb) {
$('.properties').find('.borderColorSelector div').css('background-color', '#' + hex);
box.css('border-color', '#' + hex);
GLOBAL_HEX = hex;
}
});
var current_val = parseInt(box.css('padding'));
$(".properties").find(".change_padding").slider({
range: "max",
min: 0,
max: 40,
value: current_val,
slide: function(event, ui) {
i = parseInt(box.attr('data-index'));
height = parseInt(box.css('height'))
width = parseInt(box.css('width'))
// console.log(height + " - " + width)
org_padding = parseInt(box.css('padding'))
padding = org_padding - ui.value;
boxObj.setCSS({'padding-top': ui.value, 'padding-right': ui.value, 'padding-bottom': ui.value, 'padding-left': ui.value}, false)
boxObj.setCSS({'height': height + (2 * padding), 'width': width + (2 * padding)}, false)
},
stop: function(event, ui) {
i = parseInt(box.attr('data-index'));
height = parseInt(box.css('height'))
width = parseInt(box.css('width'))
// console.log(height + " - " + width)
org_padding = parseInt(box.css('padding'))
padding = org_padding - ui.value;
boxObj.setCSS({'padding-top': ui.value, 'padding-right': ui.value, 'padding-bottom': ui.value, 'padding-left': ui.value})
boxObj.setCSS({'height': height + (2 * padding), 'width': width + (2 * padding)})
}
});
var current_val = parseInt(box.css('border-right-width'));
$(".properties").find(".change_border").slider({
range: "max",
min: 0,
max: 5,
value: current_val,
slide: function(event, ui) {
boxObj.setCSS({'border-width': ui.value}, false)
},
stop: function(event, ui) {
boxObj.setCSS({'border-width': ui.value})
}
});
var current_val = 10 * box.css('opacity');
$(".properties").find(".change_opacity").slider({
range: "max",
min: 2,
max: 10,
value: current_val,
slide: function(event, ui) {
boxObj.setCSS({'opacity': ui.value / 10}, false);
},
stop: function(event, ui) {
thisBox = $(this).getBox();
boxObj.setCSS({'opacity': ui.value / 10});
}
});
$(".background_transparent").bind("click", function(e){
e.preventDefault();
boxObj.setCSS({'background-color': 'transparent'});
});
var current_val = box.css('border-style');
// $(".borderStyle").append('<option value="solid">skörví</option>');
var current_border_style = box.css('border-left-style');
$('select option[value*=' + current_border_style + ']').attr('selected','true');
$(".borderStyle").bind("change", function(e){
var val = $(this).val();
boxObj.setCSS({'border-style': val});
});
$(".crop_imagebox").bind("click", function(e){
e.preventDefault();
text_edit_mode = true;
box.resizable( 'disable' );
$(canvas).append(tmpl('tmpl_imagebox_crop', {}));
canvas_top = parseInt(canvas.offset().top);
canvas_left = parseInt(canvas.offset().left);
box_top = box.css('top');
box_left = box.css('left');
crop_box_top = parseInt(box_top) + parseInt(box.css('height')) + 5;
crop_box_left = parseInt(box_left);
$(".imagebox_crop").css('top', crop_box_top);
$(".imagebox_crop").css('left', crop_box_left);
image = box.find('.edgeImage');
this_imagebox_id = box.attr('data-id');
jcrop = $.Jcrop(image, {onSelect: cropImage}, function(){
});
$('.properties').remove();
$(".do_crop_imagebox").bind("click", function(e){
e.preventDefault();
box.resizable( 'enable' );
// console.log(url);
$.getJSON(crop_url, {
'article_id': ARTICLE_ID
}, function(data) {
// console.log(data.path);
new_top = parseInt(box_top) + crop_dimensions.y;
new_left = parseInt(box_left) + crop_dimensions.x;
boxObj.setCSS({'width': crop_dimensions.w, 'height': crop_dimensions.h}, false);
boxObj.setCSS({'top': new_top, 'left': new_left});
jcrop.destroy();
box.find('.edgeImage').attr("width", crop_dimensions.w);
box.find('.edgeImage').attr("height", crop_dimensions.h);
box.find('.edgeImage').attr('src', data.path);
$('.imagebox_crop').remove();
text_edit_mode = false;
REVISION_NO = data.rev_id;
});
});
$(".cancel_crop_imagebox").bind("click", function(e){
e.preventDefault();
jcrop.destroy();
$('.imagebox_crop').remove();
box.resizable( 'enable' );
text_edit_mode = false;
});
});
$(".nudge_box").bind("click", function(e){
e.preventDefault();
$(document).bind("keydown", function(event) {
// console.log(event.keyCode);
if (event.keyCode == '38') {
event.preventDefault();
var top = box.css('top');
if (parseInt(top) > 1) {
boxObj.setCSS({'top': toPx(parseInt(top) - 1)});
// console.log('up?');
}
}
if (event.keyCode == '40') {
event.preventDefault();
var top = box.css('top');
var height = box.outerHeight();
var lower_edge = parseInt(top) + parseInt(height);
var canvas_height = canvas.css('height');
// console.log('canvas_height:' + canvas_height);
// console.log('box lower:' + lower_edge);
if (lower_edge < parseInt(canvas_height)) {
boxObj.setCSS({'top': toPx(parseInt(top) + 1)});
// console.log('down?');
}
}
if (event.keyCode == '39') {
event.preventDefault();
var left = box.css('left');
var width = box.outerWidth();
var right_edge = parseInt(left) + parseInt(width);
canvas_width = canvas.css('width');
if (right_edge < parseInt(canvas_width)) {
boxObj.setCSS({'left': toPx(parseInt(left) + 1)});
}
}
if (event.keyCode == '37') {
event.preventDefault();
left = box.css('left');
if (parseInt(left) > 0) {
boxObj.setCSS({'left': toPx(parseInt(left) - 1)});
}
}
});
});
$(".edit_textbox").bind("click", function(e){
e.preventDefault();
$('.save_text').hide();
$('.properties').hide();
this_org_z = box.css('z-index');
box.css('z-index', '1000');
element = box.find('.textbox_canvas_content');
replaceDiv( element[0] );
boxObj = $(element).getBox();
// console.log(boxObj);
box = boxObj.jq;
if (box.css("direction") == 'rtl') {
setTimeout(function() { $($('iframe').get(0).contentDocument).find('html').attr("dir", "rtl") }, 500);
}
$('iframe').attr("allowtransparency", "false");
box.draggable('disable');
box.resizable('disable');
text_edit_mode = true;
$(element).parent().siblings('.save_text').show();
});
$(".z-index-add").bind("click", function(e){
e.preventDefault();
var canvas = box.parents('.canvas');
highest_index = getHighestIndex(canvas);
// console.log(highest_index);
var new_index = highest_index + 1;
boxObj.setCSS({'z-index': new_index});
reSortBoxes(canvas);
});
$(".z-index-sub").bind("click", function(e){
e.preventDefault();
canvas = box.parents('.canvas');
lowest_index = getLowestIndex(canvas);
new_index = lowest_index - 1;
boxObj.setCSS({'z-index': new_index});
reSortBoxes(canvas);
});
$(".delete_box").bind("click", function(e){
e.preventDefault();
if (confirm("are you sure you wish to permanently delete this box from this page?")) {
$(".properties").remove();
boxObj.deleteme();
}
});
});
$(".canvas").live("mousemove", function(e){
var left = parseInt($(this).position().left) + parseInt($(this).css('margin-left'));
var top = parseInt($(this).position().top) + parseInt($(this).css('margin-top'));
// console.log(top);
var pageCoords = "( " + (e.pageX - left) + ", " + (e.pageY - top) + " )";
$('#coordinates').html(pageCoords);
});
$(".canvas").live("mouseout", function(e){
$('#coordinates').html('');
});
/*
$(document).click(function(event) {
if ( !$(event.target).hasClass('.box') && !$(event.target).hasClass('properties')) {
// $(".textbox_properties").hide();
}
});
*/
$(document).ready(function() {
$(document).ajaxStart(function(){
$('#ajaxBusy').css("background", "#f00");
}).ajaxStop(function(){
$('#ajaxBusy').css("background", "#0f0");
});
});
//LIVE Click Handlers:
$('.image_rotate').live("click", function(e) {
var r = $(this).getResource();
var id = r.id;
var url = "/edit/image/rotate/" + id + "/";
window.open(url);
});
$('.download_doc').live("click", function(e) {
var r = $(this).getResource();
var path = r.file;
var base_url = "http://" + window.location.hostname
window.open(base_url + path);
});
$('.printMe').live("click", function(e) {
var page = $(this).getCanvas();
var page_id = page.id;
// var url = BASE_URL + "page_pdf/?p=" + page_id + "&a=" + ARTICLE_ID;
var url = BASE_URL + "print_article/?id=" + ARTICLE_ID;
window.open(url);
});
$(function() {
$('.viewFrontend').live("click", function(e) {
window.open(FRONTEND_URL);
e.preventDefault();
e.stopPropagation();
});
});
$('.upload_srts').live("click", function(e) {
var r = $(this).getResource();
var media_id = r.media_id;
var type = r.mime == 'video' ? 'video' : 'audio';
if (media_id == 0) {
alert("sorry, there was some problem with converting this audio / video, ID: " + r.id);
} else {
var adminUrl = "/admin/editor/" + type + "/" + r.media_id.toString();
window.open(adminUrl);
}
});
$('.play_media').live("click", function(e) {
var r = $(this).getResource();
var filePath = r.file;
var base_url = "http://" + window.location.hostname;
window.open(base_url + filePath);
});
$('.toggle_handle').live("click", function() {
var $that = $(this);
var page = $(this).parents('.canvas');
page.find('.ruler').each(function() {
if ($(this).is(":visible")) { $(this).fadeOut("fast"); } else { $(this).fadeIn("fast"); };
});
});
$('.delete_page').live("click", function(e) {
var canvas = $(this).getCanvas();
if (confirm("Are you sure you want to delete this page?")) {
canvas.deleteme();
}
});
$('.move_page_up').live("click", function(e) {
var canvas = $(this).getCanvas();
var currIndex = canvas.jq.index(".canvas");
if (currIndex == 0) {
return false;
}
var newIndex = currIndex - 1;
canvas.movePage(newIndex);
});
$('.move_page_down').live("click", function(e) {
var canvas = $(this).getCanvas();
var currIndex = canvas.jq.index(".canvas");
var newIndex = currIndex + 1;
canvas.movePage(newIndex);
});