summaryrefslogtreecommitdiff
path: root/data
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2011-03-14 13:12:54 +0100
committerYorhel <git@yorhel.nl>2011-03-14 13:12:54 +0100
commit17d4f695b114f970c3b3c4c17c4b8915a0356297 (patch)
tree5e12ab47403fcf7919ebbde2a961c92506331850 /data
parent4582a5dce7c0793fe64806d4cba5ab9d386ea878 (diff)
chardb: Added Char<->VN linking edit interface
Still somewhat quircky, but it works.
Diffstat (limited to 'data')
-rw-r--r--data/global.pl1
-rw-r--r--data/script.js207
-rw-r--r--data/style.css12
3 files changed, 218 insertions, 2 deletions
diff --git a/data/global.pl b/data/global.pl
index 3f1ba3b6..5fd2bf85 100644
--- a/data/global.pl
+++ b/data/global.pl
@@ -108,6 +108,7 @@ our %S = (%S,
vnlist_status => [ 0..4 ],
blood_types => [qw| unknown a b ab o |],
genders => [qw| unknown m f b |],
+ char_roles => [qw| main primary side appears |],
atom_feeds => { # num_entries, title, id
announcements => [ 10, 'VNDB Site Announcements', '/t/an' ],
changes => [ 25, 'VNDB Recent Changes', '/hist' ],
diff --git a/data/script.js b/data/script.js
index f7b6eb1b..1aa60efa 100644
--- a/data/script.js
+++ b/data/script.js
@@ -1,5 +1,6 @@
/* function/attribute prefixes:
* ctr -> Character <-> trait linking
+ * cvn -> Character <-> VN linking
* date -> Date selector
* dd -> dropdown
* ds -> dropdown search
@@ -1774,7 +1775,7 @@ function ctrLoad() {
var t = ht.responseXML.getElementsByTagName('item');
for(var i=0; i<t.length; i++)
ctrAdd(t[i], v[t[i].getAttribute('id')]);
- });
+ }, 1);
else
ctrEmpty();
@@ -1786,7 +1787,7 @@ function ctrLoad() {
tr.appendChild(tag('td',
tag('b', {'class':'grayedout'}, g), item.firstChild.nodeValue,
tag('b', {'class':'grayedout'}, item.getAttribute('meta')=='yes' ? mt('_js_ds_tag_meta') : '')));
- }, ctrFormAdd, function () {});
+ }, ctrFormAdd);
}
function ctrEmpty() {
@@ -1884,6 +1885,208 @@ if(byId('traits_tbl'))
+/* C H A R A C T E R < - > V N L I N K I N G (/c+/edit) */
+
+// TODO: translate!
+
+function cvnLoad() {
+ // load current links
+ var l = byId('vns').value.split(' ');
+ var v = {}; // vid -> { rid: [ role, spoil ], .. }
+ var q = []; // list of v=X parameters
+ for(var i=0; i<l.length; i++) {
+ if(!l[i])
+ continue;
+ var m = l[i].split(/-/); // vid, rid, spoil, role
+ if(!v[m[0]]) {
+ q.push('v='+m[0]);
+ v[m[0]] = {};
+ }
+ v[m[0]][m[1]] = [ m[3], m[2] ];
+ }
+ if(q.length > 0)
+ ajax('/xml/releases.xml?'+q.join(';'), function(hr) {
+ var vns = byName(hr.responseXML, 'vn');
+ for(var i=0; i<vns.length; i++) {
+ var vid = vns[i].getAttribute('id');
+ cvnVNAdd(vns[i]);
+ var rels = byName(vns[i], 'release');
+ for(var r=0; r<rels.length; r++) {
+ var rid = rels[r].getAttribute('id');
+ if(v[vid][rid])
+ cvnRelAdd(vid, rid, v[vid][rid][0], v[vid][rid][1]);
+ }
+ if(v[vid][0])
+ cvnRelAdd(vid, 0, v[vid][0][0], v[vid][0][1]);
+ }
+ }, 1);
+ else
+ cvnEmpty();
+
+ // dropdown search
+ dsInit(byId('vns_input'), '/xml/vn.xml?q=', function(item, tr) {
+ tr.appendChild(tag('td', { style: 'text-align: right; padding-right: 5px'}, 'v'+item.getAttribute('id')));
+ tr.appendChild(tag('td', shorten(item.firstChild.nodeValue, 40)));
+ }, cvnFormAdd);
+}
+
+function cvnEmpty() {
+ var x = byId('vns_loading');
+ var t = byId('vns_tbl');
+ if(x)
+ t.removeChild(x);
+ var l = byName(t, 'tr');
+ var e = byId('vns_empty');
+ if(e && l.length > 1)
+ t.removeChild(e);
+ else if(!e && l.length < 1)
+ t.appendChild(tag('tr', {id:'vns_empty',colspan:3}, tag('td', 'No visual novels selected.')));
+}
+
+function cvnVNAdd(vn, rel) {
+ var vid = vn.getAttribute('id');
+ var rels = byName(vn, 'release');
+ byId('vns_tbl').appendChild(tag('tr', {id:'cvn_v'+vid, cvn_vid:vid, cvn_rels:rels},
+ tag('td', {'class':'tc_vn',colspan:4}, 'v'+vid+':',
+ tag('a', {href:'/v'+vid}, vn.getAttribute('title')),
+ tag('i', '(', tag('a', {href:'#', onclick:cvnRelNew}, 'add release'), ')')
+ )
+ ));
+ if(rel)
+ cvnRelAdd(vid, 0, 'primary', 0);
+ cvnEmpty();
+}
+
+function cvnRelAdd(vid, rid, role, spoil) {
+ var rels = byId('cvn_v'+vid).cvn_rels;
+ var rsel = tag('select', {onchange:cvnRelChange}, tag('option', {value:0}, 'All / others'));
+ for(var i=0; i<rels.length; i++) {
+ var id = rels[i].getAttribute('id');
+ rsel.appendChild(tag('option', {value: id, selected:id==rid},
+ '['+rels[i].getAttribute('lang')+'] '+rels[i].firstChild.nodeValue+' (r'+id+')'));
+ }
+
+ var lsel = tag('select', {onchange:cvnSerialize});
+ for(var i=0; i<char_roles.length; i++)
+ lsel.appendChild(tag('option', {value: char_roles[i], selected:char_roles[i]==role}, char_roles[i]));
+
+ // l10n /_spoil_\d+/
+ var ssel = tag('select', {onchange:cvnSerialize});
+ for(var i=0; i<3; i++)
+ ssel.appendChild(tag('option', {value:i, selected:i==spoil}, mt('_spoil_'+i)));
+
+ var tbl = byId('vns_tbl');
+ var l = byName(tbl, 'tr');
+ var last = null;
+ for(var i=1; i<l.length; i++)
+ if(l[i-1].cvn_vid == vid && l[i].cvn_vid != vid)
+ last = l[i-1];
+ tbl.insertBefore(tag('tr', {id:'cvn_v'+vid+'r'+rid, cvn_vid:vid, cvn_rid:rid},
+ tag('td', {'class':'tc_rel'}, rsel),
+ tag('td', {'class':'tc_rol'}, lsel),
+ tag('td', {'class':'tc_spl'}, ssel),
+ tag('td', {'class':'tc_del'}, tag('a', {href:'#', onclick:cvnRelDel}, 'remove'))
+ ), last);
+}
+
+function cvnRelChange() {
+ // look for duplicates and disallow the change
+ var val = this.options[this.selectedIndex].value;
+ var tr = this;
+ while(tr.nodeName.toLowerCase() != 'tr')
+ tr = tr.parentNode;
+ if(byId('cvn_v'+tr.cvn_vid+'r'+val)) {
+ alert('Release already selected.');
+ for(var i=0; i<this.options.length; i++)
+ this.options[i].selected = this.options[i].value == tr.cvn_rid;
+ return;
+ }
+ // otherwise, 'rename' this entry
+ tr.id = 'cvn_v'+tr.cvn_vid+'r'+val;
+ tr.cvn_rid = val;
+ cvnSerialize();
+}
+
+function cvnRelNew() {
+ var tr = this;
+ while(tr.nodeName.toLowerCase() != 'tr')
+ tr = tr.parentNode;
+ var id = 0;
+ if(byId('cvn_v'+tr.cvn_vid+'r0')) {
+ for(var i=0; i<tr.cvn_rels.length; i++) {
+ id = tr.cvn_rels[i].getAttribute('id');
+ if(!byId('cvn_v'+tr.cvn_vid+'r'+id))
+ break;
+ }
+ if(i == tr.cvn_rels.length) {
+ alert('All releases already selected');
+ return false;
+ }
+ }
+ cvnRelAdd(tr.cvn_vid, id, 'primary', 0);
+ cvnSerialize();
+ return false;
+}
+
+function cvnRelDel() {
+ var tbl = byId('vns_tbl');
+ var tr = this;
+ while(tr.nodeName.toLowerCase() != 'tr')
+ tr = tr.parentNode;
+ tbl.removeChild(tr);
+ var l = byName(tbl, 'tr');
+ var c = 0;
+ for(var i=0; i<l.length; i++)
+ if(l[i].cvn_vid == tr.cvn_vid)
+ c++;
+ if(c <= 1)
+ tbl.removeChild(byId('cvn_v'+tr.cvn_vid));
+ cvnSerialize();
+ cvnEmpty();
+ return false;
+}
+
+function cvnFormAdd(item) {
+ var inpt = byId('vns_input');
+ inpt.disabled = true;
+
+ ajax('/xml/releases.xml?v='+item.getAttribute('id'), function(hr) {
+ inpt.disabled = false;
+ inpt.value = '';
+
+ var items = byName(hr.responseXML, 'vn');
+ if(items.length < 1) // shouldn't happen
+ return alert('Oops! Error!');
+
+ var id = items[0].getAttribute('id');
+ if(byId('cvn_v'+id))
+ return alert(mt('VN already present.'));
+ cvnVNAdd(items[0], 1);
+ cvnSerialize();
+ }, 1);
+ return mt('_js_loading');
+}
+
+function cvnSerialize() {
+ var l = byName(byId('vns_tbl'), 'tr');
+ var v = [];
+ for(var i=0; i<l.length; i++)
+ if(l[i].cvn_rid != null) {
+ var rol = byName(byClass(l[i], 'tc_rol')[0], 'select')[0];
+ var spl = byName(byClass(l[i], 'tc_spl')[0], 'select')[0];
+ v.push(l[i].cvn_vid+'-'+l[i].cvn_rid+'-'+
+ spl.options[spl.selectedIndex].value+'-'+
+ rol.options[rol.selectedIndex].value);
+ }
+ byId('vns').value = v.join(' ');
+}
+
+if(byId('jt_box_chare_vns'))
+ cvnLoad();
+
+
+
+
/* F I L T E R S Y S T E M */
diff --git a/data/style.css b/data/style.css
index 27d0aeec..de55a177 100644
--- a/data/style.css
+++ b/data/style.css
@@ -872,6 +872,18 @@ div.chardetails table td.key { width: 80px; }
#jt_box_chare_traits td.tc_name { width: 200px }
#jt_box_chare_traits td.tc_name input { width: 280px; }
#jt_box_chare_traits td.tc_spoil { width: 80px; }
+#jt_box_chare_vns table { margin-bottom: 10px; margin-left: 10px; }
+#jt_box_chare_vns h2 { margin: 0 0 3px 0px; }
+#jt_box_chare_vns td.tc_vn { font-weight: bold; padding: 5px 0 3px 0 }
+#jt_box_chare_vns td.tc_vn i{ font-weight: normal; padding-left: 5px; font-style: normal }
+#jt_box_chare_vns td.tc_rel { width: 340px; padding-left: 15px }
+#jt_box_chare_vns td.tc_rel select { width: 340px; }
+#jt_box_chare_vns td.tc_rol,
+#jt_box_chare_vns td.tc_spl,
+#jt_box_chare_vns td.tc_rol select,
+#jt_box_chare_vns td.tc_spl select { width: 100px }
+#jt_box_chare_vns td.tc_del { padding-left: 5px }
+#jt_box_chare_vns td.tc_vnadd input { width: 280px }
/***** Documentation pages *****/