2 Ajax IME: http://ajaxime.chasen.org/
3 Author: Taku Kudo <taku@chasen.org>
5 (C) Taku Kudo, all rights reserve rd.
9 //////////////////////////////////////////////////////////////////////////////////////////
13 // We cannot simply define getComputedStyle() in "if" block because it seems
14 // like Safari overwrites functions during parsing the script i.e, before
15 // execution (bug?). So we substitue it at run time instead.
17 // *** TESTED ONLY ON Firefox3 AND Safari3 ***
19 if (typeof(getComputedStyle) == 'undefined') {
20 function capitalize(prop) {
21 return prop.replace(/-(.)/g, function(m, m1) { return m1.toUpperCase(); })
23 function getComputedStyle(element, pseudo){
25 currentStyle : element.currentStyle,
26 getPropertyValue : function(prop){
27 return this.currentStyle[capitalize(prop)];
29 setProperty : function(prop, value){
30 this.currentStyle[capitalize(prop)] = value;
35 // getComputedStyle == __getComputedStyle;
38 function JSONRequest(url) {
40 this.parent_ = document.getElementsByTagName('head').item(0);
41 this.obj_ = document.createElement('script');
42 this.obj_.setAttribute('type', 'text/javascript');
43 this.obj_.setAttribute('charset', 'utf-8');
44 this.obj_.setAttribute('src', this.url_);
45 this.parent_.appendChild(this.obj_);
48 JSONRequest.prototype.remove = function () {
49 this.parent_.removeChild(this.obj_);
52 function getEvent (evt) {
53 return (evt) ? evt : ((window.event) ? event : null);
56 function getKeyCode(event) {
57 var evt = getEvent(event);
58 return ((evt.which) ? evt.which : evt.keyCode);
61 function callWithDelay(func, delay) {
62 if (delay) setTimeout(func, 0);
66 function addEvent(obj, event, func) {
67 if (obj.addEventListener) {
68 obj.addEventListener(event, func, false);
69 } else if(obj.attachEvent){
70 obj.attachEvent('on' + event, func);
75 function copyFontStyle(elmOriginal, elmClone) {
76 var styleOriginal = getComputedStyle(elmOriginal,'');
77 var styleClone = getComputedStyle(elmClone,'');
78 elmClone.style["fontFamily"] = styleOriginal.getPropertyValue("font-family");
79 elmClone.style["fontSize"] = styleOriginal.getPropertyValue("font-size");
80 elmClone.style["fontWeight"] = styleOriginal.getPropertyValue('font-weight');
81 elmClone.style["fontVariant"] = styleOriginal.getPropertyValue('font-variant');
84 function cloneElement(elmOriginal, elmClone) {
85 var styleOriginal = getComputedStyle(elmOriginal,'');
87 var styleClone = getComputedStyle(elmClone,'');
88 elmClone.style.left = elmOriginal.offsetLeft + 'px';
89 elmClone.style.top = (elmOriginal.offsetTop + elmOriginal.offsetHeight + 30) + 'px';
91 elmClone.style["width"] = styleOriginal.getPropertyValue('width');
92 elmClone.style["height"] = styleOriginal.getPropertyValue('height');
93 elmClone.style["padding"] = styleOriginal.getPropertyValue('padding');
94 elmClone.style["paddingLeft"] = styleOriginal.getPropertyValue('padding-left');
95 elmClone.style["paddingRight"] = styleOriginal.getPropertyValue('padding-right');
96 elmClone.style["paddingTop"] = styleOriginal.getPropertyValue('padding-top');
97 elmClone.style["paddingBottom"] = styleOriginal.getPropertyValue('padding-bottom');
98 elmClone.style["borderStyle"] = styleOriginal.getPropertyValue('border-style');
99 elmClone.style["borderLeftStyle"] = styleOriginal.getPropertyValue('border-left-style');
100 elmClone.style["borderRightStyle"] = styleOriginal.getPropertyValue('border-right-style');
101 elmClone.style["borderTopStyle"] = styleOriginal.getPropertyValue('border-top-style');
102 elmClone.style["borderBottomStyle"] = styleOriginal.getPropertyValue('border-bottom-style');
103 elmClone.style["borderLeftWidth"] = styleOriginal.getPropertyValue('border-left-width');
104 elmClone.style["borderRightWidth"] = styleOriginal.getPropertyValue('border-right-width');
105 elmClone.style["borderTopWidth"] = styleOriginal.getPropertyValue('border-top-width');
106 elmClone.style["borderBottomWidth"] = styleOriginal.getPropertyValue('border-bottom-width');
107 elmClone.style["borderWidth"] = styleOriginal.getPropertyValue('border-width');
108 elmClone.style["fontFamily"] = styleOriginal.getPropertyValue('font-family');
109 elmClone.style["fontSize"] = styleOriginal.getPropertyValue('font-size');
110 elmClone.style["fontVariant"] = styleOriginal.getPropertyValue('font-variant');
111 elmClone.style["fontWeight"] = styleOriginal.getPropertyValue('font-weight');
112 elmClone.style["lineHeight"] = styleOriginal.getPropertyValue('line-height');
113 elmClone.style["letterSpacing"] = styleOriginal.getPropertyValue('letter-spacing');
114 elmClone.style["wordSpacing"] = styleOriginal.getPropertyValue('word-spacing');
115 elmClone.style.width = elmOriginal.offsetWidth;
116 elmClone.style.height = elmOriginal.offsetHeight;
117 elmClone.scrollLeft = elmOriginal.scrollLeft;
118 elmClone.scrollTop = elmOriginal.scrollTop;
121 //////////////////////////////////////////////////////////////////////////////////////////
122 var ImeCGI_ = "http://api.chasen.org/ajaxime/";
123 var ImeBackGroundColor_ = 'aliceblue';
126 var ImeCurrentDocument_ = null;
128 function AjaxIME(doc) {
129 var ImeJsonp_ = null;
130 var ImeJsonpLog_ = null;
131 var ImeDocument_ = doc;
133 var ImeResults_ = [];
135 var ImeNumResults_ = 0;
136 var ImeLoaded_ = false;
137 var ImeCandidates_ = null;
138 var ImePreEdit_ = null;
139 var ImePreEditWidth_ = 0;
140 var ImeWindow_ = null;
141 var ImeTextArea_ = null;
142 var ImeTextAreaClone_ = null;
143 var ImeSelectedIndex_ = -1;
144 var ImeStartPos_ = 0;
149 if (ImeLoaded_) return;
150 ImeWindow_ = ImeDocument_.createElement('div');
151 ImePreEdit_ = ImeDocument_.createElement('input');
152 ImePreEdit_.setAttribute('type', 'text');
153 ImePreEdit_.setAttribute('autocomplete', 'off');
154 ImeCandidates_ = ImeDocument_.createElement('div');
155 ImeTextAreaClone_ = ImeDocument_.createElement('pre');
156 ImePreEdit_.__ImeUsed = ImeTextAreaClone_.__ImeUsed = true;
157 ImeWindow_.appendChild(ImePreEdit_);
158 ImeWindow_.appendChild(ImeCandidates_);
159 ImeDocument_.body.appendChild(ImeWindow_);
161 ImeWindow_.style.position = 'absolute';
162 ImeWindow_.style.margin = '0px';
163 ImeWindow_.style.padding = '0px';
164 ImeWindow_.style.textAlign = 'left';
165 ImePreEdit_.style.backgroundColor = ImeBackGroundColor_;
166 ImePreEdit_.style.borderWidth = '0px';
167 ImePreEdit_.style.textDecoration = 'underline';
168 ImePreEdit_.style.textUnderLineColor = 'red';
169 ImePreEdit_.style.textAlign = 'left';
170 ImeCandidates_.style.padding = '0px';
171 ImeCandidates_.style.borderColor = '#000';
172 ImeCandidates_.style.borderWidth = '1px';
173 ImeCandidates_.style.borderStyle = 'solid';
174 ImeCandidates_.style.styleFloat = 'left'; // IE
175 ImeCandidates_.style.cssFloat = 'left'; // Firefox
176 ImeCandidates_.style.textAlign = 'left';
178 ImeDocument_.ImeRequestCallback = ImeRequestCallback;
179 ImeDocument_.ImeChangeMode = ImeChangeMode;
181 addEvent(ImeDocument_, 'keydown', ImeDocumentKeyDown);
182 addEvent(ImePreEdit_, 'keydown', ImePreEditKeyDown);
183 addEvent(ImePreEdit_, 'keyup', ImePreEditKeyUp);
185 setInterval(ImeInitTextAreas, 500);
191 function ImeInitTextAreas() {
192 var inputs = ImeDocument_.getElementsByTagName('input');
193 for (var i = 0; i < inputs.length; ++i) {
194 if (inputs[i].type == 'text') ImeInitTextAreaEvent(inputs[i]);
197 var textareas = ImeDocument_.getElementsByTagName('textarea');
198 for (var i = 0; i < textareas.length; ++i) {
199 ImeInitTextAreaEvent(textareas[i]);
203 function ImeInitTextAreaEvent(textarea) {
204 if (!textarea.__ImeUsed && !textarea.__ImeRegistered) {
205 addEvent(textarea, 'keydown', ImeTextAreaKeyDown);
206 addEvent(textarea, 'click', ImeHide);
207 textarea.__ImeRegistered = true;
211 function ImeSetCaretPos(pos) {
212 if (ImeTextArea_.setSelectionRange) { // Mozilla
213 ImeTextArea_.setSelectionRange(pos, pos);
214 } else if (ImeDocument_.selection.createRange ){ // IE
215 var e = ImeTextArea_.createTextRange();
216 var tx = ImeTextArea_.value.substr(0, pos);
217 var pl = tx.split(/\n/);
219 e.moveStart('character', pos - pl.length + 1);
223 ImeTextArea_.focus();
226 function ImeStoreCaretPos() {
229 if (ImeTextArea_.setSelectionRange) { // mozilla
230 startpos = ImeTextArea_.selectionStart;
231 endpos = ImeTextArea_.selectionEnd;
232 } else if (ImeDocument_.selection.createRange) { // IE
233 if (ImeTextArea_.type == 'textarea') {
234 ImeTextArea_.caretPos = ImeDocument_.selection.createRange().duplicate();
235 var sel = ImeDocument_.selection.createRange();
236 var r = ImeTextArea_.createTextRange();
237 var len = ImeTextArea_.value.length;
238 r.moveToPoint(sel.offsetLeft, sel.offsetTop);
239 r.moveEnd('textedit');
240 startpos = len - r.text.length
241 endpos = startpos + sel.text.length;
243 var r = ImeDocument_.selection.createRange();
244 var len = ImeTextArea_.value.length;
245 r.moveEnd('textedit');
246 startpos = len - r.text.length
250 ImeStartPos_ = startpos;
254 function ImeStoreWindowPos() {
257 var x2 = ImeDocument_.body.scrollTop;
258 var y2 = ImeDocument_.body.scrollLeft;
260 if (! ImeTextArea_.createTextRange || ImeTextArea_.type != 'textarea') {
261 for (var o = ImeTextArea_; o ; o = o.offsetParent) {
262 x2 += (o.offsetLeft - o.scrollLeft);
263 y2 += (o.offsetTop - o.scrollTop);
267 if (ImeTextArea_.selectionStart || ImeTextArea_.selectionStart == '0') { // Mozilla
268 cloneElement(ImeTextArea_, ImeTextAreaClone_);
269 ImeTextArea_.offsetParent.appendChild(ImeTextAreaClone_);
270 var value = ImeTextArea_.value.replace(/\r\n/g, '\n\r') + ' ';
271 var caretPos = ImeDocument_.createElement('span');
272 caretPos.innerHTML = '|';
273 ImeTextAreaClone_.innerHTML = '';
274 ImeTextAreaClone_.appendChild(ImeDocument_.createTextNode(value.substr(0,ImeStartPos_)));
275 ImeTextAreaClone_.appendChild(caretPos);
276 ImeTextAreaClone_.appendChild(ImeDocument_.createTextNode(value.substr(ImeStartPos_)));
277 y = y2 + (caretPos.offsetTop - ImeTextAreaClone_.offsetTop);
278 x = x2 + (caretPos.offsetLeft - ImeTextAreaClone_.offsetLeft);
279 ImeTextArea_.offsetParent.removeChild(ImeTextAreaClone_);
281 var caretPos = ImeDocument_.selection.createRange();
282 y = y2 + (caretPos.offsetTop + ImeDocument_.documentElement.scrollTop - 3); // why -3 ??
283 x = x2 + (caretPos.offsetLeft + ImeDocument_.documentElement.scrollLeft);
286 ImeWindow_.style.top = y + 'px';
287 ImeWindow_.style.left = x + 'px';
290 function ImeInsertText(text, delay) {
291 var func = function() { ImeSetCaretPos(ImeStartPos_ + text.length); }
293 if (ImeTextArea_.createTextRange && ImeTextArea_.caretPos) {
294 var caretPos = ImeTextArea_.caretPos;
295 caretPos.text = caretPos.text.charAt(caretPos.text.length - 1) == ' ' ?
297 callWithDelay(func, delay);
299 var tmpTop = ImeTextArea_.scrollTop;
300 var tmpLeft = ImeTextArea_.scrollLeft;
301 ImeTextArea_.value = ImeTextArea_.value.substring(0, ImeStartPos_) +
302 text + ImeTextArea_.value.substring(ImeEndPos_, ImeTextArea_.value.length);
303 callWithDelay(func, delay);
304 ImeTextArea_.scrollTop = tmpTop;
305 ImeTextArea_.scrollLeft = tmpLeft;
309 function ImeAdd(text, selected) {
310 if (text == '') return;
312 if (selected) ImeSelectedIndex_ = ImeNumResults_;
314 var n = ImeNumResults_;
315 ImeResults_[ImeNumResults_++] = text;
317 if (text.length > ImePreEditWidth_)
318 ImePreEditWidth_ = text.length;
320 var div = ImeDocument_.createElement('div');
321 div.style.width = '100%';
322 div.style.styleFloat = 'left';
323 div.style.cssFloat = 'left';
325 div.style.backgroundColor = '#36c';
326 div.style.color = '#fff';
328 div.style.backgroundColor = '#fff';
329 div.style.color = '#000';
332 var txt = ImeDocument_.createTextNode(text);
333 var span = ImeDocument_.createElement('span');
334 span.appendChild(txt);
335 copyFontStyle(ImeTextArea_, span);
336 addEvent(div, 'click', function() {
337 ImeSelectedIndex_ = n; ImeSelect(true); ImeHide(); });
338 div.appendChild(span);
339 ImeCandidates_.appendChild(div);
342 function ImeHandleDown() {
343 if (ImeIsHidden()) return;
345 if (ImeSelectedIndex_ == ImeNumResults_) ImeSelectedIndex_ = 0;
349 function ImeHandleUp() {
350 if (ImeIsHidden()) return;
352 if (ImeSelectedIndex_ < 0) ImeSelectedIndex = ImeNumResults_ - 1;
356 function ImeHighlight() {
357 var divs = ImeCandidates_.getElementsByTagName('div');
358 for (var i = 0; i < divs.length; ++i) {
359 if (i == ImeSelectedIndex_) {
360 ImePreEdit_.value = ImeResults_[i];
361 divs[i].style.backgroundColor = '#36c';
362 divs[i].style.color = '#fff';
364 divs[i].style.backgroundColor = '#fff';
365 divs[i].style.color = '#000';
371 ImeInsertText('', false);
372 if (ImeRawInput_ != '')
376 function ImeSelect(delay) {
377 var result = ImeResults_.length ? ImeResults_[ImeSelectedIndex_] : ImePreEdit_.value;
378 ImeInsertText(result, delay);
382 function ImeIsHidden() {
383 return (ImeCandidates_.style.display == 'none');
386 function ImeHideCandidates() {
387 ImeCandidates_.style.display = 'none';
388 ImeCandidates_.innerHTML = '';
392 ImeWindow_.style.display = 'none';
393 ImePreEdit_.style.display = 'none';
398 function ImeClear() {
403 function ImeClearPreEdit() {
404 ImePreEdit_.value = '';
405 ImePreEditWidth_ = 0;
410 function ImeClearResults() {
411 ImeSelectedIndex_ = -1;
417 ImePreEdit_.style.display = 'block';
418 ImeWindow_.style.display = 'block';
421 function ImeShowPreEdit() {
429 function ImeLog(result) {
430 if (ImeRawInput_ == '') ImeRawInput_ = result;
431 if (ImeSelectedIndex_ >= 1) ImeCache_[ImeRawInput_] = result;
432 var request = "action=log&query=" + encodeURI(ImeRawInput_) +
433 "&result=" + encodeURI(result) + "&sel=" + ImeSelectedIndex_ +
435 ImeJsonpLog_ = new JSONRequest(ImeCGI_ + request);
439 function ImeRequestCallback(result) {
442 var c = ImeCache_[ImeRawInput_];
445 for (var i = 0; i < result.length; i++) {
446 if (result[i] != c) ImeAdd(result[i], 0);
449 for (var i = 0; i < result.length; i++) {
450 ImeAdd(result[i], i == 0 ? 1 : 0);
453 if (ImeResults_.length) ImePreEdit_.value = ImeResults_[0];
454 if (ImeRawInput_ == '') ImeRawInput_ = roma2hiragana(ImePreEdit_.value, false);
455 ImeCandidates_.style.display = 'block';
456 if (ImeJsonp_) ImeJsonp_.remove();
460 function ImeShowCandidates() {
461 if (!ImeIsHidden()) return;
462 if (ImeRawInput_ == '') ImeRawInput_ = roma2hiragana(ImePreEdit_.value, false);
463 var request = "action=conv&to=" + ImeTo_ + "&query=" + encodeURI(ImeRawInput_) +
465 ImeCurrentDocument_ = ImeDocument_;
466 ImeJsonp_ = new JSONRequest(ImeCGI_ + request);
469 function ImePreEditKeyDown(event) {
470 if (!ImeMode_) return false;
472 var evt = getEvent(event);
473 var key = getKeyCode(event);
476 if (key == 0x20) { // space
482 } else if (key == 120) { // F9 katakana
486 } else if (key == 119) { // F9 roma
490 } else if (key == 40) { // down
492 } else if (key == 38) { // up
494 } else if (key == 13) { // return
497 } else if (key == 27) { // esc, delete, bs
500 } else if (! ImeIsHidden()) { // next word
502 ImeStartPos_ += ImePreEdit_.value.length;
503 ImeSetCaretPos(ImeStartPos_);
514 function ImePreEditKeyUp(event) {
515 if (ImePreEdit_.value.length == 0) {
521 ImePreEdit_.value = roma2hiragana(ImePreEdit_.value, true);
523 if (ImePreEdit_.value.length > ImePreEditWidth_)
524 ImePreEditWidth_ = ImePreEdit_.value.length;
526 var fontsize = parseFloat(getComputedStyle(ImeTextArea_, '').getPropertyValue('font-size'));
528 var length = (1.5 * fontsize * (ImePreEditWidth_ + 1)) + 'px';
529 ImePreEdit_.style.width = length;
530 ImeWindow_.style.width = length;
531 ImeCandidates_.style.width = length;
536 function ImeChangeMode() {
537 ImeMode_ = !ImeMode_;
540 var inputs = ImeDocument_.getElementsByTagName('input');
541 for (var i = 0; i < inputs.length; ++i) {
542 if (!inputs[i].__ImeUsed && inputs[i].type == 'text') {
543 inputs[i].style.backgroundColor = ImeMode_ ? ImeBackGroundColor_ : 'white';
547 var textareas = ImeDocument_.getElementsByTagName('textarea');
548 for (var i = 0; i < textareas.length; ++i) {
549 if (!textareas[i].__ImeUsed)
550 textareas[i].style.backgroundColor = ImeMode_ ? ImeBackGroundColor_ : 'white';
554 function ImeDocumentKeyDown(event) {
555 var evt = getEvent(event);
556 var key = getKeyCode(event);
557 if ((key == 79 && evt.altKey) || ((key == 57 || key == 81) && evt.ctrlKey)) {
564 function ImeTextAreaKeyDown(event) {
565 var evt = getEvent(event);
566 var key = getKeyCode(event);
568 ImeTextArea_ = evt.target || evt.srcElement;
570 copyFontStyle(ImeTextArea_, ImePreEdit_);
572 if (ImeMode_) ImeHide();
575 if (evt.ctrlKey || evt.altKey) return true;
577 if (ImeMode_ && ImeIsHidden() &&
578 ((key >= 65 && key <= 90) ||
579 (key >= 48 && key <= 57) || (key >= 187 && key <= 222))) {
590 function roma2hiragana(str, delay) {
597 var last = str.substr(l - 1, 1);
598 var last2 = str.substr(l - 2, 2);
599 if (l > 1 && last2 == 'nn') {
602 } else if (l > 1 && last2.match(/^[qwrtyplkjhgfdszxcvbmn]y$/)) {
603 text = str.substr(0, l - 2);
605 } else if (l > 0 && last.match(/[qwrtyplkjhgfdszxcvbmn]/)) {
606 text = str.substr(0, l - 1);
611 for (var i = 0; i < text.length;) {
612 var o = text.charAt(i);
613 var c = o.charCodeAt(0);
615 if ((c >= 97 && c <= 122) || (c >= 65 && c <= 90) || (c >= 44 && c <= 46))
618 var key = text.slice(i, i + len);
619 if (key in IMERoma2KatakanaTable_) {
620 var kana = IMERoma2KatakanaTable_[key];
621 if (typeof(kana) == 'string') {
625 result.push(kana[0]);
626 i += (len - kana[1]);
639 return result.join("") + rem;
642 IMERoma2KatakanaTable_ = {'.':'。',',':'、','-':'ー','~':'〜','va':'う゛ぁ','vi':'う゛ぃ','vu':'う゛','ve':'う゛ぇ','vo':'う゛ぉ','vv': ['っ',1],'xx': ['っ',1],'kk': ['っ',1],'gg': ['っ',1],'ss': ['っ',1],'zz': ['っ',1],'jj': ['っ',1],'tt': ['っ',1],'dd': ['っ',1],'hh': ['っ',1],'ff': ['っ',1],'bb': ['っ',1],'pp': ['っ',1],'mm': ['っ',1],'yy': ['っ',1],'rr': ['っ',1],'ww': ['っ',1],'cc': ['っ',1],'kya':'きゃ','kyi':'きぃ','kyu':'きゅ','kye':'きぇ','kyo':'きょ','gya':'ぎゃ','gyi':'ぎぃ','gyu':'ぎゅ','gye':'ぎぇ','gyo':'ぎょ','sya':'しゃ','syi':'しぃ','syu':'しゅ','sye':'しぇ','syo':'しょ','sha':'しゃ','shi':'し','shu':'しゅ','she':'しぇ','sho':'しょ','zya':'じゃ','zyi':'じぃ','zyu':'じゅ','zye':'じぇ','zyo':'じょ','tya':'ちゃ','tyi':'ちぃ','tyu':'ちゅ','tye':'ちぇ','tyo':'ちょ','cha':'ちゃ','chi':'ち','chu':'ちゅ','che':'ちぇ','cho':'ちょ','dya':'ぢゃ','dyi':'ぢぃ','dyu':'ぢゅ','dye':'ぢぇ','dyo':'ぢょ','tha':'てゃ','thi':'てぃ','thu':'てゅ','the':'てぇ','tho':'てょ','dha':'でゃ','dhi':'でぃ','dhu':'でゅ','dhe':'でぇ','dho':'でょ','nya':'にゃ','nyi':'にぃ','nyu':'にゅ','nye':'にぇ','nyo':'にょ','jya':'じゃ','jyi':'じ','jyu':'じゅ','jye':'じぇ','jyo':'じょ','hya':'ひゃ','hyi':'ひぃ','hyu':'ひゅ','hye':'ひぇ','hyo':'ひょ','bya':'びゃ','byi':'びぃ','byu':'びゅ','bye':'びぇ','byo':'びょ','pya':'ぴゃ','pyi':'ぴぃ','pyu':'ぴゅ','pye':'ぴぇ','pyo':'ぴょ','fa':'ふぁ','fi':'ふぃ','fu':'ふ','fe':'ふぇ','fo':'ふぉ','mya':'みゃ','myi':'みぃ','myu':'みゅ','mye':'みぇ','myo':'みょ','rya':'りゃ','ryi':'りぃ','ryu':'りゅ','rye':'りぇ','ryo':'りょ','n\'':'ん','nn':'ん','n':'ん','a':'あ','i':'い','u':'う','e':'え','o':'お','xa':'ぁ','xi':'ぃ','xu':'ぅ','xe':'ぇ','xo':'ぉ','la':'ぁ','li':'ぃ','lu':'ぅ','le':'ぇ','lo':'ぉ','ka':'か','ki':'き','ku':'く','ke':'け','ko':'こ','ga':'が','gi':'ぎ','gu':'ぐ','ge':'げ','go':'ご','sa':'さ','si':'し','su':'す','se':'せ','so':'そ','za':'ざ','zi':'じ','zu':'ず','ze':'ぜ','zo':'ぞ','ja':'じゃ','ji':'じ','ju':'じゅ','je':'じぇ','jo':'じょ','ta':'た','ti':'ち','tu':'つ','tsu':'つ','te':'て','to':'と','da':'だ','di':'ぢ','du':'づ','de':'で','do':'ど','xtu':'っ','xtsu':'っ','na':'な','ni':'に','nu':'ぬ','ne':'ね','no':'の','ha':'は','hi':'ひ','hu':'ふ','fu':'ふ','he':'へ','ho':'ほ','ba':'ば','bi':'び','bu':'ぶ','be':'べ','bo':'ぼ','pa':'ぱ','pi':'ぴ','pu':'ぷ','pe':'ぺ','po':'ぽ','ma':'ま','mi':'み','mu':'む','me':'め','mo':'も','xya':'ゃ','ya':'や','xyu':'ゅ','yu':'ゆ','xyo':'ょ','yo':'よ','ra':'ら','ri':'り','ru':'る','re':'れ','ro':'ろ','xwa':'ゎ','wa':'わ','wi':'うぃ','we':'うぇ','wo':'を'};
646 function ImeInitRecursive(w) {
647 var frames = w.frames;
648 for (var i = 0; i < frames.length; ++i) {
649 AjaxIME(frames[i].document);
650 ImeInitRecursive(frames[i].window);
654 ImeInitRecursive(window);
657 function ImeChangeMode() {
658 function ImeChangeModeRecursive(w) {
659 var frames = w.frames;
660 for (var i = 0; i < frames.length; ++i) {
661 frames[i].document.ImeChangeMode();
662 ImeChangeModeRecursive(frames[i].window);
665 document.ImeChangeMode();
666 ImeChangeModeRecursive(window);
669 function ImeRequestCallback(result) {
670 ImeCurrentDocument_.ImeRequestCallback(result);
673 addEvent(window, 'load', ImeInit);