From 026ade950bb9cd901d2b52be2686e7642d27d02f Mon Sep 17 00:00:00 2001 From: Yorhel Date: Sun, 17 Jan 2016 16:00:39 +0100 Subject: L10N: Intern all Javascript strings and rename main JS file This has been mostly automated. --- Makefile | 10 +-- data/js/chartraits.js | 22 +++--- data/js/charvns.js | 19 +++-- data/js/dateselector.js | 6 +- data/js/dropdownsearch.js | 8 +-- data/js/filter.js | 170 ++++++++++++++++++++++---------------------- data/js/iv.js | 8 +-- data/js/lib.js | 14 +--- data/js/main.js | 23 +----- data/js/misc.js | 16 +++-- data/js/prodrel.js | 16 ++--- data/js/relmedia.js | 6 +- data/js/relprod.js | 16 ++--- data/js/relvns.js | 16 ++--- data/js/staffalias.js | 6 +- data/js/vncast.js | 12 ++-- data/js/vnrel.js | 22 +++--- data/js/vnreldropdown.js | 6 +- data/js/vnscr.js | 43 +++++------ data/js/vnstaff.js | 10 +-- data/js/vntagmod.js | 18 ++--- lib/VNDB/Util/LayoutHTML.pm | 2 +- util/jsgen.pl | 104 ++------------------------- 23 files changed, 227 insertions(+), 346 deletions(-) diff --git a/Makefile b/Makefile index d914d504..620f5a33 100644 --- a/Makefile +++ b/Makefile @@ -50,9 +50,9 @@ all: dirs js skins robots data/config.pl util/sql/editfunc.sql -dirs: static/f/js static/ch static/cv static/sf static/st data/log www www/feeds www/api +dirs: static/ch static/cv static/sf static/st data/log www www/feeds www/api -js: static/f/js/en.js +js: static/f/vndb.js icons: data/icons/icons.css @@ -67,10 +67,10 @@ static/ch static/cv static/sf static/st: mkdir $@; for i in $$(seq -w 0 1 99); do mkdir "$@/$$i"; done -static/f/js data/log www www/feeds www/api: +data/log www www/feeds www/api: mkdir $@ -static/f/js/en.js: data/js/*.js data/lang.txt util/jsgen.pl data/config.pl data/global.pl +static/f/vndb.js: data/js/*.js util/jsgen.pl data/config.pl data/global.pl util/jsgen.pl data/icons/icons.css: data/icons/*.png data/icons/*/*.png util/spritegen.pl @@ -87,7 +87,7 @@ chmod: all chmod -R a-x+rwX static/{ch,cv,sf,st} chmod-autoupdate: chmod - chmod a+xrw static/f static/f/js data/icons + chmod a+xrw static/f data/icons chmod -f a-x+rw static/s/*/{style.css,boxbg.png} static/f/icons.png chmod-tladmin: chmod diff --git a/data/js/chartraits.js b/data/js/chartraits.js index dacb31f7..51196f93 100644 --- a/data/js/chartraits.js +++ b/data/js/chartraits.js @@ -1,5 +1,3 @@ -// l10n /_spoil_-?\d+/ - function ctrLoad() { // load current traits var l = byId('traits').value.split(' '); @@ -28,7 +26,7 @@ function ctrLoad() { tr.appendChild(tag('td', { style: 'text-align: right; padding-right: 5px'}, 'i'+item.getAttribute('id'))); 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') : ''))); + tag('b', {'class':'grayedout'}, item.getAttribute('meta')=='yes' ? 'meta' : ''))); }, ctrFormAdd); } @@ -42,21 +40,21 @@ function ctrEmpty() { if(e && l.length > 1) t.removeChild(e); else if(!e && l.length < 1) - t.appendChild(tag('tr', {id:'traits_empty',colspan:3}, tag('td', mt('_chare_traits_empty')))); + t.appendChild(tag('tr', {id:'traits_empty',colspan:3}, tag('td', 'No traits present yet.'))); } function ctrAdd(item, spoil) { var id = item.getAttribute('id'); var name = item.firstChild.nodeValue; var group = item.getAttribute('groupname'); - var sp = tag('td', {'class':'tc_spoil', onclick:ctrSpoilNext, ctr_spoil:spoil}, mt('_spoil_'+spoil)); + var sp = tag('td', {'class':'tc_spoil', onclick:ctrSpoilNext, ctr_spoil:spoil}, fmtspoil(spoil)); ddInit(sp, 'left', ctrSpoilDD); byId('traits_tbl').appendChild(tag('tr', {ctr_id:id, ctr_spoiler:spoil}, tag('td', {'class':'tc_name'}, tag('b', {'class':'grayedout'}, group?group+' / ':''), tag('a', {'href':'/i'+id}, name)), sp, - tag('td', {'class':'tc_del'}, tag('a', {href:'#', onclick:ctrDel}, mt('_js_remove'))) + tag('td', {'class':'tc_del'}, tag('a', {href:'#', onclick:ctrDel}, 'remove')) )); ctrEmpty(); ctrSerialize(); @@ -68,9 +66,9 @@ function ctrFormAdd(item) { if(l[i].ctr_id && l[i].ctr_id == item.getAttribute('id')) break; if(i < l.length) - alert(mt('_chare_traits_present')); + alert('Selected trait is already present.'); else if(item.getAttribute('meta') == 'yes') - alert(mt('_chare_traits_nometa')); + alert('Meta traits can\'t be used here.'); else ctrAdd(item, 0); return ''; @@ -79,7 +77,7 @@ function ctrFormAdd(item) { function ctrSpoilNext() { if(++this.ctr_spoil > 2) this.ctr_spoil = 0; - setText(this, mt('_spoil_'+this.ctr_spoil)); + setText(this, fmtspoil(this.ctr_spoil)); ddRefresh(); ctrSerialize(); } @@ -88,15 +86,15 @@ function ctrSpoilDD(lnk) { var lst = tag('ul', null); for(var i=0; i<=2; i++) lst.appendChild(tag('li', i == lnk.ctr_spoil - ? tag('i', mt('_spoil_'+i)) - : tag('a', {href: '#', onclick:ctrSpoilSet, ctr_td:lnk, ctr_sp:i}, mt('_spoil_'+i)) + ? tag('i', fmtspoil(i)) + : tag('a', {href: '#', onclick:ctrSpoilSet, ctr_td:lnk, ctr_sp:i}, fmtspoil(i)) )); return lst; } function ctrSpoilSet() { this.ctr_td.ctr_spoil = this.ctr_sp; - setText(this.ctr_td, mt('_spoil_'+this.ctr_sp)); + setText(this.ctr_td, fmtspoil(this.ctr_sp)); ddHide(); ctrSerialize(); return false; diff --git a/data/js/charvns.js b/data/js/charvns.js index 10fd1f77..dcac2950 100644 --- a/data/js/charvns.js +++ b/data/js/charvns.js @@ -50,7 +50,7 @@ function cvnEmpty() { 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', mt('_chare_vns_empty')))); + t.appendChild(tag('tr', {id:'vns_empty',colspan:3}, tag('td', 'No visual novels selected.'))); } function cvnVNAdd(vn, rel) { @@ -59,7 +59,7 @@ function cvnVNAdd(vn, rel) { 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}, mt('_chare_vns_addrel')), ')') + tag('i', '(', tag('a', {href:'#', onclick:cvnRelNew}, 'add release'), ')') ) )); if(rel) @@ -69,7 +69,7 @@ function cvnVNAdd(vn, rel) { function cvnRelAdd(vid, rid, role, spoil) { var rels = byId('cvn_v'+vid).cvn_rels; - var rsel = tag('select', {onchange:cvnRelChange}, tag('option', {value:0}, mt('_chare_vns_other'))); + var rsel = tag('select', {onchange:cvnRelChange}, tag('option', {value:0}, 'All / others')); for(var i=0; i=1980; i--) year.appendChild(tag('option', {value: i}, i)); var month = tag('select', selops, - tag('option', {value:99}, mt('_js_date_month')) + tag('option', {value:99}, '-month-') ); for(i=1; i<=12; i++) month.appendChild(tag('option', {value: i}, i)); var day = tag('select', selops, - tag('option', {value:99}, mt('_js_date_day')) + tag('option', {value:99}, '-day-') ); for(i=1; i<=31; i++) day.appendChild(tag('option', {value: i}, i)); diff --git a/data/js/dropdownsearch.js b/data/js/dropdownsearch.js index e7c42dc0..428858cd 100644 --- a/data/js/dropdownsearch.js +++ b/data/js/dropdownsearch.js @@ -32,7 +32,7 @@ var boxobj; function box() { if(!boxobj) { - boxobj = tag('div', {id: 'ds_box', 'class':'hidden'}, tag('b', mt('_js_loading'))); + boxobj = tag('div', {id: 'ds_box', 'class':'hidden'}, tag('b', 'Loading...')); addBody(boxobj); } return boxobj; @@ -72,7 +72,7 @@ function setvalue(obj) { obj.ds_returnFunc(obj); setClass(box(), 'hidden', true); - setContent(box(), tag('b', mt('_js_loading'))); + setContent(box(), tag('b', 'Loading...')); setselected(obj, 0); if(obj.ds_dosearch) { clearTimeout(obj.ds_dosearch); @@ -153,7 +153,7 @@ function search(obj) { // hide the ds_box div if the search string is too short if(val.length < 2) { setClass(b, 'hidden', true); - setContent(b, tag('b', mt('_js_loading'))); + setContent(b, tag('b', 'Loading...')); setselected(obj, 0); return; } @@ -181,7 +181,7 @@ function results(hr, obj) { var lst = hr.responseXML.getElementsByTagName('item'); var b = box(); if(lst.length < 1) { - setContent(b, tag('b', mt('_js_ds_noresults'))); + setContent(b, tag('b', 'No results...')); setselected(obj, 0); return; } diff --git a/data/js/filter.js b/data/js/filter.js index c77820ab..9f7de239 100644 --- a/data/js/filter.js +++ b/data/js/filter.js @@ -94,20 +94,20 @@ function filLoad(lnk, serobj) { fil_lnk: lnk, fil_type: type }, - tag('a', {href:'#', onclick:show, 'class':'close'}, mt('_js_close')), + tag('a', {href:'#', onclick:show, 'class':'close'}, 'close'), tag('h3', l[0]), p, tag('b', {'class':'ruler'}, null), c, tag('b', {'class':'ruler'}, null), - tag('input', {type:'button', 'class':'submit', value: mt('_js_fil_apply'), onclick:function () { + tag('input', {type:'button', 'class':'submit', value: 'Apply', onclick:function () { var f = serobj; while(f.nodeName.toLowerCase() != 'form') f = f.parentNode; f.submit(); }}), - tag('input', {type:'button', 'class':'submit', value: mt('_js_fil_reset'), onclick:function () { serobj.value = ''; deSerialize(obj) } }), - byId('pref_code') && lnk.id != 'rfilselect' ? tag('input', {type:'button', 'class':'submit', value: mt('_js_fil_save'), onclick:saveDefault }) : null, + tag('input', {type:'button', 'class':'submit', value: 'Reset', onclick:function () { serobj.value = ''; deSerialize(obj) } }), + byId('pref_code') && lnk.id != 'rfilselect' ? tag('input', {type:'button', 'class':'submit', value: 'Save as default', onclick:saveDefault }) : null, savenote ); lnk.fil_obj = obj; @@ -124,12 +124,14 @@ function saveDefault() { var but = this; var obj = getObj(this); var note = obj.fil_savenote; - setText(note, mt('_js_loading')); + setText(note, 'Loading...'); but.enabled = false; setClass(note, 'hidden', false); var type = obj.fil_type == 'r' ? 'release' : 'vn'; ajax('/xml/prefs.xml?formcode='+byId('pref_code').title+';key=filter_'+type+';value='+obj.fil_serobj.value, function (hr) { - setText(note, mt('_js_fil_savenote')); + setText(note, 'Your saved filters will be applied automatically to several other parts of the site as well, such as the homepage.'+ + ' To change these filters, come back to this page and use the "Save as default" button again.'+ + ' To remove your saved filters, hit "Reset" and then save.'); but.enable = true; }); } @@ -368,7 +370,7 @@ function filFSelect(c, n, lines, opts) { s.appendChild(g); } } - return [ c, lines > 1 ? [ n, mt('_js_fil_boolor') ] : n, s, + return [ c, lines > 1 ? [ n, 'Boolean or, selecting more gives more results' ] : n, s, function (c) { var l = []; for(var i=0; i characters).') ], + ] : [ 'Traits', + [ '', ' ', tag('Boolean and, selecting more gives less results') ], + filFTagInput('trait_inc', 'Traits to include', 'trait'), + filFTagInput('trait_exc', 'Traits to exclude', 'trait'), + filFOptions('tagspoil', ' ', [[0, 'Hide spoilers'],[1, 'Show minor spoilers'],[2, 'Spoil me!']]), ], - [ mt('_charb_roles'), filFSelect('role', mt('_charb_roles'), 4, VARS.char_roles) ] + [ 'Roles', filFSelect('role', 'Roles', 4, VARS.char_roles) ] ]; } function filReleases() { var plat = VARS.platforms; - plat.splice(0, 0, [ 'unk', mt('_unknown') ]); + plat.splice(0, 0, [ 'unk', 'Unknown' ]); var med = VARS.media; - med.splice(0, 0, [ 'unk', mt('_unknown') ]); + med.splice(0, 0, [ 'unk', 'Unknown' ]); return [ - mt('_rbrowse_fil_title'), - [ mt('_rbrowse_general'), - filFOptions('type', mt('_rbrowse_type'), VARS.release_types), - filFOptions('patch', mt('_rbrowse_patch'), [ [1, mt('_rbrowse_patch_yes')], [0, mt('_rbrowse_patch_no')] ]), - filFOptions('freeware', mt('_rbrowse_freeware'),[ [1, mt('_rbrowse_freeware_yes')], [0, mt('_rbrowse_freeware_no')] ]), - filFOptions('doujin', mt('_rbrowse_doujin'), [ [1, mt('_rbrowse_doujin_yes')], [0, mt('_rbrowse_doujin_no')] ]), - [ 'date_after', mt('_rbrowse_dateafter'), dateLoad(null, selectField), function (c) { return [c.date_val] }, function(o,v) { o.dateSet(v) } ], - [ 'date_before', mt('_rbrowse_datebefore'), dateLoad(null, selectField), function (c) { return [c.date_val] }, function(o,v) { o.dateSet(v) } ], - filFOptions('released', mt('_rbrowse_released'),[ [1, mt('_rbrowse_released_yes')], [0, mt('_rbrowse_released_no')] ]) + 'Release filters', + [ 'General', + filFOptions('type', 'Release type', VARS.release_types), + filFOptions('patch', 'Patch status', [ [1, 'Patch'], [0, 'Standalone'] ]), + filFOptions('freeware', 'Freeware', [ [1, 'Only freeware'], [0, 'Only non-free releases'] ]), + filFOptions('doujin', 'Doujin', [ [1, 'Only doujin releases'], [0, 'Only commercial releases'] ]), + [ 'date_after', 'Released after', dateLoad(null, selectField), function (c) { return [c.date_val] }, function(o,v) { o.dateSet(v) } ], + [ 'date_before', 'Released before', dateLoad(null, selectField), function (c) { return [c.date_val] }, function(o,v) { o.dateSet(v) } ], + filFOptions('released', 'Release date', [ [1, 'Past (already released)'], [0, 'Future (to be released)'] ]) ], - [ mt('_rbrowse_minage'), filFSelect('minage', mt('_rbrowse_minage'), 15, VARS.age_ratings) ], - [ mt('_rbrowse_language'), filFSelect('lang', mt('_rbrowse_language'), 20, VARS.languages) ], + [ 'Age rating', filFSelect('minage', 'Age rating', 15, VARS.age_ratings) ], + [ 'Language', filFSelect('lang', 'Language', 20, VARS.languages) ], byId('rfilselect') ? null : - [ mt('_rbrowse_olang'), filFSelect('olang', mt('_rbrowse_olang'), 20, VARS.languages) ], - [ mt('_rbrowse_resolution'), filFSelect('resolution', mt('_rbrowse_resolution'), 15, VARS.resolutions) ], - [ mt('_rbrowse_platform'), filFSelect('plat', mt('_rbrowse_platform'), 20, plat) ], - [ mt('_rbrowse_misc'), - filFSelect('med', mt('_rbrowse_medium'), 10, med), - filFSelect('voiced', mt('_rbrowse_voiced'), 5, VARS.voiced), - filFSelect('ani_story', mt('_rbrowse_ani_story'), 5, VARS.animated), - filFSelect('ani_ero', mt('_rbrowse_ani_ero'), 5, VARS.animated) + [ 'Original language', filFSelect('olang', 'Original language', 20, VARS.languages) ], + [ 'Screen resolution', filFSelect('resolution', 'Screen resolution', 15, VARS.resolutions) ], + [ 'Platform', filFSelect('plat', 'Platform', 20, plat) ], + [ 'Misc', + filFSelect('med', 'Medium', 10, med), + filFSelect('voiced', 'Voiced', 5, VARS.voiced), + filFSelect('ani_story', 'Story animation', 5, VARS.animated), + filFSelect('ani_ero', 'Ero animation', 5, VARS.animated) ] ]; } @@ -568,30 +570,30 @@ function filVN() { var ontagpage = location.pathname.indexOf('/v/') < 0; return [ - mt('_vnbrowse_fil_title'), - [ mt('_vnbrowse_general'), - filFSelect( 'length', mt('_vnbrowse_length'), 6, VARS.vn_lengths), - filFOptions('hasani', mt('_vnbrowse_anime'), [[1, mt('_vnbrowse_anime_yes')], [0, mt('_vnbrowse_anime_no')]]), - filFOptions('hasshot',mt('_vnbrowse_screenshots'), [[1, mt('_vnbrowse_screenshots_yes')],[0, mt('_vnbrowse_screenshots_no')]]) + 'Visual Novel Filters', + [ 'General', + filFSelect( 'length', 'Length', 6, VARS.vn_lengths), + filFOptions('hasani', 'Anime', [[1, 'Has anime'], [0, 'Does not have anime']]), + filFOptions('hasshot','Screenshots', [[1, 'Has screenshot'],[0, 'Does not have a screenshot']]) ], - ontagpage ? [ mt('_vnbrowse_tags'), - [ '', ' ', tag(mt('_vnbrowse_tagnothere')) ], - ] : [ mt('_vnbrowse_tags'), - [ '', ' ', tag(mt('_js_fil_booland')) ], - [ '', ' ', byId('pref_code') ? tag(mt('_vnbrowse_tagactive')) : null ], - filFTagInput('tag_inc', mt('_vnbrowse_taginc'), 'tag'), - filFTagInput('tag_exc', mt('_vnbrowse_tagexc'), 'tag'), - filFOptions('tagspoil', ' ', [[0, mt('_spoilset_0')],[1, mt('_spoilset_1')],[2, mt('_spoilset_2')]]) + ontagpage ? [ 'Tags', + [ '', ' ', tag('Additional tag filters are not available on this page. Use the visual novel browser instead (available from the main menu -> visual novels).') ], + ] : [ 'Tags', + [ '', ' ', tag('Boolean and, selecting more gives less results') ], + [ '', ' ', byId('pref_code') ? tag('These filters are ignored on tag pages (when set as default).') : null ], + filFTagInput('tag_inc', 'Tags to include', 'tag'), + filFTagInput('tag_exc', 'Tags to exclude', 'tag'), + filFOptions('tagspoil', ' ', [[0, 'Hide spoilers'],[1, 'Show minor spoilers'],[2, 'Spoil me!']]) ], - [ mt('_vnbrowse_language'), filFSelect('lang', mt('_vnbrowse_language'), 20, VARS.languages) ], - [ mt('_vnbrowse_olang'), filFSelect('olang',mt('_vnbrowse_olang'), 20, VARS.languages) ], - [ mt('_vnbrowse_platform'), filFSelect('plat', mt('_vnbrowse_platform'), 20, VARS.platforms) ], + [ 'Language', filFSelect('lang', 'Language', 20, VARS.languages) ], + [ 'Original language', filFSelect('olang','Original language', 20, VARS.languages) ], + [ 'Platform', filFSelect('plat', 'Platform', 20, VARS.platforms) ], !byId('pref_code') ? null : [ - mt('_vnbrowse_ul'), - filFOptions('ul_notblack', mt('_vnbrowse_ul_notblack'), [[1, mt('_vnbrowse_ul_notblackmsg')]]), - filFOptions('ul_onwish', mt('_vnbrowse_ul_onwish'), [[0, mt('_vnbrowse_ul_onwishno')],[1, mt('_vnbrowse_ul_onwishyes')]]), - filFOptions('ul_voted', mt('_vnbrowse_ul_voted'), [[0, mt('_vnbrowse_ul_votedno')], [1, mt('_vnbrowse_ul_votedyes') ]]), - filFOptions('ul_onlist', mt('_vnbrowse_ul_onlist'), [[0, mt('_vnbrowse_ul_onlistno')],[1, mt('_vnbrowse_ul_onlistyes')]]) + 'My lists', + filFOptions('ul_notblack', 'Blacklist', [[1, 'Exclude VNs on my blacklist']]), + filFOptions('ul_onwish', 'Wishlist', [[0, 'Not on my wishlist'],[1, 'On my wishlist']]), + filFOptions('ul_voted', 'Voted', [[0, 'Not voted on'], [1, 'Voted on' ]]), + filFOptions('ul_onlist', 'VN list', [[0, 'Not on my VN list'],[1, 'On my VN list']]) ], ]; } @@ -604,14 +606,14 @@ function filStaff() { roles.splice(-1, 0, ['seiyuu', 'Voice actor']); return [ - mt('_sbrowse_fil_title'), - [ mt('_sbrowse_general'), - filFOptions('truename', mt('_sbrowse_names'), [[1, mt('_sbrowse_names_primary')],[0, mt('_sbrowse_names_all')]]), - filFSelect('role', mt('_sbrowse_roles'), roles.length, roles), + 'Staff filters', + [ 'General', + filFOptions('truename', 'Names', [[1, 'Primary names only'],[0, 'Include aliases']]), + filFSelect('role', 'Roles', roles.length, roles), '', - filFSelect('gender', mt('_sbrowse_gender'), gend.length, gend), + filFSelect('gender', 'Gender', gend.length, gend), ], - [ mt('_sbrowse_language'), filFSelect('lang', mt('_sbrowse_language'), 20, VARS.languages) ], + [ 'Language', filFSelect('lang', 'Language', 20, VARS.languages) ], ]; } diff --git a/data/js/iv.js b/data/js/iv.js index f1593d22..1591cc0a 100644 --- a/data/js/iv.js +++ b/data/js/iv.js @@ -39,11 +39,11 @@ function init() { tag('b', {id:'ivimg'}, ''), tag('br', null), tag('a', {href:'#', id:'ivfull'}, ''), - tag('a', {href:'#', onclick: close, id:'ivclose'}, mt('_js_close')), - tag('a', {href:'#', onclick: show, id:'ivprev'}, '« '+mt('_js_iv_prev')), - tag('a', {href:'#', onclick: show, id:'ivnext'}, mt('_js_iv_next')+' »') + tag('a', {href:'#', onclick: close, id:'ivclose'}, 'close'), + tag('a', {href:'#', onclick: show, id:'ivprev'}, '« previous'), + tag('a', {href:'#', onclick: show, id:'ivnext'}, 'next »') )); - addBody(tag('b', {id:'ivimgload','class':'hidden'}, mt('_js_loading'))); + addBody(tag('b', {id:'ivimgload','class':'hidden'}, 'Loading...')); } } diff --git a/data/js/lib.js b/data/js/lib.js index 7d0f6b18..a4921d3e 100644 --- a/data/js/lib.js +++ b/data/js/lib.js @@ -169,17 +169,9 @@ window.shorten = function(v, l) { }; -/* maketext function. Less powerful than the Perl equivalent, as it only - * supports [_n], ~[ and ~]. jsgen.pl is responsible for weeding out the other - * codes. */ -window.mt = function() { - var key = arguments[0]; - var val = VARS.l10n_str[key] || key; - // BUG: ~[_1] will get replaced. We don't have a string like that, so whatever. - for(var i=1; i', - * or - * mt('') - * The single quotes and (lack of) spaces are significant! - * - * To use non-exact translation keys as argument to mt(), make sure to - * indicate which keys should be inserted in the header by adding a comment - * containing the following format: - * l10n // - * any keys matching that regex will be included. - * - * In the case of an mt('') without any extra arguments, the entire - * function call may be replaced by the TL string. - */ + * generate the final JS file(s) used by the site. */ // Variables from jsgen.pl VARS = /*VARS*/; diff --git a/data/js/misc.js b/data/js/misc.js index a758b191..11c7ef8e 100644 --- a/data/js/misc.js +++ b/data/js/misc.js @@ -12,18 +12,22 @@ if(byId('votesel')) byId('votesel').onchange = function() { var s = this.options[this.selectedIndex].value; if(s == -2) - s = prompt(mt('_vnpage_uopt_othervote'), ''); + s = prompt('Please input your vote as a number between 1 and 10. One digit after the decimal is allowed, for example: 8.6 or 7.3.', ''); if(!s || s == -3) return; if(s != -1 && (!s.match(/^([1-9]|10)([\.,][0-9])?$/) || s > 10 || s < 1)) { - alert(mt('_vnpage_uopt_invvote')); + alert('Invalid number.'); this.selectedIndex = 0; return; } s = s.replace(',', '.'); - if(s == 1 && !confirm(mt('_vnpage_uopt_1vote'))) + if(s == 1 && !confirm('You are about to give this visual novel a 1 out of 10.'+ + ' This is a rather extreme rating, meaning this game has absolutely nothing to offer, and that it\'s the worst game you have ever played.'+ + ' Are you really sure this visual novel matches that description?')) return; - if(s == 10 && !confirm(mt('_vnpage_uopt_10vote'))) + if(s == 10 && !confirm('You are about to give this visual novel a 10 out of 10.'+ + ' This is a rather extreme rating, meaning this is one of the best visual novels you\'ve ever played and it\'s unlikely that any other game could ever be better than this one.'+ + ' It is generally a bad idea to have more than three games in your vote list with this rating, choose carefully!')) return; if(s > 0 || s == -1) ulist_redirect('v', '/vote', this.name, 'v='+s); @@ -241,7 +245,7 @@ if(byId('batchedit')) if(byId('not') && byId('vns')) byId('vns').onchange = function () { if(this.options[this.selectedIndex].value == 999) - byId('not').value = prompt(mt('_rlist_setnote_prompt'), ''); + byId('not').value = prompt('Set notes (leave empty to remove note)', ''); return true; }; @@ -253,7 +257,7 @@ if(byId('not') && byId('vns')) return; function setexpand() { var exp = !(getCookie('prodrelexpand') == 1); - setText(lnk, exp ? mt('_js_collapse') : mt('_js_expand')); + setText(lnk, exp ? 'collapse' : 'expand'); setClass(byId('prodrel'), 'collapse', !exp); }; lnk.onclick = function () { diff --git a/data/js/prodrel.js b/data/js/prodrel.js index 2ddc100e..ec6082e3 100644 --- a/data/js/prodrel.js +++ b/data/js/prodrel.js @@ -28,7 +28,7 @@ function prrAdd(rel, pid, title) { byId('relation_tbl').appendChild(tag('tr', {id:'relation_tr_'+pid}, tag('td', {'class':'tc_prod' }, 'p'+pid+':', tag('a', {href:'/p'+pid}, shorten(title, 40))), tag('td', {'class':'tc_rel' }, sel), - tag('td', {'class':'tc_add' }, tag('a', {href:'#', onclick:prrDel}, mt('_js_remove'))) + tag('td', {'class':'tc_add' }, tag('a', {href:'#', onclick:prrDel}, 'remove')) )); prrEmpty(); @@ -37,7 +37,7 @@ function prrAdd(rel, pid, title) { function prrEmpty() { var tbl = byId('relation_tbl'); if(byName(tbl, 'tr').length < 1) - tbl.appendChild(tag('tr', {id:'relation_tr_none'}, tag('td', {colspan:4}, mt('_pedit_rel_none')))); + tbl.appendChild(tag('tr', {id:'relation_tr_none'}, tag('td', {colspan:4}, 'Nothing selected.'))); else if(byId('relation_tr_none')) tbl.removeChild(byId('relation_tr_none')); } @@ -76,26 +76,26 @@ function prrFormAdd() { var input = txt.value; if(!input.match(/^p[0-9]+/)) { - alert(mt('_pedit_rel_findformat')); + alert('Producer textbox should start with an ID (e.g. "p7:")'); return false; } txt.disabled = sel.disabled = true; - txt.value = mt('_js_loading'); - setText(lnk, mt('_js_loading')); + txt.value = 'Loading...'; + setText(lnk, 'Loading...'); ajax('/xml/producers.xml?q='+encodeURIComponent(input), function(hr) { txt.disabled = sel.disabled = false; txt.value = ''; - setText(lnk, mt('_js_add')); + setText(lnk, 'add'); var items = hr.responseXML.getElementsByTagName('item'); if(items.length < 1) - return alert(mt('_pedit_rel_notfound')); + return alert('Producer not found'); var id = items[0].getAttribute('id'); if(byId('relation_tr_'+id)) - return alert(mt('_pedit_rel_double')); + return alert('Producer already selected!'); prrAdd(sel.options[sel.selectedIndex].value, id, items[0].firstChild.nodeValue); sel.selectedIndex = 0; diff --git a/data/js/relmedia.js b/data/js/relmedia.js index 3b1a4f4a..4068d499 100644 --- a/data/js/relmedia.js +++ b/data/js/relmedia.js @@ -8,18 +8,18 @@ function medLoad() { } function medAdd(med, qty) { - var qsel = tag('select', {'class':'qty', onchange:medSerialize}, tag('option', {value:0}, mt('_redit_form_med_quantity'))); + var qsel = tag('select', {'class':'qty', onchange:medSerialize}, tag('option', {value:0}, '-quantity-')); for(var i=1; i<=20; i++) qsel.appendChild(tag('option', {value:i, selected: qty==i}, i)); var msel = tag('select', {'class':'medium', onchange: med == '' ? medFormAdd : medSerialize}); if(med == '') - msel.appendChild(tag('option', {value:''}, mt('_redit_form_med_medium'))); + msel.appendChild(tag('option', {value:''}, '-medium-')); for(var i=0; i 10) { - alert(mt('_vnedit_scr_errtoomany')); + alert('Too many files selected. The total number of screenshots may not exceed 10.'); return false; } diff --git a/data/js/vnstaff.js b/data/js/vnstaff.js index 2a9990d1..e4a3b284 100644 --- a/data/js/vnstaff.js +++ b/data/js/vnstaff.js @@ -36,7 +36,7 @@ function vnsAdd(staff, role, note) { tag('a', {href:'/s'+staff.id}, staff.name)), tag('td', {'class':'tc_role'}, rlist), tag('td', {'class':'tc_note'}, tag('input', {type:'text', 'class':'text', value:note})), - tag('td', {'class':'tc_del'}, tag('a', {href:'#', onclick:vnsDel}, mt('_js_remove'))) + tag('td', {'class':'tc_del'}, tag('a', {href:'#', onclick:vnsDel}, 'remove')) )); vnsEmpty(); vnsSerialize(); @@ -51,7 +51,7 @@ function vnsEmpty() { tbody.removeChild(x); if(byName(tbody, 'tr').length < 1) { tbody.appendChild(tag('tr', {id:'credits_tr_none'}, - tag('td', {colspan:4}, mt('_vnstaffe_none')))); + tag('td', {colspan:4}, 'None'))); if (thead.length) tbl.removeChild(thead[0]); } else { @@ -59,9 +59,9 @@ function vnsEmpty() { tbody.removeChild(byId('credits_tr_none')); if (thead.length < 1) { thead = tag('thead', tag('tr', - tag('td', {'class':'tc_name'}, mt('_vnstaffe_form_staff')), - tag('td', {'class':'tc_role'}, mt('_vnstaffe_form_role')), - tag('td', {'class':'tc_note'}, mt('_vnstaffe_form_note')), + tag('td', {'class':'tc_name'}, 'Staff'), + tag('td', {'class':'tc_role'}, 'Credit'), + tag('td', {'class':'tc_note'}, 'Note'), tag('td', ''))); tbl.insertBefore(thead, tbody); } diff --git a/data/js/vntagmod.js b/data/js/vntagmod.js index 108fba39..8bc5da22 100644 --- a/data/js/vntagmod.js +++ b/data/js/vntagmod.js @@ -2,14 +2,14 @@ var tglSpoilers = []; function tglLoad() { for(var i=0; i<=3; i++) - tglSpoilers[i] = mt('_spoil_'+(i-1)); // l10n /_spoil_-?\d+/ + tglSpoilers[i] = fmtspoil(i-1); // tag dropdown search dsInit(byId('tagmod_tag'), '/xml/tags.xml?q=', function(item, tr) { tr.appendChild(tag('td', shorten(item.firstChild.nodeValue, 40), - item.getAttribute('meta') == 'yes' ? tag('b', {'class':'grayedout'}, ' '+mt('_js_ds_tag_meta')) : - item.getAttribute('state') == 0 ? tag('b', {'class':'grayedout'}, ' '+mt('_js_ds_tag_mod')) : null + item.getAttribute('meta') == 'yes' ? tag('b', {'class':'grayedout'}, ' meta') : + item.getAttribute('state') == 0 ? tag('b', {'class':'grayedout'}, ' awaiting moderation') : null )); }, function(item) { return item.firstChild.nodeValue; @@ -99,27 +99,27 @@ function tglAdd() { var tg = byId('tagmod_tag'); var add = byId('tagmod_add'); tg.disabled = add.disabled = true; - add.value = mt('_js_loading'); + add.value = 'Loading...'; ajax('/xml/tags.xml?q=name:'+encodeURIComponent(tg.value), function(hr) { tg.disabled = add.disabled = false; tg.value = ''; - add.value = mt('_tagv_add'); + add.value = 'Add tag'; var items = hr.responseXML.getElementsByTagName('item'); if(items.length < 1) - return alert(mt('_tagv_notfound')); + return alert('Item not found!'); if(items[0].getAttribute('meta') == 'yes') - return alert(mt('_js_ds_tag_nometa')); + return alert('Can\'t use meta tags here!'); var name = items[0].firstChild.nodeValue; var id = items[0].getAttribute('id'); if(byId('tgl_'+id)) - return alert(mt('_tagv_double')); + return alert('Tag is already present!'); if(!byId('tagmod_newtags')) byId('tagtable').appendChild(tag('tr', {'class':'tagmod_cat', id:'tagmod_newtags'}, - tag('td', {colspan:7}, mt('_tagv_newlyadded')))); + tag('td', {colspan:7}, 'Newly added'))); var vote = tag('td', {'class':'tc_myvote', tgl_vote: 2}, ''); tglVoteBar(vote); diff --git a/lib/VNDB/Util/LayoutHTML.pm b/lib/VNDB/Util/LayoutHTML.pm index 42b582e8..36fa9937 100644 --- a/lib/VNDB/Util/LayoutHTML.pm +++ b/lib/VNDB/Util/LayoutHTML.pm @@ -157,7 +157,7 @@ sub htmlFooter { # %options => { pref_code => 1 } # Abuse an empty noscript tag for the formcode to update a preference setting, if the page requires one. noscript id => 'pref_code', title => $self->authGetCode('/xml/prefs.xml'), '' if $o{pref_code} && $self->authInfo->{id}; - script type => 'text/javascript', src => $self->{url_static}.'/f/js/en.js?'.$self->{version}, ''; + script type => 'text/javascript', src => $self->{url_static}.'/f/vndb.js?'.$self->{version}, ''; end 'body'; end 'html'; diff --git a/util/jsgen.pl b/util/jsgen.pl index aad133a1..cf2c5638 100755 --- a/util/jsgen.pl +++ b/util/jsgen.pl @@ -12,92 +12,6 @@ our($ROOT, %S, %O); BEGIN { ($ROOT = abs_path $0) =~ s{/util/jsgen\.pl$}{}; } require $ROOT.'/data/global.pl'; -use lib "$ROOT/lib"; -use LangFile; - -# The VNDB::L10N module is not really suited to be used outside the VNDB::* -# framework, but it's the central location that defines which languages we have -# and in what order to display them. -use VNDB::L10N; - - - -my %lang; # lang1 => { key1 => .., key22 => .. }, lang2 => { .. } - -sub l10n_load { - # fetch all text from lang.txt - my $lang = LangFile->new(read => "$ROOT/data/lang.txt"); - my $key; - while((my $l = $lang->read())) { - my $type = shift @$l; - $key = shift @$l if $type eq 'key'; - $lang{$l->[0]}{$key} = $l->[2] if $type eq 'tl'; - } -} - - -# Remove formatting codes from L10N strings that the Javascript mt() does not support. -# [quant,_n,x,..] -> x -# [index,_n,x,..] -> x -# [_n] is supported by Javascript mt(). It is left alone if no arguments are -# given, otherwise it is replaced. All other codes result in an error. -sub l10nstr { - my($lang, $key, @args) = @_; - local $_ = $lang{$lang}{$key} || $lang{'en'}{$key} || ''; - - # Simplify parsing - s/~\[/JSGEN_QBEGIN/g; - s/~]/JSGEN_QENDBR/g; - s/~,/JSGEN_QCOMMA/g; - - # Replace quant/index - s/\[(?:quant|index),_[0-9]+,([^,\]]*)[^\]]*\]/$1/g; - - # Replace [_n] - for my $i (0..$#args) { - my $v = $i+1; - s/\[_$v\]/$args[$i]/g; - } - - # Check for unhandled codes - die "Unsupported formatting code in $lang:$key\n" if /\[[^_]/; - - # Convert back - s/JSGEN_QBEGIN/~[/g; - s/JSGEN_QENDBR/~]/g; - s/JSGEN_QCOMMA/,/g; # No need to escape, at this point there are no codes with arguments - $_; -} - - -sub l10n { - my($lang, $js) = @_; - - # parse the .js code and replace mt()'s that can be modified in-place, otherwise add to the @keys - my @keys; - $js =~ s{(?:mt\('([a-z0-9_]+)'([,\)])|l10n /([^/]+)/)}# - my($k, $s, $q) = ($1, $2, $3); - my $v = $k && l10nstr($lang, $k); - if($q) { - $q ne '' && push @keys, qr/$q/; '' - } elsif($s eq ')' && $v && $v !~ /[\~\[\]]/) { - $v =~ s/"/\\"/g; - $v =~ s/\n/\\n/g; - qq{"$v"} - } else { - push @keys, '^'.quotemeta($k).'$'; - "mt('$k'$s" - } - #eg; - - my %keys; - for my $key (sort keys %{$lang{$lang}}) { - next if !grep $key =~ /$_/, @keys; - $keys{$key} = l10nstr($lang, $key); - } - (\%keys, $js); -} - # screen resolution information, suitable for usage in filFSelect() sub resolutions { @@ -118,11 +32,10 @@ sub resolutions { sub vars { - my($lang, $l10n) = @_; my %vars = ( rlist_status => $S{rlist_status}, cookie_prefix => $O{cookie_prefix}, - age_ratings => [ map [ $_, l10nstr($lang, $_ == -1 ? ('_unknown') : $_ == 0 ? ('_minage_all') : ('_minage_age', $_)) ], @{$S{age_ratings}} ], + age_ratings => [ map [ $_, $_ == -1 ? 'Unknown' : $_ == 0 ? 'All ages' : "$_+" ], @{$S{age_ratings}} ], languages => [ map [ $_, $S{languages}{$_} ], keys %{$S{languages}} ], platforms => [ map [ $_, $S{platforms}{$_} ], keys %{$S{platforms}} ], char_roles => [ map [ $_, $S{char_roles}{$_} ], keys %{$S{char_roles}} ], @@ -135,7 +48,6 @@ sub vars { genders => [ map [ $_, $S{genders}{$_} ], keys %{$S{genders}} ], staff_roles => [ map [ $_, $S{staff_roles}{$_} ], keys %{$S{staff_roles}} ], resolutions => scalar resolutions(), - l10n_str => $l10n, ); JSON::XS->new->encode(\%vars); } @@ -187,15 +99,7 @@ sub save { } } -sub jsgen { - my $js = readjs 'main.js'; - - for my $l (VNDB::L10N::languages()) { - my($l10n, $body) = l10n($l, $js); - $body =~ s{/\*VARS\*/}{vars($l, $l10n)}eg; - save "$ROOT/static/f/js/$l.js", $body; - } -} -l10n_load; -jsgen; +my $js = readjs; +$js =~ s{/\*VARS\*/}{vars()}eg; +save "$ROOT/static/f/vndb.js", $js; -- cgit v1.2.3