PageSourceSearch

https://trunghocduytan.com/mods/vietuni.js

js trunghocduytan.com collected 2026-09-27 05:41:42 UTC 11,060 bytes, 366 lines download raw bytes

1/*vietuni.js - V.1.618 - R.11.11.01 @QDJTGSLLA@P*Veni*Vidi*Vici*
2* by Tran Anh Tuan [[email protected]]
3* Copyright (c) 2001, 2002 AVYS e.V.. All Rights Reserved.
4*
5* Originally published and documented at http://www.avys.de/
6* You may use this code without fee on noncommercial web sites.
7* You may NOT alter the code and then call it another name and/or resell it.
8* The copyright notice must remain intact on srcipts.
9*/
10
11// interface for HTML:
12//
13
14
15var supported = (document.all || document.getElementById);
16var disabled = false;
17var charmapid = 1;
18var keymodeid = 0;
19var linebreak = 0;
20var theTyper = null;
21
22reset = function(){}
23initTyper = telexingVietUC;
24
25function setTypingMode(mode) {
26  keymodeid = mode;
27  if (theTyper) theTyper.keymode= initKeys();
28  if (!supported && !disabled) {
29    alert("Xin loi, trinh duyet web cua ban khong cho phep dung VietTyping.\n");
30    disabled = true;
31  }
32}
33
34initCharMap = function() { return new CVietUniCodeMap(); }
35
36initKeys = function() {
37  switch (keymodeid) {
38    case 1: return new CTelexKeys();
39    case 2: return new CVniKeys();
40    case 3: return new CViqrKeys();
41    case 4: return new CVKOff();
42    default: return new CAllKeys();
43  }
44}
45
46function telexingVietUC (txtarea) {
47  txtarea.vietarea= true;
48  txtarea.onkeyup= null;
49  if (!supported) return;
50  txtarea.onkeypress= vietTyping;
51  txtarea.getCurrentWord= getCurrentWord;
52  txtarea.replaceWord= replaceWord;
53  txtarea.onkeydown= onKeyDown;
54  txtarea.onmousedown= onMouseDown;
55  if(!theTyper) theTyper = new CVietString("");
56}
57
58function getEvt(evt) {
59  if (typeof(evt)=='string') return evt.charCodeAt(0);
60  return document.all? event.keyCode: (evt && evt.which)? evt.which: 0;
61}
62
63function onKeyDown(evt) {
64  var c= getEvt(evt);
65  if ((c==10) || (c==13)) { reset(1); linebreak= 1; }
66  else if ((c<49) && (c!=16) && (c!=20)) { linebreak= 0; reset(c==32); }
67  return true;
68}
69
70function onMouseDown(evt) { reset(0); linebreak= 0; return true; }
71
72function vietTyping(evt) {
73  var c= getEvt(evt);
74  theTyper.value= this.getCurrentWord();
75  var changed= ((c>32) && theTyper.typing(c));
76  if (changed) this.replaceWord(theTyper.value);
77  return !changed;
78}
79
80function getCurrentWord() {
81  if(!document.all) return this.value;
82  var caret = this.document.selection.createRange();
83  if (caret.text) return null;
84  var backward = -10;
85  do {
86    var caret2 = caret.duplicate();
87    caret2.moveStart("character", backward++);
88  } while (caret2.parentElement() != this && backward <0);
89  this.curword = caret2.duplicate();
90  return caret2.text;
91}
92
93function replaceWord(newword) {
94  if(!document.all) { this.value= newword; return; }
95  this.curword.text = newword;
96  this.curword.collapse(false);
97}
98// end interface
99
100
101// "class": CVietString
102//
103function CVietString(str) {
104  this.value= str;
105  this.keymode= initKeys();
106  this.charmap= initCharMap();
107  this.ctrlchar= '-';
108  this.changed= 0;
109
110  this.typing= typing;
111  this.Compose= Compose;
112  this.Correct= Correct;
113  this.findCharToChange= findCharToChange;
114  return this;
115}
116
117function typing(ctrl) {
118  this.changed = 0;
119  this.ctrlchar = String.fromCharCode(ctrl);
120  if (linebreak) linebreak= 0; else this.keymode.getAction(this);
121  this.Correct();
122  return this.changed;
123}
124
125function Compose(type) {
126  if(!this.value) return;
127  var info = this.findCharToChange(type);
128  if (!info || !info[0]) return;
129  var telex;
130  if (info[0]=='\\') telex= [1,this.ctrlchar,1];
131  else if (type>6) telex= this.charmap.getAEOWD(info[0], type, info[3]);
132  else telex= this.charmap.getDau(info[0], type);
133  if (!(this.changed = telex[0])) return;
134  this.value = this.value.replaceAt(info[1],telex[1],info[2]);
135  if (!telex[2]) { spellerror= 1; this.value+= this.ctrlchar; }
136}
137
138function Correct() {
139  if (this.charmap.maxchrlen || !document.all) return 0;
140  var tmp= this.value;
141  if ('nNcC'.indexOf(this.ctrlchar)>=0) tmp+= this.ctrlchar;
142  var er= /[^\x01-\x7f](hn|hc|gn)$/i.exec(tmp);
143  if (er) {
144    this.value= tmp.substring(0,tmp.length-2)+er[1].charAt(1)+er[1].charAt(0);
145    this.changed= 1;
146  }
147  else if(!this.changed) return 0;
148  er= /\w([^\x01-\x7f])(\w*)([^\x01-\x7f])\S*$/.exec(this.value);
149  if (!er) return 0;
150  var i= this.charmap.isVowel(er[1]);
151  var ri= (i-1)%24 + 1, ci= (i-ri)/24;
152  var i2= this.charmap.isVowel(er[3]);
153  if (!ci || !i2) return 0;
154  var ri2= (i2-1)%24 + 1, ci2= (i2-ri2)/24;
155  var nc= this.charmap.charAt(ri)+ er[2]+ this.charmap.charAt(ci*24+ri2);
156  this.value= this.value.replace(new RegExp(er[1]+er[2]+er[3],'g'), nc);
157}
158
159function findCharToChange(type) {
160  var lastchars= this.charmap.lastCharsOf(this.value, 5);
161  var i= 0, c=lastchars[0][0], chr=0;
162  if (c=='\\') return [c,this.value.length-1,1];
163  if (type==15) while (!(chr=this.charmap.isVD(c))) {
164    if ((c < 'A') || (i>=4) || !(c=lastchars[++i][0])) return null;
165  }
166  else while( "cghmnptCGHMNPT".indexOf(c)>=0) {
167    if ((c < 'A') || (i>=2) || !(c=lastchars[++i][0])) return null;
168  }
169  c = lastchars[0][0].toLowerCase();
170  var pc = lastchars[1][0].toLowerCase();
171  var ppc = lastchars[2][0].toLowerCase();
172  if (i==0 && type!=15) {
173    if ( (chr=this.charmap.isVowel(lastchars[1][0]))
174      && ("uyoia".indexOf(c)>=0) && !this.charmap.isUO(pc,c)
175      && !((pc=='o' && c=='a') || (pc=='u' && c=='y'))
176      && !((ppc=='q' && pc=='u') || (ppc=='g' && pc=='i')) ) ++i;
177    if (c=='a' && (type==9 || type==7)) i= 0;
178  }
179  c= lastchars[i][0];
180  if ((i==0 || chr==0) && type!=15) chr= this.charmap.isVowel(c);
181  if (!chr) return null;
182  var clen= lastchars[i][1], isuo=0;
183  if ((i>0) && (type==7 || type==8 || type==11)) {
184    isuo=this.charmap.isUO(lastchars[i+1][0],c);
185    if (isuo) { chr=isuo; clen+=lastchars[++i][1]; isuo=1; }
186  }
187  var pos= this.value.length;
188  for (var j=0; j<= i; j++) pos -= lastchars[j][1];
189  return [chr, pos, clen, isuo];
190}
191// end CVietString
192
193
194// character-map template
195//
196function CVietCharMap(){
197  this.vietchars = null;
198  this.length = 149;
199  this.chr_cache = new Array(20);
200  this.ind_cache = new Array(20);
201  this.cptr = 0;
202  this.caching= function(chr, ind) {
203    this.chr_cache[this.cptr] = chr;
204    this.ind_cache[this.cptr++] = ind;
205    this.cptr %= 20;
206  }
207  return this;
208}
209
210CVietCharMap.prototype.charAt= function(ind){
211  var chrcode = this.vietchars[ind];
212  return chrcode ? String.fromCharCode(chrcode) : null;
213}
214
215CVietCharMap.prototype.isVowel= function(chr){
216  var i = 0;
217  while ((i<20) && (chr != this.chr_cache[i])) ++i;
218  if (i<20) return this.ind_cache[i];
219
220  i = this.length-5;
221  while ((chr != this.charAt(i)) && i) --i;
222  this.caching(chr, i);
223  return i;
224}
225
226CVietCharMap.prototype.isVD= function (chr){
227  var ind = this.length-5;
228  while ((chr != this.charAt(ind)) && (ind < this.length)) ++ind;
229  return (ind<this.length)? ind: 0;
230}
231
232CVietCharMap.prototype.isUO= function (c1, c2){
233  if (!c1 || !c2) return 0;
234  var ind1 = this.isVowel(c1);
235  var ci = (ind1-1)%12;
236  if ((ci!=9) && (ci!=10)) return 0;
237  var ind2 = this.isVowel(c2);
238  ci = (ind2-1)%12;
239  if ((ci!=6) && (ci!=7) && (ci!=8)) return 0;
240  return [ind1,ind2];
241}
242
243CVietCharMap.prototype.getDau= function (ind, type){
244  var accented= (ind < 25)? 0: 1;
245  var ind_i= (ind-1) % 24 +1;
246  var charset= (type == 6)? 0 : type;
247  if ((type== 6) && !accented) return [0];
248  var newind= charset*24 + ind_i;
249  if (newind == ind) newind= ind_i;
250  var chr= this.charAt(newind);
251  if (!chr) chr= this.lowerCaseOf(0,newind);
252  return [1, chr, newind>24 || type==6];
253}
254
255var map=[
256[7,7,7,8,8, 8,9,10,11,15],
257[0,3,6,0,6, 9,0, 3, 6, 0],
258[1,4,7,2,8,10,1, 4, 7, 1]
259];
260CVietCharMap.prototype.getAEOWD= function(ind, type, isuo) {
261  var c=0, i1=isuo? ind[0]: ind;
262  var vc1= (type==15)? (i1-1)%2 : (i1-1)%12;
263  if (isuo) {
264    var base= ind[1]-(ind[1]-1)%12;
265    if (type==7 || type==11) c= this.charAt(i1-vc1+9)+this.charAt(base+7);
266    else if (type==8) c= this.charAt(i1-vc1+10)+this.charAt(base+8);
267    return [c!=0, c, 1];
268  }
269  var i= -1, shift= 0, del= 0;
270  while (shift==0 && ++i<map[0].length) {
271    if (map[0][i]==type) {
272      if(map[1][i]==vc1) shift= map[2][i]-vc1;
273      else if(map[2][i]==vc1) shift= map[1][i]-vc1;
274    }
275  }
276  if (shift==0) {
277    if (type==7 && (vc1==2 || vc1==8)) shift=-1;
278    else if ((type==9 && vc1==2) || (type==11 && vc1==8)) shift=-1;
279    else if (type==8 && (vc1==1 || vc1==7)) shift=1;
280    del= 1;
281  } else del=(shift>0);
282  i1 += shift;
283  var chr= this.charAt(i1);
284  if (i1<145) this.caching(chr, i1);
285  if (!chr) chr= this.lowerCaseOf(0, i1);
286  return [shift!=0, chr, del];
287}
288
289CVietCharMap.prototype.lastCharsOf= function(str, num){
290  if (!num) return [str.charAt(str.length-1),1];
291  var vchars = new Array(num);
292  for (var i=0; i< num; i++) { vchars[i]= [str.charAt(str.length-i-1),1]; }
293  return vchars;
294}
295// end CVietCharMap prototype
296
297
298String.prototype.replaceAt= function(i,newchr,clen){
299  return this.substring(0,i)+ newchr + this.substring(i+clen);
300}
301
302// output map: class CVietUniCodeMap
303//
304function CVietUniCodeMap(){ var map= new CVietCharMap();
305map.vietchars = new Array(
306"UNICODE",
30797, 226, 259, 101, 234, 105, 111, 244, 417, 117, 432, 121,
30865, 194, 258, 69, 202, 73, 79, 212, 416, 85, 431, 89,
309225, 7845, 7855, 233, 7871, 237, 243, 7889, 7899, 250, 7913, 253,
310193, 7844, 7854, 201, 7870, 205, 211, 7888, 7898, 218, 7912, 221,
311224, 7847, 7857, 232, 7873, 236, 242, 7891, 7901, 249, 7915, 7923,
312192, 7846, 7856, 200, 7872, 204, 210, 7890, 7900, 217, 7914, 7922,
3137841, 7853, 7863, 7865, 7879, 7883, 7885, 7897, 7907, 7909, 7921, 7925,
3147840, 7852, 7862, 7864, 7878, 7882, 7884, 7896, 7906, 7908, 7920, 7924,
3157843, 7849, 7859, 7867, 7875, 7881, 7887, 7893, 7903, 7911, 7917, 7927,
3167842, 7848, 7858, 7866, 7874, 7880, 7886, 7892, 7902, 7910, 7916, 7926,
317227, 7851, 7861, 7869, 7877, 297, 245, 7895, 7905, 361, 7919, 7929,
318195, 7850, 7860, 7868, 7876, 296, 213, 7894, 7904, 360, 7918, 7928,
319100, 273, 68, 272);
320return map;
321}
322
323// input methods: class C...Keys
324function CVietKeys() {
325  this.getAction= function(typer){
326    var i= this.keys.indexOf(typer.ctrlchar.toLowerCase());
327    if(i>=0) typer.Compose(this.actions[i]);
328  }
329  return this;
330}
331
332function CVKOff() {
333  this.off = true;
334  this.getAction= function(){};
335  return this;
336}
337
338function CTelexKeys() {
339  var k= new CVietKeys();
340  k.keys= "0123456789";
341  k.actions= [6,1,2,4,5,3,7,8,8,15];
342  return k;
343}
344
345function CVniKeys() {
346  var k= new CVietKeys();
347  k.keys= "0123456789";
348  k.actions= [6,1,2,4,5,3,7,8,8,15];
349  return k;
350}
351
352function CViqrKeys() {
353  var k= new CVietKeys();
354  k.keys= "\xB4/'\u2019`.?~-^(*+d";
355  k.actions= [1,1,1,1,2,3,4,5,6,7,8,8,8,15];
356  return k;
357}
358
359function CAllKeys() {
360  var k= new CVietKeys();
361  k.keys= "0123456789\xB4/'\u2019`.?~-^(*+d";
362  k.actions= [6,1,2,4,5,3,7,8,8,15,1,1,1,1,2,3,4,5,6,7,8,8,8,15];
363  return k;
364}
365
366// end vietuni.js

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.