This includes 3 features about the Find Toolbar.
The first feature is the "dictionary-assisted find" for Japanese (or other languages). This provides a feature to find Japanese terms in roman-letter spelling. For example, if you input "kanji", Firefox finds any terms of the sound, like "感じ", "幹事" and "漢字". See the demonstration video. Additionally, you can find modified latin letters with their simple versions. For example, "Frédéric" can be found by the input "frederic". Or, if you want and you switch the find mode, you can do regular expression search for web contents.
Second is more customizable Find Toolbar. You can check "Highlight all" and "Match Cases" automatically. And, found term can be shown in the center of the screen.
Third, the highlight feature like Safari 3 is available. In "Highlight all" mode, the content area is covered by a dark screen and the focused term is shown with animation effect. Markers indicating where the search term is in the page will appear beside the scroll bar.
XUL/Migemo is available on:
*From 0.3.1 to 0.6.6, this project was called "XUL/Migemo [Forked Edition]" and it was developed separately from the original "XUL/Migemo" project. Now, 0.7.0 or later, this is approved as an official successor by the original author, so this is not a "[Forked Edition]" anymore. See project background too.
If you see any problem, see FAQ at first. If there is no solution, post a report to the issue tracker on the GitHub please.
You should try to input a Japanese term in roman characters after "/" key, like "/nihongo". Then, the find toolbar automatically appears and the term "日本語" will be found. This is "Migemo find." By the "Migemo find", you can find a Japanese term in roman-letter spelling.
And, like this, you can start Migemo find by just type "/" key. This is "Quick Migemo Find. mode".
When multiple terms found for the roman-letter spelling, Firefox recognizes all of them. For example, the input "kanji" founds "漢字", "感じ", "幹事", "かんじ" and "カンジ".
If an input field is focused, you cannot start Quick Migemo Find by "/" key. So, you can use "Ctrl-Shift-F" instead of "/".
You'll see a progressive bar on the right edge of the find toolbar, while finding Japanese terms. It indicates the remaining time of timeout. When the bar become zero, Firefox exit Quick Migemo Find mode and back to the normal browsing automatically.
You can exit Quick Migemo Find mode manually by "ESC" key.
Input multiple terms in roman-letter spelling, split by spaces like "nihongo deno pe-zi nai kensaku". A long sentence, "日本語でのページ内検索" will be found. You can find sentences by input split by spaces.
Another way, XUL/Migemo recognize SKK style input. An input "nihongoDenoPe-ziNaiKensaku", split by caps will work like above.
When you are in normal find mode, started by "Ctrl-F", you can switch to Migemo find as you like. Click the "Migemo" button rightmost of the find toolbar. To back to the normal find mode, click it again or click "Normal".
Moreover, without mouse operations, you can switch the find mode only with pressing "Ctrl-F" shortcut while you are doing find.
In Migemo mode, you can find Japanese terms which are in the system dictionary. Unregistered terms cannot be found.
To make Firefox to be able to find more and more terms, you can add terms to the user-dictionary. To go to the Dictionary Manager, press "Ctrl-Shift-F7" or click the "Manage Dictionary" button in the configuration panel.
With Version 0.8.0 or later, you cau do regular expression search as you like. Click "RegExp" button on the right edge of the find bar, then regular expression becomes available in the find toolbar.
Moreover, you can start regular expression search dynamically even if you doing normal search. Please type regular expressions with slashes, like "/reg(ular )?exp(ressions)?/", then it is automatically parsed as a regular expression.
On Firefox 3, by default, Migemo Find is available on the Smart Location Bar, search boxes in the History and Bookmarks sidebars, and the Library. If you want it is disabled on these places, you'll go to XUL/Migemo configuration and turn them off.
On Thunderbird 2, Migemo Find is available on the Quick Find of the thread pane except "Body" find. If you want it is available for "Body" find, go to XUL/Migemo configuration and turn it on.
XUL/Migemo Service generates regular expressions (regexp) from simple key inputs. Content of generated regexps are depend on the "engine". By default, XUL/Migemo includes two engines: Japanese and English. Japanese engine generates regexps to find Japanese words from roman letters. English engine generates regexps including lists of English terms which are starts from the input.
You can call XUL/Migemo functions via an global object migemo
in the JavaScript namespace. migemo
object is public for not only other addons, but web applications also.
migemo
object uses the default engine which is choosen in the initializing dialog. Following methods and properties are available:
migemo.provider
migemo.version
migemo.lang
migemo.query()
migemo.queries()
migemo.queryFunctional()
migemo.queriesFunctional()
migemo.provider
"XUL/Migemo 0.12.0 (ja)"
will be returned if you use XUL/Migemo version 0.12.0 with Japanese engine.migemo.version
"0.12.0"
will be returned if you use XUL/Migemo version 0.12.0.migemo.lang
"ja"
will be returned if you use XUL/Migemo with Japanese engine.migemo.query(in String aInput)
String
class, which checks the string matches to the input
or not?:
String.prototype.migemoMatches = function(input) {
return new RegExp(migemo.query(input), 'i').test(this);
};
alert('日本語'.migemoMatches('nihongo')) // => "true"
alert('英語'.migemoMatches('nihongo')) // => "false"
function getMatchedItems(list, input) {
var regexp = new RegExp(migemo.query(input));
return list.split('\n')
.filter(function(aTerm) {
return regexp.test(aTerm);
});
}
var list = <[CDATA[
コーヒー
紅茶
緑茶
水
]]>.toString();
alert(getMatchedItems(list, 'cha')); // => ["紅茶", "緑茶"]
migemo.queries(in String aInput)
String
class, which checks the string matches to all of input
or not?:
String.prototype.migemoMatchesAll = function(input) {
return migemo.queries(input)
.map(function(aSource) {
return new RegExp(aSource, 'i');
})
.every(function(aRegExp) {
return aRegExp.test(this);
}, this);
};
alert('日本語と英語'.migemoMatchesAll('nihongo eigo')) // => "true"
alert('日本語とフランス語'.migemoMatchesAll('nihongo eigo')) // => "false"
migemo.queryFunctional(in String aInput)
regexp
, terms
, and exceptions
.
retval.regexp
retval.terms
retval.exceptions
target
array:
var target = [
'日本で英語を話す',
'英語を日本で話す',
'日本語fooooo!!',
'日本語hooooo!!'
];
var input = 'nihon go -foo';
var result = migemo.queryFunctional(input);
var regexp = new RegExp(result.regexp, 'i');
var terms = new RegExp(result.terms, 'gim');
var exceptions = result.exceptions ?
new RegExp(result.exceptions, 'gim') :
null ;
var matchedTerms = [];
var output = target.filter(function(aTarget) {
if (exceptions && exceptions.test(aTarget))
return false;
if (regexp.test(aTarget)) {
match = aTarget.match(terms);
matchedTerms = matchedTerms.concat(match);
return true;
}
});
alert(output.join('\n')+'\n---\n'+matchedTerms.join(', '));
// Result:
// 日本で英語を話す
// 英語を日本で話す
// 日本語hooooo!!
// ---
// 日本, 語, 語, 日本, 日本, 語
migemo.queriesFunctional(in String aInput, [in String aFlags])
"im"
regexps
, terms
, and exceptions
.
retval.regexps
retval.terms
retval.exceptions
target
array:
var target = [
'日本で英語を話す',
'英語を日本で話す',
'日本語fooooo!!',
'日本語hooooo!!'
];
var input = 'nihon go -foo';
var result = migemo.queriesFunctional(input);
var regexps = result.regexps.map(function(aSource) {
return new RegExp(aSource, 'i');
});
var terms = new RegExp(result.terms, 'gim');
var exceptions = result.exceptions ?
new RegExp(result.exceptions, 'gim') :
null ;
var matchedTerms = [];
var output = target.filter(function(aTarget) {
if (exceptions && exceptions.test(aTarget))
return false;
if (regexps.every(function(aRegExp) {
return aRegExp.test(aTarget);
})) {
match = aTarget.match(terms);
matchedTerms = matchedTerms.concat(match);
return true;
}
});
alert(output.join('\n')+'\n---\n'+matchedTerms.join(', '));
// Result:
// 日本で英語を話す
// 英語を日本で話す
// 日本語hooooo!!
// ---
// 日本, 語, 語, 日本, 日本, 語
Moreover, priviledged scripts (addons, etc.) can call following extra methods. They returns JavaScript RegExp objects directly.
migemo.getRegExp(in String aInput, [in String aFlags])
"im"
String
class, which checks the string matches to the input
or not?:
String.prototype.migemoMatches = function(input) {
return migemo.getRegExp(input, 'i').test(this);
};
alert('日本語'.migemoMatches('nihongo')) // => "true"
alert('英語'.migemoMatches('nihongo')) // => "false"
function getMatchedItems(list, input) {
var regexp = migemo.getRegExp(input);
return list.split('\n')
.filter(function(aTerm) {
return regexp.test(aTerm);
});
}
var list = <[CDATA[
コーヒー
紅茶
緑茶
水
]]>.toString();
alert(getMatchedItems(list, 'cha')); // => ["紅茶", "緑茶"]
migemo.getRegExps(in String aInput, [in String aFlags])
"im"
String
class, which checks the string matches to all of input
or not?:
String.prototype.migemoMatchesAll = function(input) {
return migemo.getRegExps(input, 'i')
.every(function(aRegExp) {
return aRegExp.test(this);
}, this);
};
alert('日本語と英語'.migemoMatchesAll('nihongo eigo')) // => "true"
alert('日本語とフランス語'.migemoMatchesAll('nihongo eigo')) // => "false"
migemo.getRegExpFunctional(in String aInput, [in String aFlags])
"im"
regexp
, terms
, and exceptions
.
retval.regexp
retval.terms
retval.exceptions
target
array:
var target = [
'日本で英語を話す',
'英語を日本で話す',
'日本語fooooo!!',
'日本語hooooo!!'
];
var input = 'nihon go -foo';
var result = migemo.getRegExpFunctional(input, 'i');
var matchedTerms = [];
var output = target.filter(function(aTarget) {
if (result.exceptions &&
result.exceptions.test(aTarget))
return false;
if (result.regexp.test(aTarget)) {
match = aTarget.match(result.terms);
matchedTerms = matchedTerms.concat(match);
return true;
}
});
alert(output.join('\n')+'\n---\n'+matchedTerms.join(', '));
// Result:
// 日本で英語を話す
// 英語を日本で話す
// 日本語hooooo!!
// ---
// 日本, 語, 語, 日本, 日本, 語
migemo.getRegExpsFunctional(in String aInput, [in String aFlags])
"im"
regexps
, terms
, and exceptions
.
retval.regexps
retval.terms
retval.exceptions
target
array:
var target = [
'日本で英語を話す',
'英語を日本で話す',
'日本語fooooo!!',
'日本語hooooo!!'
];
var input = 'nihon go -foo';
var result = migemo.getRegExpsFunctional(input, 'i');
var matchedTerms = [];
var output = target.filter(function(aTarget) {
if (output.exceptions &&
output.exceptions.test(aTarget))
return false;
if (output.regexps.every(function(aRegExp) {
return aRegExp.test(aTarget);
})) {
match = aTarget.match(output.terms);
matchedTerms = matchedTerms.concat(match);
return true;
}
});
alert(output.join('\n')+'\n---\n'+matchedTerms.join(', '));
// Result:
// 日本で英語を話す
// 英語を日本で話す
// 日本語hooooo!!
// ---
// 日本, 語, 語, 日本, 日本, 語
You can use custom dictionary for the dictionary-assisted find feature of XUL/Migemo.
The format of custom dictionaries is a list of terms, which is split by TAB(\t)s and line-break(\n)s. For example, English dictionary is:
2 to too two
4 for
AA
AAA
Aachen
aardvark
Aaren
Aarhus
Aarika
Aaron
AB
aback
abacus
abaft
Abagael
Abagail
...
The term which is in the start of each line will be found by dictionary-assisted find. For example, Input "A" will finds "AA", "AAA", "Aachen", "aardvark", "Aaren", etc. And, if you put multiple terms in a line with TAB(\t)s, second and following terms are found for the first term of the line. For example, "2" will finds "to", "too" and "two".
Save the list as "lang-name.txt" (like "en-US.txt") into the dictionary folder, encoding UTF-8. And, set the name of the language to a string preference xulmigemo.lang
. XUL/Migemo will use the dictionary for its find.
Set the download URI to the preference xulmigemo.dictionary.download.uri.the name of the language supported by your engine
. The dictionary file is a ZIP archive, and which includes dictionary files without any folder. XUL/Migemo will downloads it and decompresses automatically.
If you wish to translate inputs, like Japanese (roman-letter inputs to hiragana and katakana), you have to create a custom engine.
You have to implement the engine which has xmIXMigemo interface, and the dictionary which has xmIXMigemoDictionary interface, if you want to add a new engine for another language.
Fast steps to create custom engines is:
lang
property in xmXMigemoEngineMyLang.js and xmXMigemoDictionaryMyLang.js, to your favorite language. For example, MyLang
and so on.classID
property in xmXMigemoEngineMyLang.js and xmXMigemoDictionaryMyLang.js. New UUIDs can be generated by the UUID Generator on the Web or other ways.MyLang
and so on.After all, XUL/Migemo uses the custom engine you implemented.
You have to name the contract ID of the component like as @piro.sakura.ne.jp/xmigemo/engine;1?lang=langage name
when you implement a new engine. For example, the language name of the Japanese engine is ja
. You have to implement following methods and properties:
lang
ja
, en-US
, and so on.getRegExpFor(in String aInput)
var regexp = new RegExp(XMigemoCore.getRegExp('romaji'), 'ig');
gatherEntriesFor(in String aInput, in unsigned short aTargetDictionaryType)
xmIXMigemoEngine.SYSTEM_DIC
: System dictionaryxmIXMigemoEngine.USER_DIC
: User dictionary (contains terms added by the user)xmIXMigemoEngine.ALL_DIC
: Both dictionariessplitInput(in String aInput)
textTransform
Cc['@piro.sakura.ne.jp/xmigemo/text-transform;1?lang=*'].getService(Ci.xmIXMigemoTextTransform)
, which is used by English engine) or a custom service you implemented (Japanese engine has it).dictionary
By the way, xmIXMigemo interface is an extended version of xmIXMigemoEngine.
xmIXMigemoTextTransform interface provides features to format text for the dictionary or the engine.
isValidInput(in String aInput)
normalizeInput(in String aInput)
normalizeKeyInput(in String aInput)
addLatinModifiers(in String aInput)
removeLatinModifiers(in String aInput)
The custom service for Japanese language (xmIXMigemoTextTransformJa) includes some extra features to transform text from roman characters to hiragana, hiragana to roman, hiragana to katakana, and others.
xmIXMigemoDictionary interface provides features to read/write the dictionary for the engine.
getDic()
getUserDic()
saveUserDic()
addTerm(in String aInput, in String aTerm)
xmIXMigemoDictionary.RESULT_OK
: correctly registeredxmIXMigemoDictionary.RESULT_ERROR_INVALID_INPUT
: the input includes invalid characterxmIXMigemoDictionary.RESULT_ERROR_ALREADY_EXIST
: the set of input and term has been already registered.xmIXMigemoDictionary.RESULT_ERROR_NO_TARGET
: no term is specifiedxmIXMigemoDictionary.RESULT_ERROR_INVALID_OPERATION
: other errorsremoveTerm(in String aInput, in String aTerm)
xmIXMigemoDictionary.RESULT_OK
: correctly unregisteredxmIXMigemoDictionary.RESULT_ERROR_INVALID_INPUT
: the input includes invalid characterxmIXMigemoDictionary.RESULT_ERROR_ALREADY_EXIST
: the set of input and term has been already unregistered.xmIXMigemoDictionary.RESULT_ERROR_NO_TARGET
: no term is specifiedxmIXMigemoDictionary.RESULT_ERROR_INVALID_OPERATION
: other errorsload()
reload()
initialized
Set the name of the language to the preference xulmigemo.lang
. XUL/Migemo uses the engine automatically.
Set the download URI to the preference xulmigemo.dictionary.download.uri.the name of the language supported by your engine
. The dictionary file is a ZIP archive, and which includes dictionary files without any folder. xmIXMigemoDicManager will downloads it and decompresses automatically.
Firefox includes a cool feature "Find As You Type" which provides incremental search in webpages. But the feature doesn't convenient for Japanese pages, because webpages written in Japanese require to input searching terms via IME(Input Method Editor)s, and FAYT feature cannot do incremental search via IME.
The original version of XUL/Migemo, made by a cool hacker "plus7", was the solution. Migemo (written in Ruby) is a helper tool for Emacs which provides incremental search feature for Japanese language without IME. He implement the Migemo by XUL and JavaScript, based on the beavior of fub_net (which uses the library C/Migemo).
The [Forked Edition] distributed in this page, was a modified and corrected version of the original XUL/Migemo 0.3.0. In some reasons, he stopped developing the original XUL/Migemo so I decided to support future versions of Firefox by forking it.
I thought this forking is just a temporary project. When a new version of the original (which includes patches for those problems) appeared, this contents were deleted, or finished its own work. But my work on this fork made it incompatible to the original one, so, this project was not temporary.
Now, this project is approved by plus7 as the official successor.
See the page of the original XUL/Migemo to find out documentations of its history and implementation.
return
statement.t-
can appear in input text as an alternative of modified Ε§
, but it seems not to appear in webpages. So now t-
and similar patterns are not matched to regular input like t
.xulmigemo.highlight.foundMarker.smoothScroll.enabled
to false
.)xulmigemo.highlight.foundMarker.smoothScroll.enabled
to false
.)browser.urlbar.autoFill
works correctly for the smart location bar with XUL/Migemo.