summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2009-10-05 20:50:04 +0200
committerYorhel <git@yorhel.nl>2009-10-05 20:55:11 +0200
commit519b13787e33f1b8edb3d0f3b018339410b48371 (patch)
tree3d865f8aeffed1833c63bf56064df5e4d0aff90b
parentfd24d5f1f95eb4285ddb938101275f66d1fdb544 (diff)
JS: Moved, split and rewrote release <-> VN & producer linking
+ removed last traces of forms.js + converted code to use tables, as that is easier to expand more accurate for this purpose. The reason I probably didn't use tables before was that the innerHTML property doesn't work on tr elements. The split was mainly because the producer linking is going to be expanded with an additional field later on.
-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