summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--data/style.css12
-rw-r--r--lib/VNDB/Handler/Releases.pm16
-rw-r--r--lib/VNDB/Handler/Tags.pm2
-rw-r--r--lib/VNDB/Handler/VNBrowse.pm2
-rw-r--r--lib/VNDB/Handler/VNEdit.pm2
-rw-r--r--lib/VNDB/Util/LayoutHTML.pm4
-rw-r--r--static/f/forms.js123
-rw-r--r--static/f/script.js208
9 files changed, 229 insertions, 145 deletions
diff --git a/ChangeLog b/ChangeLog
index 5966c38d..9e12388f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,11 @@ git - ?
- vn_relations.relation
- anime.type
- New language: Hungarian
+ - Complete rewrite of the Javascript code:
+ - Intended to be less error prone, more maintainable, and easier to make
+ 'XHTML compliant' in the future (currently still has some issues here).
+ - Improved spoiler selection on /v+/tagmod
+ - Everything merged into one file.
2.7 - 2009-09-24
- Improved styling of the threeboxes layout
diff --git a/data/style.css b/data/style.css
index 139551c9..192f909d 100644
--- a/data/style.css
+++ b/data/style.css
@@ -866,13 +866,11 @@ div.scr_uploader { visibility: hidden; overflow: hidden; width: 1px; height: 1px
#media_div { padding-left: 20px; }
#media_div span { display: block }
-#jt_box_rel_vn h2, #jt_box_rel_prod h2 { clear: left; padding-top: 10px; }
-#jt_box_rel_vn div, #jt_box_rel_prod div { padding-left: 20px }
-#jt_box_rel_vn input, #jt_box_rel_prod input { margin-right: 10px; width: 300px }
-#jt_box_rel_vn span, #jt_box_rel_prod span { clear: left; display: block; padding: 2px; }
-#jt_box_rel_vn span.odd, #jt_box_rel_prod span.odd { background: url($_boxbg$) repeat; }
-#jt_box_rel_vn i, #jt_box_rel_prod i { font-style: normal; display: block; float: left; width: 310px }
-#jt_box_rel_vn b, #jt_box_rel_prod b { font-weight: normal; }
+#jt_box_rel_vn h2, #jt_box_rel_prod h2 { clear: left; padding-top: 10px; }
+#jt_box_rel_vn div, #jt_box_rel_vn table,
+#jt_box_rel_prod div, #jt_box_rel_prod table { margin-left: 20px }
+#jt_box_rel_vn input, #jt_box_rel_prod input { margin-right: 10px; width: 300px }
+#jt_box_rel_vn .tc_title, #jt_box_rel_prod .tc_name { width: 310px; padding: 2px }
diff --git a/lib/VNDB/Handler/Releases.pm b/lib/VNDB/Handler/Releases.pm
index f0daa4cb..e7442845 100644
--- a/lib/VNDB/Handler/Releases.pm
+++ b/lib/VNDB/Handler/Releases.pm
@@ -370,7 +370,7 @@ sub edit {
$frm->{original} = $v->{original} if !defined $frm->{original} && !$r;
my $title = mt $rid ? ($copy ? '_redit_title_copy' : '_redit_title_edit', $r->{title}) : ('_redit_title_add', $v->{title});
- $self->htmlHeader(js => 'forms', title => $title, noindex => 1);
+ $self->htmlHeader(title => $title, noindex => 1);
$self->htmlMainTabs('r', $r, $copy ? 'copy' : 'edit') if $rid;
$self->htmlMainTabs('v', $v, 'edit') if $vid;
$self->htmlEditMessage('r', $r, $title, $copy);
@@ -446,12 +446,11 @@ sub _form {
[ hidden => short => 'producers' ],
[ static => nolabel => 1, content => sub {
h2 mt('_redit_form_prod_sel');
- div id => 'producerssel';
- end;
+ table; tbody id => 'producer_tbl'; end; end;
h2 mt('_redit_form_prod_add');
div;
- input type => 'text', class => 'text';
- a href => '#', 'add';
+ input id => 'producer_input', type => 'text', class => 'text';
+ a id => 'producer_add', href => '#', 'add';
end;
}],
],
@@ -460,12 +459,11 @@ sub _form {
[ hidden => short => 'vn' ],
[ static => nolabel => 1, content => sub {
h2 mt('_redit_form_vn_sel');
- div id => 'vnsel';
- end;
+ table; tbody id => 'vn_tbl'; end; end;
h2 mt('_redit_form_vn_add');
div;
- input type => 'text', class => 'text';
- a href => '#', 'add';
+ input id => 'vn_input', type => 'text', class => 'text';
+ a href => '#', id => 'vn_add', 'add';
end;
}],
],
diff --git a/lib/VNDB/Handler/Tags.pm b/lib/VNDB/Handler/Tags.pm
index 0f8b780a..6a13446b 100644
--- a/lib/VNDB/Handler/Tags.pm
+++ b/lib/VNDB/Handler/Tags.pm
@@ -422,7 +422,7 @@ sub vntagmod {
my $frm;
my $title = mt '_tagv_title', $v->{title};
- $self->htmlHeader(title => $title, noindex => 1, js => 'forms');
+ $self->htmlHeader(title => $title, noindex => 1);
$self->htmlMainTabs('v', $v, 'tagmod');
div class => 'mainbox';
h1 $title;
diff --git a/lib/VNDB/Handler/VNBrowse.pm b/lib/VNDB/Handler/VNBrowse.pm
index 2a6d6cd7..b0c948cd 100644
--- a/lib/VNDB/Handler/VNBrowse.pm
+++ b/lib/VNDB/Handler/VNBrowse.pm
@@ -70,7 +70,7 @@ sub list {
$self->resRedirect('/v'.$list->[0]{id}, 'temp')
if $f->{q} && @$list == 1;
- $self->htmlHeader(title => mt('_vnbrowse_title'), search => $f->{q}, js => 'forms');
+ $self->htmlHeader(title => mt('_vnbrowse_title'), search => $f->{q});
_filters($self, $f, $char, \@ignored);
my $url = "/v/$char?q=$f->{q};ti=$f->{ti};te=$f->{te}";
diff --git a/lib/VNDB/Handler/VNEdit.pm b/lib/VNDB/Handler/VNEdit.pm
index e618b360..8430156d 100644
--- a/lib/VNDB/Handler/VNEdit.pm
+++ b/lib/VNDB/Handler/VNEdit.pm
@@ -97,7 +97,7 @@ sub edit {
$frm->{editsum} = sprintf 'Reverted to revision v%d.%d', $vid, $rev if $rev && !defined $frm->{editsum};
my $title = $vid ? mt('_vnedit_title_edit', $v->{title}) : mt '_vnedit_title_add';
- $self->htmlHeader(js => 'forms', title => $title, noindex => 1);
+ $self->htmlHeader(title => $title, noindex => 1);
$self->htmlMainTabs('v', $v, 'edit') if $vid;
$self->htmlEditMessage('v', $v, $title);
_form($self, $v, $frm);
diff --git a/lib/VNDB/Util/LayoutHTML.pm b/lib/VNDB/Util/LayoutHTML.pm
index 99b615b5..524b6258 100644
--- a/lib/VNDB/Util/LayoutHTML.pm
+++ b/lib/VNDB/Util/LayoutHTML.pm
@@ -10,11 +10,10 @@ use VNDB::Func;
our @EXPORT = qw|htmlHeader htmlFooter|;
-sub htmlHeader { # %options->{ title, js, noindex, search }
+sub htmlHeader { # %options->{ title, noindex, search }
my($self, %o) = @_;
my $skin = $self->reqParam('skin') || $self->authInfo->{skin} || $self->{skin_default};
$skin = $self->{skin_default} if !$self->{skins}{$skin} || !-d "$VNDB::ROOT/static/s/$skin";
- $self->{js} = $o{js}; # save for use in htmlFooter
# heading
html;
@@ -159,7 +158,6 @@ sub htmlFooter {
end;
end; # /div maincontent
script type => 'text/javascript', src => $self->{url_static}.'/f/script.js?'.$self->{version}, '';
- script type => 'text/javascript', src => $self->{url_static}.'/f/forms.js?'.$self->{version}, '' if $self->{js};
end; # /body
end; # /html
diff --git a/static/f/forms.js b/static/f/forms.js
deleted file mode 100644
index 99b8bd13..00000000
--- a/static/f/forms.js
+++ /dev/null
@@ -1,123 +0,0 @@
-function qq(v) {
- return v.replace(/&/g,"&amp;").replace(/</,"&lt;").replace(/>/,"&gt;").replace(/"/g,'&quot;');
-}
-
-
-
-
- /****************************************************\
- * V I S U A L N O V E L S / P R O D U C E R S *
- \****************************************************/
-
-
-function vnpLoad(type) {
- // load currently selected VNs
- var l = x(type).value.split('|||');
- for(var i=0;i<l.length;i++)
- if(l[i].length > 2)
- vnpAdd(type, l[i].split(',',2)[0], l[i].split(',',2)[1]);
- vnpCheckEmpty(type);
-
- // dropdown
- var n = x('jt_box_'+(type == 'vn' ? 'rel_vn' : 'rel_prod')).getElementsByTagName('div')[1];
- dsInit(n.getElementsByTagName('input')[0], '/xml/'+type+'.xml?q=', function(item, tr) {
- var td = document.createElement('td');
- td.innerHTML = type.substr(0,1)+item.getAttribute('id');
- td.style.textAlign = 'right';
- td.style.paddingRight = '5px';
- tr.appendChild(td);
- td = document.createElement('td');
- td.innerHTML = shorten(item.firstChild.nodeValue, 40);
- tr.appendChild(td);
- }, function(item) {
- return type.substr(0,1)+item.getAttribute('id')+':'+item.firstChild.nodeValue;
- }, function() { vnpFormAdd(type) });
- n.getElementsByTagName('a')[0].onclick = function() { vnpFormAdd(type); return false };
-}
-
-function vnpAdd(type, id, title) {
- var o = document.createElement('span');
- o.innerHTML = '<i>'+type.substr(0,1)+id+':<a href="/'+type.substr(0,1)+id+'">'+shorten(title, 40)+'</a></i>'
- +'<a href="#" onclick="return vnpDel(this, \''+type+'\')">remove</a>';
- x(type+'sel').appendChild(o);
- vnpStripe(type);
- vnpCheckEmpty(type);
-}
-
-function vnpDel(what, type) {
- what = what.nodeName ? what : this;
- while(what.nodeName.toLowerCase() != 'span')
- what = what.parentNode;
- x(type+'sel').removeChild(what);
- vnpCheckEmpty(type);
- vnpSerialize(type);
- return false;
-}
-
-function vnpCheckEmpty(type) {
- var o = x(type+'sel');
- if(o.getElementsByTagName('span').length < 1) {
- if(o.getElementsByTagName('b').length < 1)
- o.innerHTML = '<b>Nothing selected...</b>';
- } else if(o.getElementsByTagName('b').length == 1)
- o.removeChild(o.getElementsByTagName('b')[0]);
-}
-
-function vnpStripe(type) {
- var l = x(type+'sel').getElementsByTagName('span');
- for(var i=0;i<l.length;i++)
- l[i].className = i%2 ? 'odd' : '';
-}
-
-function vnpFormAdd(type) {
- var n = x('jt_box_'+(type == 'vn' ? 'rel_vn' : 'rel_prod')).getElementsByTagName('div')[1];
- var txt = n.getElementsByTagName('input')[0];
- var lnk = n.getElementsByTagName('a')[0];
- var input = txt.value;
-
- if(type == 'vn' && !input.match(/^v[0-9]+/)) {
- alert('Visual novel textbox must start with an ID (e.g. v17)');
- return false;
- }
- if(type == 'producers' && !input.match(/^p[0-9]+/)) {
- alert('Producer textbox must start with an ID (e.g. p5)');
- return false;
- }
-
- txt.disabled = true;
- txt.value = 'loading...';
- lnk.innerHTML = 'loading...';
-
- ajax('/xml/'+type+'.xml?q='+encodeURIComponent(input), function(hr) {
- txt.disabled = false;
- txt.value = '';
- lnk.innerHTML = 'add';
-
- var items = hr.responseXML.getElementsByTagName('item');
- if(items.length < 1)
- return alert('Item not found!');
-
- vnpAdd(type, items[0].getAttribute('id'), items[0].firstChild.nodeValue);
- vnpSerialize(type);
- });
- return false;
-}
-
-function vnpSerialize(type) {
- var r = '';
- var l = x(type+'sel').getElementsByTagName('span');
- for(var i=0;i<l.length;i++)
- r += (r ? '|||' : '') + l[i].getElementsByTagName('i')[0].innerHTML.substr(1, l[i].getElementsByTagName('i')[0].innerHTML.indexOf(':')-1)
- + ',' + l[i].getElementsByTagName('a')[0].innerHTML;
- x(type).value = r;
-}
-
-
-
-// load
-
-if(x('jt_box_rel_vn'))
- vnpLoad('vn');
-if(x('jt_box_rel_prod'))
- vnpLoad('producers');
-
diff --git a/static/f/script.js b/static/f/script.js
index 69f54fc9..07ad9866 100644
--- a/static/f/script.js
+++ b/static/f/script.js
@@ -6,6 +6,8 @@
* jt -> Javascript Tabs
* med -> Release media selector
* rl -> Release List dropdown
+ * rpr -> Release <-> producer linking
+ * rvn -> Release <-> visual novel linking
* scr -> VN screenshot uploader
* tgl -> VN tag linking
* tvs -> VN page tag spoilers
@@ -758,6 +760,8 @@ function vnrSerialize() {
var r = [];
var trs = byName(byId('relation_tbl'), 'tr');
for(var i=0; i<trs.length; i++) {
+ if(trs[i].id == 'relation_tr_none')
+ continue;
var rel = byName(byClass(trs[i], 'td', 'tc_rel')[0], 'select')[0];
r[r.length] = [
rel.options[rel.selectedIndex].value, // relation
@@ -1307,6 +1311,210 @@ if(byId('taglinks'))
+/* R E L E A S E -> V I S U A L N O V E L L I N K I N G (/r+/edit) */
+
+function rvnLoad() {
+ var vns = byId('vn').value.split('|||');
+ for(var i=0; i<vns.length && vns[i].length>1; i++)
+ rvnAdd(vns[i].split(',',2)[0], vns[i].split(',',2)[1]);
+ rvnEmpty();
+
+ dsInit(byId('vn_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)));
+ }, function(item) {
+ return 'v'+item.getAttribute('id')+':'+item.firstChild.nodeValue;
+ },
+ rvnFormAdd
+ );
+ byId('vn_add').onclick = rvnFormAdd;
+}
+
+function rvnAdd(id, title) {
+ x('vn_tbl').appendChild(tag('tr', {id:'rvn_'+id, rvn_id:id},
+ tag('td', {'class':'tc_title'}, 'v'+id+':', tag('a', {href:'/v'+id}, shorten(title, 40))),
+ tag('td', {'class':'tc_rm'}, tag('a', {href:'#', onclick:rvnDel}, 'remove'))
+ ));
+ rvnStripe();
+ rvnEmpty();
+}
+
+function rvnDel() {
+ var tr = this;
+ while(tr.nodeName.toLowerCase() != 'tr')
+ tr = tr.parentNode;
+ tr.parentNode.removeChild(tr);
+ rvnEmpty();
+ rvnSerialize();
+ rvnStripe();
+ return false;
+}
+
+function rvnEmpty() {
+ var tbl = byId('vn_tbl');
+ if(byName(tbl, 'tr').length < 1)
+ tbl.appendChild(tag('tr', {id:'rvn_tr_none'}, tag('td', {colspan:2}, 'Nothing selected.')));
+ else if(byId('rvn_tr_none'))
+ tbl.removeChild(byId('rvn_tr_none'));
+}
+
+function rvnStripe() {
+ var l = byName(byId('vn_tbl'), 'tr');
+ for(var i=0; i<l.length; i++)
+ setClass(l[i], 'odd', i%2);
+}
+
+function rvnFormAdd() {
+ var txt = byId('vn_input');
+ var lnk = byId('vn_add');
+ var val = txt.value;
+
+ if(!val.match(/^v[0-9]+/)) {
+ alert('Visual novel textbox must start with an ID (e.g. v17)');
+ return false;
+ }
+
+ txt.disabled = true;
+ txt.value = 'loading...';
+ setText(lnk, 'loading...');
+
+ ajax('/xml/vn.xml?q='+encodeURIComponent(val), function(hr) {
+ txt.disabled = false;
+ txt.value = '';
+ setText(lnk, 'add');
+
+ var items = hr.responseXML.getElementsByTagName('item');
+ if(items.length < 1)
+ return alert('Visual novel not found!');
+
+ var id = items[0].getAttribute('id');
+ if(byId('rvn_'+id))
+ return alert('VN already selected!');
+
+ rvnAdd(id, items[0].firstChild.nodeValue);
+ rvnSerialize();
+ });
+ return false;
+}
+
+function rvnSerialize() {
+ var r = [];
+ var l = byName(byId('vn_tbl'), 'tr');
+ for(var i=0; i<l.length; i++)
+ if(l[i].rvn_id)
+ r[r.length] = l[i].rvn_id + ',' + getText(byName(byClass(l[i], 'td', 'tc_title')[0], 'a')[0]);
+ byId('vn').value = r.join('|||');
+}
+
+if(byId('jt_box_rel_vn'))
+ rvnLoad();
+
+
+
+
+/* R E L E A S E -> P R O D U C E R L I N K I N G (/r+/edit) */
+
+function rprLoad() {
+ var ps = byId('producers').value.split('|||');
+ for(var i=0; i<ps.length && ps[i].length>1; i++)
+ rprAdd(ps[i].split(',',2)[0], ps[i].split(',',2)[1]);
+ rprEmpty();
+
+ dsInit(byId('producer_input'), '/xml/producers.xml?q=',
+ function(item, tr) {
+ tr.appendChild(tag('td', {style:'text-align: right; padding-right: 5px'}, 'p'+item.getAttribute('id')));
+ tr.appendChild(tag('td', shorten(item.firstChild.nodeValue, 40)));
+ }, function(item) {
+ return 'p'+item.getAttribute('id')+':'+item.firstChild.nodeValue;
+ },
+ rprFormAdd
+ );
+ byId('producer_add').onclick = rprFormAdd;
+}
+
+function rprAdd(id, name) {
+ x('producer_tbl').appendChild(tag('tr', {id:'rpr_'+id, rpr_id:id},
+ tag('td', {'class':'tc_name'}, 'p'+id+':', tag('a', {href:'/p'+id}, shorten(name, 40))),
+ tag('td', {'class':'tc_rm'}, tag('a', {href:'#', onclick:rprDel}, 'remove'))
+ ));
+ rprStripe();
+ rprEmpty();
+}
+
+function rprDel() {
+ var tr = this;
+ while(tr.nodeName.toLowerCase() != 'tr')
+ tr = tr.parentNode;
+ tr.parentNode.removeChild(tr);
+ rprEmpty();
+ rprSerialize();
+ rprStripe();
+ return false;
+}
+
+function rprEmpty() {
+ var tbl = byId('producer_tbl');
+ if(byName(tbl, 'tr').length < 1)
+ tbl.appendChild(tag('tr', {id:'rpr_tr_none'}, tag('td', {colspan:2}, 'Nothing selected.')));
+ else if(byId('rpr_tr_none'))
+ tbl.removeChild(byId('rpr_tr_none'));
+}
+
+function rprStripe() {
+ var l = byName(byId('producer_tbl'), 'tr');
+ for(var i=0; i<l.length; i++)
+ setClass(l[i], 'odd', i%2);
+}
+
+function rprFormAdd() {
+ var txt = byId('producer_input');
+ var lnk = byId('producer_add');
+ var val = txt.value;
+
+ if(!val.match(/^p[0-9]+/)) {
+ alert('Producer textbox must start with an ID (e.g. p17)');
+ return false;
+ }
+
+ txt.disabled = true;
+ txt.value = 'loading...';
+ setText(lnk, 'loading...');
+
+ ajax('/xml/producers.xml?q='+encodeURIComponent(val), function(hr) {
+ txt.disabled = false;
+ txt.value = '';
+ setText(lnk, 'add');
+
+ var items = hr.responseXML.getElementsByTagName('item');
+ if(items.length < 1)
+ return alert('Producer not found!');
+
+ var id = items[0].getAttribute('id');
+ if(byId('rpr_'+id))
+ return alert('Producer already selected!');
+
+ rprAdd(id, items[0].firstChild.nodeValue);
+ rprSerialize();
+ });
+ return false;
+}
+
+function rprSerialize() {
+ var r = [];
+ var l = byName(byId('producer_tbl'), 'tr');
+ for(var i=0; i<l.length; i++)
+ if(l[i].rpr_id)
+ r[r.length] = l[i].rpr_id + ',' + getText(byName(byClass(l[i], 'td', 'tc_name')[0], 'a')[0]);
+ byId('producers').value = r.join('|||');
+}
+
+if(byId('jt_box_rel_prod'))
+ rprLoad();
+
+
+
+
/* M I S C S T U F F */
// search box