607 lines
15 KiB
JavaScript
607 lines
15 KiB
JavaScript
// Generated by CoffeeScript 1.9.0
|
|
|
|
/*
|
|
Sahli Editor
|
|
============
|
|
|
|
Editor for Sahli files.
|
|
|
|
- open existing file
|
|
- create new item
|
|
* get filename from dir
|
|
* insert SAUCE data if available
|
|
* use SAUCE data to find font
|
|
* allow Amiga choices
|
|
* colorpicker
|
|
- edit existing item
|
|
- remove item
|
|
- clear whole file
|
|
- copy/clone
|
|
- move items around
|
|
- sort items
|
|
- output to screen (copy into file)
|
|
* run from node - save filename dialog
|
|
|
|
***
|
|
It should be noted that this does not do bounds checking, and it would be very
|
|
possible to overflow this by using a debugger and such. As the purpose of this
|
|
is limited, and this should NOT be put on a live website, I feel that is ok for
|
|
now. Perhaps I will fix it after Revision.
|
|
|
|
***
|
|
|
|
== Create Initial crappage
|
|
We need to make a screen that has a few things in it for starters
|
|
Title, load existing, and new file options.
|
|
|
|
Silliness for checking that this works.
|
|
*/
|
|
|
|
(function() {
|
|
var Emptyfiledef, Sahli, ansiorascii, arraytocolor, booltoint, colorindex, colortoarray, colortoname, dec2hex, dumpjson, getfilelist, hex2dec, inttobool, loadsahli, newsahli, resolvefiletype, sahlicolor, statustobool;
|
|
|
|
$(function() {
|
|
return $("h1").hide().slideDown(500);
|
|
});
|
|
|
|
|
|
/*
|
|
Create buttons to choose between the New and Load functionalities
|
|
(As we aren't going to ever load a file _and_ do a new file.)
|
|
(If someone wants to do that, they can restart with F5 or something.)
|
|
Also hide the editor until needed, and initialize some elements.
|
|
*/
|
|
|
|
$(function() {
|
|
return $("#newsahli").button({
|
|
disabled: false
|
|
}).click(function() {
|
|
return newsahli();
|
|
});
|
|
});
|
|
|
|
$(function() {
|
|
return $("#loadsahli").button({
|
|
disabled: false
|
|
}).click(function() {
|
|
return loadsahli();
|
|
});
|
|
});
|
|
|
|
$(function() {
|
|
$(".hidden").hide();
|
|
$("#entryamiga").button({
|
|
icons: {
|
|
primary: "ui-icon-gear"
|
|
}
|
|
}).click(function() {
|
|
var stuff;
|
|
stuff = $(this).children();
|
|
if (this.value === "1") {
|
|
stuff[1].textContent = 'Ansi';
|
|
return this.value = "0";
|
|
} else {
|
|
stuff[1].textContent = 'Ascii';
|
|
return this.value = "1";
|
|
}
|
|
});
|
|
$(".45box").css({
|
|
width: '40ex',
|
|
display: 'inline-block'
|
|
});
|
|
$(".groupbox p").css({
|
|
margin: "0 0 .25em 0"
|
|
});
|
|
$(".colorbox").change(function() {
|
|
return sahlicolor();
|
|
});
|
|
$("#entryfont").change(function() {
|
|
var font;
|
|
font = $("#entryfont").val();
|
|
if (font === "ansifont") {
|
|
font = "BlockZone";
|
|
}
|
|
return $('pre').css('font-family', font);
|
|
});
|
|
$("#entryfilepick").change(function() {
|
|
if (this.files[0] != null) {
|
|
return $("#entryfile").val(this.files[0].name);
|
|
}
|
|
});
|
|
return $("#entryfile").click(function() {
|
|
return $("#entryfilepick").click();
|
|
});
|
|
});
|
|
|
|
|
|
/*
|
|
The sahli file definition format is as follows:
|
|
"file" - the actual filename on disk, "name" - the title of the piece,
|
|
the boolean 'amiga' indicates if it is ansi or ascii (True = ascii),
|
|
width is the width (widest point of the file), author the author of the piece,
|
|
the color and bg items define the color for amiga ascii, and the font
|
|
defines the font similarly. For PC ansi, this should be 'ansifont.'
|
|
The three remaining lines are informational and optional.
|
|
|
|
The slide format is currently unused, but consists of a background picture,
|
|
a html template, and a css file.
|
|
*/
|
|
|
|
Emptyfiledef = (function() {
|
|
function Emptyfiledef() {
|
|
this.file = "";
|
|
this.name = "";
|
|
this.amiga = true;
|
|
this.filetype = 'plain';
|
|
this.width = "";
|
|
this.author = "";
|
|
this.font = "Propaz";
|
|
this.color = [255, 255, 255, 255];
|
|
this.bg = [0, 0, 0, 0];
|
|
this.line1 = "";
|
|
this.line2 = "";
|
|
this.text = "";
|
|
}
|
|
|
|
return Emptyfiledef;
|
|
|
|
})();
|
|
|
|
Sahli = (function() {
|
|
function Sahli() {
|
|
this.emptyfiledef = new Emptyfiledef;
|
|
this.emptyslidesdef = {
|
|
"background": "",
|
|
"template": "",
|
|
"css": ""
|
|
};
|
|
this.empty = {
|
|
"location": "",
|
|
"slides": this.emptyslidesdef,
|
|
"filedata": []
|
|
};
|
|
}
|
|
|
|
Sahli.prototype.loader = function() {
|
|
return $.ajax({
|
|
url: '../list.sahli',
|
|
dataType: "json",
|
|
success: (function(_this) {
|
|
return function(result) {
|
|
_this.data = result;
|
|
return _this.edit();
|
|
};
|
|
})(this)
|
|
});
|
|
};
|
|
|
|
Sahli.prototype.edit = function() {
|
|
$('#buttonbox').hide();
|
|
$('#dirlocation').change((function(_this) {
|
|
return function(event) {
|
|
return _this.data.location = event.target.value;
|
|
};
|
|
})(this));
|
|
$('#listsave').button({
|
|
icons: {
|
|
primary: "ui-icon-disk"
|
|
}
|
|
}).click((function(_this) {
|
|
return function() {
|
|
$('#sahlioutput').text(dumpjson(_this.data));
|
|
return $('#dumparea').show(100);
|
|
};
|
|
})(this));
|
|
$('#listlist').button({
|
|
icons: {
|
|
primary: "ui-icon-folder-open"
|
|
}
|
|
}).click(function() {
|
|
return getfilelist();
|
|
});
|
|
$('#listappend').button({
|
|
icons: {
|
|
primary: "ui-icon-1-n"
|
|
}
|
|
}).click((function(_this) {
|
|
return function(event) {
|
|
var newentry;
|
|
newentry = new Emptyfiledef;
|
|
_this.data.filedata.push(newentry);
|
|
return _this.buildlist(_this.data);
|
|
};
|
|
})(this));
|
|
$('#listdisplay').button({
|
|
icons: {
|
|
primary: "ui-icon-refresh"
|
|
}
|
|
}).click((function(_this) {
|
|
return function() {
|
|
return _this.buildlist(_this.data);
|
|
};
|
|
})(this));
|
|
$('#closespan').click(function() {
|
|
$(this.parentElement.parentElement).hide();
|
|
return $('#sahlioutput').text('');
|
|
});
|
|
return this.buildlist(this.data);
|
|
};
|
|
|
|
Sahli.prototype.buildlist = function(data) {
|
|
var i, item, x, _i, _j, _len, _len1, _ref, _ref1;
|
|
$('#list').show(100);
|
|
$('#list ol li').remove();
|
|
_ref = this.data.filedata;
|
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
i = _ref[_i];
|
|
console.log(i.author);
|
|
}
|
|
x = 0;
|
|
$('#dirlocation').val(this.data.location);
|
|
_ref1 = this.data.filedata;
|
|
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
|
|
item = _ref1[_j];
|
|
$('#sortlist').append(this.additem(item, x++));
|
|
}
|
|
return $('#sortlist').sortable({
|
|
start: function(event, ui) {
|
|
return ui.item.data({
|
|
startpos: ui.item.index()
|
|
});
|
|
},
|
|
stop: (function(_this) {
|
|
return function(event, ui) {
|
|
var a, e, s;
|
|
a = 2;
|
|
s = ui.item.data().startpos;
|
|
e = ui.item.index();
|
|
_this.data.filedata = _this.rearrangearray(s, e, _this.data.filedata);
|
|
return _this.buildlist(_this.data);
|
|
};
|
|
})(this)
|
|
});
|
|
};
|
|
|
|
Sahli.prototype.rearrangearray = function(startpos, endpos, a) {
|
|
var alen, moving, tarr;
|
|
moving = a[startpos];
|
|
alen = a.length;
|
|
tarr = a.slice(0, startpos).concat(a.slice(startpos + 1));
|
|
return tarr.slice(0, endpos).concat([moving].concat(tarr.slice(endpos)));
|
|
};
|
|
|
|
Sahli.prototype.additem = function(item, pos) {
|
|
var entry;
|
|
entry = this.genentryline(item, pos);
|
|
return entry.dblclick((function(_this) {
|
|
return function() {
|
|
return _this.editline(item, pos);
|
|
};
|
|
})(this));
|
|
};
|
|
|
|
Sahli.prototype.genentryline = function(item, pos) {
|
|
var amigastatus, arrows, delbutton, entry, whichone;
|
|
arrows = "<span class='ui-icon ui-icon-arrowthick-2-n-s'></span>";
|
|
amigastatus = ansiorascii(booltoint(item.amiga));
|
|
delbutton = $("<span class='righty' id=del-" + pos + ">delete</span>").click((function(_this) {
|
|
return function(event) {
|
|
pos = event.currentTarget.id.replace("del-", "");
|
|
_this.data.filedata.splice(pos, 1);
|
|
return _this.buildlist(_this.data);
|
|
};
|
|
})(this));
|
|
whichone = "<li class='entry' id='" + item.file + "'>" + arrows + amigastatus + " |";
|
|
whichone += " " + item.author + " : " + item.name + " : " + item.file + "</li>";
|
|
entry = $(whichone);
|
|
return entry.append(delbutton);
|
|
};
|
|
|
|
Sahli.prototype.save = function() {
|
|
var entry, pos;
|
|
pos = $("#entryindex").val();
|
|
entry = this.data.filedata[pos];
|
|
entry.name = $("#entryname").val();
|
|
entry.author = $("#entryauthor").val();
|
|
entry.amiga = statustobool($("#entryamiga").children()[1].textContent);
|
|
console.log($("#entryamiga").children()[1].textContent);
|
|
console.log(entry.amiga, entry.author);
|
|
entry.color = colortoarray($("#entrycolor").val());
|
|
entry.bg = colortoarray($("#entrybg").val());
|
|
entry.width = $("#entrywidth").val();
|
|
entry.line1 = $("#entryline1").val();
|
|
entry.line2 = $("#entryline2").val();
|
|
entry.text = $("#entrytext").val();
|
|
entry.font = $("#entryfont").val();
|
|
entry.file = $("#entryfile").val();
|
|
entry.filetype = $("#entryfiletype").val();
|
|
return this.buildlist(this.data);
|
|
};
|
|
|
|
Sahli.prototype.editline = function(data, pos) {
|
|
var bcol, fcol;
|
|
$("#formica").dialog({
|
|
width: '800',
|
|
modal: false,
|
|
title: "Entry " + data.file + " ",
|
|
buttons: [
|
|
{
|
|
text: "Cancel",
|
|
icons: {
|
|
primary: 'ui-icon-trash'
|
|
},
|
|
click: function() {
|
|
return $(this).dialog("close");
|
|
}
|
|
}, {
|
|
text: "Save",
|
|
icons: {
|
|
primary: 'ui-icon-disk'
|
|
},
|
|
click: (function(_this) {
|
|
return function(event) {
|
|
event.preventDefault();
|
|
_this.save();
|
|
return event.currentTarget.previousElementSibling.click();
|
|
};
|
|
})(this)
|
|
}
|
|
]
|
|
});
|
|
data.amiga = booltoint(data.amiga);
|
|
fcol = colortoname(arraytocolor(data.color));
|
|
bcol = colortoname(arraytocolor(data.bg));
|
|
$("#entryindex").val(pos);
|
|
$("#entryname").val(data.name);
|
|
$("#entryauthor").val(data.author);
|
|
$("#entryfiletpye").val(data.filetype);
|
|
$("#entryfiletype").children()[resolvefiletype(data.filetype)].selected = true;
|
|
$("#entryamiga").val(data.amiga);
|
|
$("#entryamiga").children()[1].textContent = ansiorascii(data.amiga);
|
|
$("#entryfont").val(data.font);
|
|
$("#entrycolor").val(fcol);
|
|
$("#entrycolor").children()[colorindex(fcol)].selected = true;
|
|
$("#entrybg").val(bcol);
|
|
$("#entrybg").children()[colorindex(bcol)].selected = true;
|
|
$("#entrywidth").val(data.width);
|
|
$("#entryline1").val(data.line1);
|
|
$("#entryline2").val(data.line2);
|
|
$("#entrytext").val(data.text);
|
|
$("#entryfile").val(data.file);
|
|
return sahlicolor();
|
|
};
|
|
|
|
return Sahli;
|
|
|
|
})();
|
|
|
|
|
|
/*
|
|
A Helper function to dump json out of an object as text:
|
|
*/
|
|
|
|
dumpjson = function(obj) {
|
|
return JSON.stringify(obj, null, "\t");
|
|
};
|
|
|
|
|
|
/*
|
|
Boolean / integer Helpers
|
|
*/
|
|
|
|
booltoint = function(bool) {
|
|
return bool + 1 - 1;
|
|
};
|
|
|
|
inttobool = function(intstr) {
|
|
return (intstr === 1).toString();
|
|
};
|
|
|
|
statustobool = function(status) {
|
|
if (status === 'Ascii') {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
|
|
/*
|
|
Resolve filetype offset in array:
|
|
*/
|
|
|
|
resolvefiletype = function(filetype) {
|
|
var options;
|
|
options = {
|
|
"plain": 0,
|
|
"ansi": 1,
|
|
"xbin": 2,
|
|
"ice": 3,
|
|
"adf": 4,
|
|
"avatar": 5,
|
|
"bin": 6,
|
|
"idf": 7,
|
|
"pcboard": 8,
|
|
"tundra": 9
|
|
};
|
|
return options[filetype];
|
|
};
|
|
|
|
|
|
/*
|
|
Resolve ansi or ascii status
|
|
*/
|
|
|
|
ansiorascii = function(status) {
|
|
if (status === 0) {
|
|
return "Ansi";
|
|
} else {
|
|
return "Ascii";
|
|
}
|
|
};
|
|
|
|
|
|
/*
|
|
Color conversion from array to color item:
|
|
|
|
This decimal to hex conversion only handles 00-FF but it's fine for this
|
|
purpose; we actually _want_ that limitation in the output.
|
|
*/
|
|
|
|
dec2hex = function(num) {
|
|
return "" + (('000' + num.toString(16)).slice(-2));
|
|
};
|
|
|
|
hex2dec = function(num) {
|
|
return parseInt(num, 16);
|
|
};
|
|
|
|
arraytocolor = function(array) {
|
|
var c, x;
|
|
c = ((function() {
|
|
var _i, _len, _results;
|
|
_results = [];
|
|
for (_i = 0, _len = array.length; _i < _len; _i++) {
|
|
x = array[_i];
|
|
_results.push(dec2hex(x));
|
|
}
|
|
return _results;
|
|
})()).slice(0, 3).join('');
|
|
return "#" + c;
|
|
};
|
|
|
|
colortoarray = function(color) {
|
|
var c1, i, x;
|
|
color = color.slice(1);
|
|
c1 = [color.slice(0, 2), color.slice(2, 4), color.slice(4, 6)];
|
|
x = (function() {
|
|
var _i, _len, _results;
|
|
_results = [];
|
|
for (_i = 0, _len = c1.length; _i < _len; _i++) {
|
|
i = c1[_i];
|
|
_results.push(hex2dec(i));
|
|
}
|
|
return _results;
|
|
})();
|
|
x.push(255);
|
|
return x;
|
|
};
|
|
|
|
|
|
/*
|
|
Need a way to convert the array back to the color name.
|
|
*/
|
|
|
|
colortoname = function(color) {
|
|
var bw, colorname, names, ret;
|
|
names = {
|
|
"#E0E0E0": "Light Grey",
|
|
"#A0A0E0": "Light Blue",
|
|
"#9AFE2E": "Light Green",
|
|
"#FF0000": "Red",
|
|
"#FF8000": "Orange",
|
|
"#FFFF00": "Yellow",
|
|
"#00F000": "Green",
|
|
"#2EFEF7": "Cyan",
|
|
"#002EF7": "Blue",
|
|
"#0B0B3B": "Navy",
|
|
"#FF00FF": "Magenta",
|
|
"#8000FF": "Purple",
|
|
"#0A2A0A": "Dark Green",
|
|
"#3B3B3B": "Dark Grey",
|
|
"#FFFFFF": "White",
|
|
"#000000": "Black"
|
|
};
|
|
color = color.toUpperCase();
|
|
colorname = names[color];
|
|
bw = hex2dec(color.slice(1)) > 8421504 ? 'White' : "Black";
|
|
return ret = colorname != null ? colorname : bw;
|
|
};
|
|
|
|
|
|
/*
|
|
Similarly, need to be able to get the color index.
|
|
*/
|
|
|
|
colorindex = function(colorname) {
|
|
var names;
|
|
names = {
|
|
"Light Grey": 0,
|
|
"Light Blue": 1,
|
|
"Light Green": 2,
|
|
"Red": 3,
|
|
"Orange": 4,
|
|
"Yellow": 5,
|
|
"Green": 6,
|
|
"Cyan": 7,
|
|
"Blue": 8,
|
|
"Navy": 9,
|
|
"Magenta": 10,
|
|
"Purple": 11,
|
|
"Dark Green": 12,
|
|
"Dark Grey": 13,
|
|
"White": 14,
|
|
"Black": 15
|
|
};
|
|
return names[colorname];
|
|
};
|
|
|
|
|
|
/*
|
|
A function for changing the fore and background colors of the sahli ascii
|
|
example
|
|
*/
|
|
|
|
sahlicolor = function() {
|
|
var bg, fg;
|
|
fg = $('#entrycolor').val();
|
|
bg = $('#entrybg').val();
|
|
console.log('sahlicolor', fg, bg);
|
|
return $('#sahliascii').css({
|
|
'color': fg,
|
|
'background': bg
|
|
});
|
|
};
|
|
|
|
|
|
/*
|
|
Function for loading the filelist from the specified directory on the
|
|
server/filesystem.
|
|
Needs to be made into an actual real thing.
|
|
*/
|
|
|
|
getfilelist = function() {
|
|
var location;
|
|
location = $("#dirlocation").val();
|
|
return $.get("../" + location, function(listing) {
|
|
return console.log(listing);
|
|
});
|
|
};
|
|
|
|
|
|
/*
|
|
When clicking 'New' we want to make a brand new Sahli, and then clear out
|
|
the buttons and create the editor bit as blank.
|
|
*/
|
|
|
|
newsahli = function() {
|
|
var newentry, sahli;
|
|
sahli = new Sahli;
|
|
sahli.data = sahli.empty;
|
|
newentry = new Emptyfiledef;
|
|
sahli.data.filedata.push(newentry);
|
|
return sahli.edit();
|
|
};
|
|
|
|
|
|
/*
|
|
And when clicking 'load' we want to load the existing sahli file.
|
|
*/
|
|
|
|
loadsahli = function() {
|
|
var sahli;
|
|
sahli = new Sahli;
|
|
return sahli.loader('list.sahli');
|
|
};
|
|
|
|
}).call(this);
|