| 1 | /** |
|---|
| 2 | * encodingSwithcer (Vimperator plugin) |
|---|
| 3 | * @author teramako teramako@gmail.com |
|---|
| 4 | * @version 0.1 |
|---|
| 5 | * |
|---|
| 6 | * Usage: |
|---|
| 7 | * |
|---|
| 8 | * change encoding |
|---|
| 9 | * :set fileencoding = {encodeName} |
|---|
| 10 | * :set fenc = {encodeName} |
|---|
| 11 | * |
|---|
| 12 | * list available encodings |
|---|
| 13 | * :listencoding [expr] |
|---|
| 14 | * :lsenc [expr] |
|---|
| 15 | * |
|---|
| 16 | * change auto detector |
|---|
| 17 | * :set autodetector = {detectorName} |
|---|
| 18 | * :set audet = {detectorName} |
|---|
| 19 | * |
|---|
| 20 | * list available auto detectors |
|---|
| 21 | * :listdetector [expr] |
|---|
| 22 | * :lsdet [expr] |
|---|
| 23 | */ |
|---|
| 24 | (function(){ |
|---|
| 25 | |
|---|
| 26 | var encodings = []; |
|---|
| 27 | var detectors = []; |
|---|
| 28 | const Cc = Components.classes; |
|---|
| 29 | const Ci = Components.interfaces; |
|---|
| 30 | if (!RDF) var RDF = Cc['@mozilla.org/rdf/rdf-service;1'].getService(Ci.nsIRDFService); |
|---|
| 31 | if (!RDFCU) var RDFCU = Cc['@mozilla.org/rdf/container-utils;1'].getService(Ci.nsIRDFContainerUtils); |
|---|
| 32 | var cm = RDF.GetDataSource('rdf:charset-menu'); |
|---|
| 33 | var sbService = Cc['@mozilla.org/intl/stringbundle;1'].getService(Ci.nsIStringBundleService); |
|---|
| 34 | var sbCharTitle = sbService.createBundle('chrome://global/locale/charsetTitles.properties'); |
|---|
| 35 | CreateMenu('browser'); |
|---|
| 36 | CreateMenu('more-menu'); |
|---|
| 37 | var allEnum = cm.GetAllResources(); |
|---|
| 38 | while (allEnum.hasMoreElements()){ |
|---|
| 39 | var res = allEnum.getNext().QueryInterface(Ci.nsIRDFResource); |
|---|
| 40 | var value = res.Value; |
|---|
| 41 | if (RDFCU.IsContainer(cm, res) || value.indexOf('charset.') == 0 || value.indexOf('----') == 0) { |
|---|
| 42 | continue; |
|---|
| 43 | } |
|---|
| 44 | var label = sbCharTitle.GetStringFromName(value.toLowerCase() + '.title'); |
|---|
| 45 | if (res.Value.indexOf('chardet.') == 0){ |
|---|
| 46 | value = value.substr('chardet.'.length); |
|---|
| 47 | var buf = createDetector(value); |
|---|
| 48 | buf[1] = label; |
|---|
| 49 | detectors.push(buf); |
|---|
| 50 | } else { |
|---|
| 51 | encodings.push([value,label]); |
|---|
| 52 | } |
|---|
| 53 | } |
|---|
| 54 | function createDetector(name){ |
|---|
| 55 | var i = name.indexOf('_'); |
|---|
| 56 | if (i > 0){ |
|---|
| 57 | return [name.substr(0,i),null,name.substr(i)]; |
|---|
| 58 | } |
|---|
| 59 | return [name,null,'']; |
|---|
| 60 | } |
|---|
| 61 | function getDetector(name){ |
|---|
| 62 | for (let i = 0, l = detectors.length; i < l; i++){ |
|---|
| 63 | if (detectors[i][0].toLowerCase() == name.toLowerCase()){ |
|---|
| 64 | return detectors[i][0] + detectors[i][2]; |
|---|
| 65 | } |
|---|
| 66 | } |
|---|
| 67 | } |
|---|
| 68 | function getEncoding(name){ |
|---|
| 69 | for (let i = 0, l = encodings.length; i < l; i++){ |
|---|
| 70 | if (encodings[i][0].toLowerCase() == name.toLowerCase()){ |
|---|
| 71 | return encodings[i][0]; |
|---|
| 72 | } |
|---|
| 73 | } |
|---|
| 74 | } |
|---|
| 75 | function isValid(array, value) array.some(function(v) |
|---|
| 76 | v[0].toLowerCase() == value.toLowerCase()); |
|---|
| 77 | function completion(array, filter){ |
|---|
| 78 | if (!filter) return array; |
|---|
| 79 | filter = filter.toLowerCase(); |
|---|
| 80 | return array.filter(function(v) |
|---|
| 81 | v[0].toLowerCase().indexOf(filter) == 0); |
|---|
| 82 | } |
|---|
| 83 | var sbCharDefault = sbService.createBundle(gPrefService.getDefaultBranch('intl.charset.').getCharPref('default')); |
|---|
| 84 | const DEFAULT_CHARSET = sbCharDefault.GetStringFromName('intl.charset.default'); |
|---|
| 85 | options.add(['fileencoding','fenc'],'set the charactor encoding for the current page','string', DEFAULT_CHARSET, |
|---|
| 86 | { |
|---|
| 87 | scope: options.OPTION_SCOPE_LOCAL, |
|---|
| 88 | setter: function(value){ |
|---|
| 89 | if (value) { |
|---|
| 90 | value = getEncoding(value); |
|---|
| 91 | liberator.log('set: ' + value) |
|---|
| 92 | SetForcedCharset(value); |
|---|
| 93 | } |
|---|
| 94 | return value; |
|---|
| 95 | }, |
|---|
| 96 | getter: function() |
|---|
| 97 | getBrowser().docShell.QueryInterface(Ci.nsIDocCharset).charset, |
|---|
| 98 | validator: function(value) |
|---|
| 99 | isValid(encodings, value), |
|---|
| 100 | completer: function(context) { |
|---|
| 101 | context.completions = completion(encodings, context.filter); |
|---|
| 102 | } |
|---|
| 103 | } |
|---|
| 104 | ); |
|---|
| 105 | var sbCharDetector = sbService.createBundle(gPrefService.getDefaultBranch('intl.charset.').getCharPref('detector')); |
|---|
| 106 | const DEFAULT_DETECTOR = createDetector(sbCharDetector.GetStringFromName('intl.charset.detector'))[0]; |
|---|
| 107 | options.add(['autodetector','audet'],'set auto detect character encoding','string',DEFAULT_DETECTOR, |
|---|
| 108 | { |
|---|
| 109 | setter: function(value){ |
|---|
| 110 | var pref = Cc['@mozilla.org/preferences-service;1'].getService(Ci.nsIPrefBranch); |
|---|
| 111 | var str = Cc['@mozilla.org/supports-string;1'].createInstance(Ci.nsISupportsString); |
|---|
| 112 | if (!value || value == 'off') { |
|---|
| 113 | str.data = ''; |
|---|
| 114 | } else { |
|---|
| 115 | str.data = value = getDetector(value); |
|---|
| 116 | } |
|---|
| 117 | pref.setComplexValue('intl.charset.detector',Ci.nsISupportsString, str); |
|---|
| 118 | SetForcedDetector(true); |
|---|
| 119 | }, |
|---|
| 120 | getter: function(){ |
|---|
| 121 | var elms = document.getElementById('charsetMenu').getElementsByAttribute('checed','true'); |
|---|
| 122 | for (let i = 0,l = elms.length; i < l; i++){ |
|---|
| 123 | if (elms[i].getAttribute('name') == 'detectorGroup'){ |
|---|
| 124 | let str = elms[i].getAttribute('id').substr('chardet.'.length); |
|---|
| 125 | return createDetector(str)[0]; |
|---|
| 126 | } |
|---|
| 127 | } |
|---|
| 128 | }, |
|---|
| 129 | validator: function(value) |
|---|
| 130 | isValid( detectors, value), |
|---|
| 131 | completer: function(context) { |
|---|
| 132 | context.completions = completion(detectors, context.filter); |
|---|
| 133 | } |
|---|
| 134 | } |
|---|
| 135 | ); |
|---|
| 136 | function listCharset(arg, current, list){ |
|---|
| 137 | if (!arg) arg = '.'; |
|---|
| 138 | var reg = new RegExp(arg,'i'); |
|---|
| 139 | var str = []; |
|---|
| 140 | str.push('<table>'); |
|---|
| 141 | list.forEach(function(i){ |
|---|
| 142 | if (!reg.test(i[0]) && !reg.test(i[1])) return; |
|---|
| 143 | str.push('<tr>'); |
|---|
| 144 | if (current == i[0]){ |
|---|
| 145 | str.push('<td class="hl-Title">' + i[0] + '</td><td class="hl-Title">' + i[1] + '</td>'); |
|---|
| 146 | } else { |
|---|
| 147 | str.push('<td>' + i[0] + '</td><td>' + i[1] + '</td>'); |
|---|
| 148 | } |
|---|
| 149 | str.push('</tr>'); |
|---|
| 150 | }); |
|---|
| 151 | str.push('</table>'); |
|---|
| 152 | liberator.echo( str.join(''), true); |
|---|
| 153 | } |
|---|
| 154 | commands.addUserCommand(['listencoding','lsenc'],'list all encodings', |
|---|
| 155 | function(arg){ |
|---|
| 156 | listCharset(arg, options.fileencoding, encodings); |
|---|
| 157 | },{ |
|---|
| 158 | completer: function(context) { |
|---|
| 159 | context.completions = completion(encodings, context.filter); |
|---|
| 160 | } |
|---|
| 161 | } |
|---|
| 162 | ); |
|---|
| 163 | commands.addUserCommand(['listdetector','lsdet'],'list all auto detectors', |
|---|
| 164 | function(arg){ |
|---|
| 165 | listCharset(arg, options.autodetector, detectors); |
|---|
| 166 | },{ |
|---|
| 167 | completer: function(context) { |
|---|
| 168 | context.completions = completion(detectors, context.filter); |
|---|
| 169 | } |
|---|
| 170 | } |
|---|
| 171 | ); |
|---|
| 172 | |
|---|
| 173 | })(); |
|---|
| 174 | |
|---|
| 175 | // vim: set fdm=marker sw=4 ts=4 et: |
|---|