Opera Nalakuvara, customized Taiwanese browser — Part 3: Third party components and menus

By Jedi Lin

Introduction

In the previous parts in the series, we discussed initial planning and customizing the installation procedure, and tweaking Opera's default settings. This is great, and these parts of the procedure have already provided a great number of useful customizations.

But there are some things Opera can't do by itself. As mentioned in the Guidelines section in Part 1, we have no choice but to use third party components to achieve some functions. The components I used within Nalakuvara are as follows:

  • User CSS (user stylesheets): Put in OPERA_INSTALL_PATH\styles\user\ by default
  • User JavaScript (UserJS): Disabled by default
  • Plug-Ins: Put in OPERA_INSTALL_PATH\program\plugins\ by default
  • Java Applet: Requires Java Runtime Environment

In this article, I will show how these components were used in Nalakuvara. The contents are as follows:

User CSS

Opera has already achieved some leading support CSS-related features, such as Fit to Width, and support for all the CSS3 selectors. Opera@USB includes some handy advertisement blocking functions purely via CSS.

User CSS can be enabled and disabled on demand via the Opera View menu, or through adding a button to do it into your toolbars. Adding custom buttons to enable/disable user CSS however is quite difficult. Opera's internal command "Select user CSS file" targets a particular CSS file by its order in the User CSS path. In order to make custom buttons that apply User CSS on, we have to manipulate the CSS file order in the path.

On Windows, files are arranged by filename. In Nalakuvara I have taken CSS files from Opera@USB and renamed them with low numbers at the start (eg 000_Antiflash.css and 000_bantiad.css) to make sure they are the first two files. On Linux or FreeBSD, however, it doesn't work that way, so sadly these buttons work only on Windows. I will talk about these buttons later, in the "Altering Menus and Toolbars" section.

My 000_Antiflash.css stylesheet blocks all Flash content in a web page:

@charset "UTF-8";
/*
Name: Flash Blocker
Version: 1 08.2005
Beschreibung: Flash und Shockwave Blocker Version 12.06
*/

object[classid="clsid:D27CDB6E-aE6D-11cf-96B8-444553540000"],
object[classid="clsid:166B1BCA-3F9C-11CF-8075-444553540000"],
object[type="application/x-shockwave-flash"],
embed[type="application/x-shockwave-flash"],
embed[type="application/x-director"],
embed[quality]
embed[src$=".swf"]
{display: none !important;}

000_bantiad.css blocks particular image sizes from appearing on a web page:

@charset "UTF-8";
/*
Name: Grafik Blocker
Version: 1
Beschreibung: Grafik Blocker
*/

[height="60"][width="468"], [height="60px"][width="468px"],
[height="31"][width="88"], [height="31px"][width="88px"],
[height="336"][width="280"], [height="336px"][width="280px"],
[height="300"][width="250"], [height="300px"][width="250px"],
[height="250"][width="250"], [height="250px"][width="250px"],
[height="400"][width="240"], [height="400px"][width="240px"],
[height="120"][width="240"], [height="120px"][width="240px"],
[height="60"][width="234"], [height="60px"][width="234px"],
[height="150"][width="180"], [height="150px"][width="180px"],
[height="600"][width="160"], [height="600px"][width="160px"],
[height="125"][width="125"], [height="125px"][width="125px"],
[height="600"][width="120"], [height="600px"][width="120px"],
[height="90"][width="120"], [height="90px"][width="120px"],
[height="60"][width="120"], [height="60px"][width="120px"]
{display: none !important;}

This is an excellent demonstration of CSS attribution selectors.

User JavaScript

If you are customizing the Opera 10.50 Labs pre-alpha snapshot, you will find that the JavaScript is a bit unstable in part. Unfortunately this means that several of the Nalakuvara User JavaScript additions will not work. This will be fixed in later 10.5 releases.

User JavaScript allows us to add much more functionality, although because of compatibility and security concerns it is disabled by default. To enable the User JavaScript feature, you need to tweak the following preferences:

[User Prefs]
Feature opera:config Link Opera Default Nalakuvara Tweak
Enable User JavaScript opera:config#UserPrefs|UserJavaScript 0 1
Always load User JavaScript even on web pages without <script> opera:config#UserPrefs|AlwaysLoadUserJavaScript 0 1
Do not enable User JavaScript on HTTPS connection opera:config#UserPrefs|UserJavaScriptonHTTPS 0 0
Specify User JavaScript directory opera:config#UserPrefs|UserJavaScriptFile userjs

For example, the OPERA_INSTALL_PATH\custom\defaults\operaprefs.ini file on Windows should look like so:

Opera Preferences version 2.1
; Do not edit this file while Opera is running
; This file is stored in UTF-8 encoding

[User Prefs]
Enable Gesture=1
Enable Drag=255
Doubleclick to Close Tab=1
New Window=1
Open New Window in Background=1
Show panel toggle=1
User JavaScript=1
Always Load User JavaScript=1
User JavaScript on HTTPS=0
User JavaScript File=userjs

[Fonts]
Menu=12,4,0,0,0,0,新細明體
Toolbar=12,4,0,0,0,0,新細明體
Dialog=12,4,0,0,0,0,新細明體
Panel=12,4,0,0,0,0,新細明體
Tooltip=12,4,0,0,0,0,新細明體

[Network]
HTTP Accept Language=zh-tw,en;q=0.9
Check Local HostName=0
Enable HostName Expansion=0
Enable HostName Web Lookup=1
HostName Web Lookup Address=http://www.google.com/search?q=%s&sourceid=opera&num=%i&ie=utf-8&oe=utf-8

User JavaScript on HTTPS remains disabled for security concerns. If you have to enable this preference, please, think about it carefully, and warn users too.

User JavaScript File can be an absolute or relative path. It is wise to let users choose where to put their own user JavaScript files, However it is convenient to predefine a relative path here. The tricky part is that the working directory is different on Windows and Linux/FreeBSD. On Windows, Opera's working directory is where opera.exe is located, ie OPERA_INSTALL_PATH. On Linux and FreeBSD, Opera's working directory is user's home directory, i.e., ~. The User JavaScript File relative path is related to Opera's working directory, which means userjs is at OPERA_INSTALL_PATH\userjs\ on Windows, and ~/userjs/ on Linux or FreeBSD.

Nalakuvara chooses User JavaScript based on my guidelines carefully. Here is my final list:

Adblock Plus

The pure-JavaScript version of AdBlock Plus uses CSS attribute selectors and optional CSS3 nth-child selectors to target elements to block. All "blocker" CSS rules are stored in cookies. All AdBlock Plus functions can be accessed via Toolbar buttons (which will be discussed in the "Altering Menus and Toolbars" section) and hotkeys, which are as follows:

  • Alt-Shift-B: block web elements with CSS3 nth-child selector;
  • Alt-Shift-W: block web elements without CSS3 nth-child selector;
  • Alt-Shift-U: revert previous blocked web elements;
  • Alt-Shift-L: revert last blocked web elements;
  • Alt-Shift-E: edit blocker CSS rules manually.

Autosizer 2

Autosizer 2 lets users click on large images to resize them to fit within the browser window size, and click again to restore them to their original size. It also uses cookies to store this resize setting for each image.

Customize Google

CustomizeGoogle uses a separate customizegoogle_prefs.js file to adjust its behavior. Here are the predefined options in Nalakuvara:

Google Web Search /* webtab */
Options Description Nalakuvara's predefined value
web.remove-ads Remove advertisements true
web.search-links Add links from other search engines false
web.suggest Enable Google suggest true
web.focus Set input focus at search field false
web.counter Add counter on search results true
web.filter Enable filter rules false
web.history Add links to waybackmachine.org true
web.removeclicktrack Remove Google's click track true
web.auto-page Display Next search results continuous false
web.favicons Display favicons of search results true
Google Images Search /* imagestab */
Options Description Nalakuvara's predefined value
images.image-links Add links from other images search engines false
images.rewrite-links Rewrite links of original images and web pages true
images.auto-page Display next search results continuously false
Google Groups /* groupstab */
Options Description Nalakuvara's predefined value
groups.remove-ads Remove advertisements true
Google News /* newstab */
Options Description Nalakuvara's predefined value
news.news-links Add Links from other news search engines false
news.filter Enable filter rules false
news.removeclicktrack Remove Google's click track true
Google Products Search /* froogletab */
Options Description Nalakuvara's predefined value
froogle.remove-ads Remove advertisements true
froogle.products-links Add links from other products search engines false
Google Answers /* answerstab */
Options Description Nalakuvara's predefined value
answers.remove-ads Remove advertisements true
Google print /* printtab */
Options Description Nalakuvara's predefined value
print.remove-ads Remove advertisements true
print.restore-menu Restore right-click menu true
print.book-links Add links from other book sites false
GMail /* gmailtab */
Options Description Nalakuvara's predefined value
gmail.remove-ads Remove advertisements true
gmail.secure Secure mode (switch to https:// connection) true
gmail.hidespam Hide spam-counter false
gmail.hidechat Hide "Quick contacts box" false
gmail.hideinvite Hide "invite box" true
gmail.monospace Display mail content using monospace font false
Google Calendar /* calendartab */
Options Description Nalakuvara's predefined value
calendar.secure Secure mode (switch to https:// connection) true
Google Local /* localtab */
Options Description Nalakuvara's predefined value
local.remove-ads Remove advertisements true
Google Docs & Spreadsheets /* docstab */
Options Description Nalakuvara's predefined value
docs.secure Secure mode (switch to https:// Connection) true
Google Videos Search /* videotab */
Options Description Nalakuvara's predefined value
video.video-links Add links from other videos search engines false
Google Reader /* readertab */
Options Description Nalakuvara's predefined value
reader.secure Secure Mode (Switch to https:// Connection) true
Google Cache /* cachetab */
Options Description Nalakuvara's predefined value
cache.continue Rewrite links to Google cache true
Google Blog Search /* blogtab */
Options Description Nalakuvara's predefined value
blogs.blog-links Add links from other blogs' search engines false
blogs.removeclicktrack Remove Google's click track true
Google Web History /* historytab */
Options Description Nalakuvara's predefined value
history.secure Secure Mode (Switch to https:// Connection) true
Privacy /* privacytab */
Options Description Nalakuvara's predefined value
misc.anonymizeUID Anonymous Google cookie UID false
misc.removeGoogleAnalytics Remove google analytics true
Preferences /* Preferencestab */ (cookies.enableDefaultPreferences has to be true to take effect)
Options Description Nalakuvara's predefined value
cookies.enableDefaultPreferences Predefine Google preferences false
cookies.enableInterfaceLanguage Specify interface language false
cookies.interfaceLanguage Interface language (cookies.enableInterfaceLanguage has to be true to take effect) zh-TW
cookies.enableSearchLanguage Specify search language false
cookies.searchAnyOrSelected Search any language or only selected languages (cookies.enableSearchLanguage has to be true to take effect) all
cookies.searchLanguage Specify Languages to Search (cookies.searchAnyOrSelected has to be selected to take effect) lang_zh-TW
cookies.enableSafeSearch Enable safeSearch false
cookies.SafeSearch SafeSearch option (cookies.enableSafeSearch has to be true to take effect)
  • 1: Strict - filter images and language
  • "empty": Default - filter images only
  • 4: None - do not filter at all
4
cookies.enableResultsPerPage Specify results per page false
cookies.ResultsPerPage Results per page (cookies.enableResultsPerPage has to be true to take effect) 10
cookies.enableResultsWindow Specify results window false
cookies.OpenSearchResultsInNewWindow Open search results in new window (cookies.enableResultsWindow has to be true to take effect) false
Filter /* filtertab */
Options Description Nalakuvara's predefined value
misc.filterlist Filter rules

Nalakuvara prompts users to change these values upon installation.

HanConvert

HanConvert is not a mature solution yet — it can't translate between Traditional Chinese and Simplified Chinese yet. It can however do character-level conversion between these two languages. The next step in the future will be improving it to phrase level conversion, and later on perhaps, full translation.

HanConvert can be accessed via Toolbar buttons, which will be discussed later, in the "Altering Menus and Toolbars" section. There is also another User JavaScript file that enables language conversion automatically for all web pages; this is undesirable as it doesn't go along with Opera's clean nature.

HTML Ruby

Opera follows W3C web standards in general, although it fails on W3C Ruby annotation. HTML Ruby fills this gap via JavaScript and CSS — it comes with a separate ruby.settings.js file to adjust its behaviour:

HtmlRubySettings (OPTION: VALUE,)
Options Description Nalakuvara's predefined value
rubyTextSize The size of ruby text (The size of Ruby Base is '1em') '.55em'
maxPageLength Maximum page length to force closing tags (to prevent slowing down)
  • 0: Do not close tags at all
  • -1: Always close tags
-1
spaceRubyText Space Ruby text as tight as possible true
showNotice Show notice via opera.postError false
processDynamicContent Process dynamic content false

Nalakuvara prompts users to change these values upon installation.

Open in Background with Long Press

Open in Background with Long Press is for those who do not use mouse gestures but want similar functionality, and it works only on actual <a> links. Sadly, some users reported that this User JavaScript slows down web games on Facebook. Nalakuvara highlights this issue to users before installing it, so that if the user is unhappy with this side effect, they can choose not to install the User Javacript.

Textarea Backup

Textarea Backup is a Greasemonkey User JavaScript, and therefore needs Emulate GM functions to work in Opera. There is one variable in its textareabackup.js:

textareabackup.js (var OPTION = VALUE;)
Options Description Nalakuvara's predefined value
shelfLife The duration that backups should be stored for, in seconds. 3600

Again, Nalakuvara prompts users to change these values upon installation.

Remember: If the User JavaScripts above are installed, you can enable and tweak their preferences in operaprefs.ini.

Plugin

There is only one plugin used in Nalakuvara, and it is only available on Windows: npviewinie. This provides the functionality of the "IE Tab", rendering web pages using IE's trident engine without leaving Opera, (this is analogous to the Firefox "IE Tab" extension).

The core of npviewinie is a npviewinie.dll, which was placed in OPERA_INSTALL_PATH\program\plugins\ or anywhere listed in the opera:config#UserPrefs|PluginPath preference. I then embedded an npviewinie object using an <embed> tag with an type="application/viewinie" attribute. This, too, could be performed via a Toolbar button, which will be discussed later, in the "Altering Menus and Toolbars" section. There is also a seperate Autorender.in.IE.js to load listed web pages with the npviewinie object automatically. This Autorender.in.IE.js should be in the User JavaScript path, with related preferences enabled to take effect.

npviewinie might not be usable in Windows Vista and Windows 7 due to Data Execution Prevention (DEP). The workaround is to turn DEP off with the following command line entry:

bcdedit /set nx alwaysoff

Users have to reboot their system for this to take effect. With DEP disabled, other security issues might be raised too, so this is by no means a foolproof solution. This information is revealed to users, too.

If you are customizing the Opera 10.50 Labs pre-alpha snapshot, you'll find that due to unstable JavaScript (as mentioned earlier), these npviewinie buttons will not work properly. This will be fixed in later 10.5 releases.

Java Applets

If you are customizing the Opera 10.50 Labs pre-alpha snapshot, you'll find that this doesn't work, as the build does not have Java support included.

Java Applets, on the other hand, provide a cross-platformed solution, which might be slower but works just fine. If users do not have a JRE installed beforehand, Opera can prompt them to install JRE at the first run of any Java Applet. On some platforms users have to install JRE through the system's package management system. On Ubuntu, for example, one has to install the sun-java6-bin package via the Synaptic Package Manager to make Java Applet work.

Nalakuvara uses the ZTerm Applet (URL no longer active) to handle telnet:// and ssh:// protocols, which are necessary for telnet-based BBS. There are two different ways to include this third party component into Nalakuvara: install files locally, or use the applet page provided by the ZTerm Applet project. Either way, the ZTerm Applet stores its preferences in a .ztermrc file. This file is located at %USERPROFILE% on Windows, and at ~ on Linux/FreeBSD.

The applet page provided by the ZTerm Applet project was no longer provide applet service due to policy issue. However, the ZTerm Applet files are still available. You could upload them to somewhere else to use remotely.

By default, the ZTerm Applet uses IE as an external browser on Windows, and Firefox on Linux/FreetdBtdSD. You can predefine it to Opera by editing .ztermrc:

external-browser-command::opera %u

On Linux, you can tweak ZTerm Applet more to make it look better:

external-browser-command::opera %u
font.antialias::true
font.family::AR PL UMing TW MBE
font.vertical-gap::1
locale.language::en
use-system-look-and-feel::true

On Ubuntu, again, there is 文泉驛等寬正黑 font for better look:

external-browser-command::opera %u
font.antialias::true
font.family::文泉驛等寬正黑
font.vertical-gap::1
locale.language::en
use-system-look-and-feel::true

The applet page (local or remote) can be accessed via bookmarks, bookmarklets or toolbar buttons. I prefer using toolbar buttons; we will talk about this in the next section.

With 3rd party components installed, there should be a ways to conveniently access them. Toolbar buttons are one of the best practical ways. New features (buttons) could be hidden by default, preserving Opera's default UI layout; users can also remove unwanted features, and revert them back easily.

Customized Toolbar buttons are stored in the [Customize Toolbar Custom.content] section of standard_toolbar.ini:

[Customize Toolbar Custom.content]
Button0, "訂閱源料"="Go to page, "javascript:void(function (){subscriptions = [];linksList = document.getElementsByTagName('link');for ( i = 0; i < linksList.length; i++ ){ type = linksList[i].type;if ( type == 'application/rss+xml' || type == 'application/atom+xml' || type == 'application/rdf+xml' ){ subscriptions.push( { 'title':linksList[i].title, 'href':linksList[i].href } );}}if ( subscriptions.length == 0 ) return;str = '你要訂閱哪個源料?請輸入編號\n';for ( i = 0; i < subscriptions.length; i++ ){str += i + ': ' + subscriptions[i].title + '\n';}str = str.substr( 0, str.length - 1 );ret = prompt( str );if ( ret < 0 || ret >= subscriptions.length ) return;document.location.href = 'feed://' + subscriptions[ret].href;})()", 1, "以桌面軟體訂閱 feed: 協定的源料", "RSS""
Button1, "Flash Blocker"="Select user CSS file, 0, , "Flash Blocker 啟用中", "Transfer Loading" > Deselect user CSS file, 0, , "Flash Blocker 已停用", "Transfer Failure""
Button2, "Grafik Blocker"="Select user CSS file, 1, , "Grafik Blocker 啟用中", "Transfer Loading" > Deselect user CSS file, 1, , "Grafik Blocker 已停用", "Transfer Failure""
Button3, "依據 nth-child 結構阻擋網頁元素"="Go to page, "javascript:navigator.ujs_adblock.block()", , "依據 nth-child 結構阻擋網頁元素", "Delete""
Button4, "阻擋網頁元素"="Go to page, "javascript:navigator.ujs_adblock.block(true)", , "阻擋網頁元素", "Delete""
Button5, "還原被擋掉的網頁元素"="Go to page, "javascript:navigator.ujs_adblock.unblock()", , "還原被擋掉的網頁元素", "Mail Redirected""
Button6, "還原前一個擋掉的網頁元素"="Go to page, "javascript:navigator.ujs_adblock.unblock(true)", , "還原前一個擋掉的網頁元素", "Mail Redirected""
Button7, "手動輸入要擋掉的 CSS 選擇符"="Go to page, "javascript:navigator.ujs_adblock.edit()", , "手動輸入要擋掉的 CSS 選擇符", "Window Mail Compose Icon""
Button8, "View in IE Tab"="Go to page, "javascript:(function () { if( !location.href || location.href.match(/^(javascript|about|opera):/i) ) { return; } var w = window.open(); w.document.write('<html><head><title>' + (document.title?document.title:location.href).replace(/</,'&lt;') + ' - view in ie<\/title><\/head><body><div style=\'position:absolute;top:0;left:0;right:0;bottom:0;\'><embed type=\'application\/viewinie\' width=\'100'+String.fromCharCode(37)+'\' height=\'100'+String.fromCharCode(37)+'\' param-location=\'' + window.location.href + '\'><\/embed><\/div><\/body><\/html>'); })();", , "View in IE", "View""
Button9, "View in IE Same Tab"="Go to page, "javascript:(function () { if( !location.href || location.href.match(/^(javascript|about|opera):/i) ) { return; } document.write('<html><head><title>' + (document.title?document.title:location.href).replace(/</,'&lt;') + ' - view in ie<\/title><\/head><body><div style=\'position:absolute;top:0;left:0;right:0;bottom:0;\'><embed type=\'application\/viewinie\' width=\'100'+String.fromCharCode(37)+'\' height=\'100'+String.fromCharCode(37)+'\' param-location=\'' + window.location.href + '\'><\/embed><\/div><\/body><\/html>'); })();", , "View in IE Same Tab", "View""
Button10, "繁"="Go to page, "javascript:void(document.body.innerHTML=document.body.innerHTML.s2t());", , "繁", "A""
Button11, "简"="Go to page, "javascript:void(document.body.innerHTML=document.body.innerHTML.t2s());", , "简", "A""
Button12, "BBS"="Go to page, "file://localhost/C:/ZTerm/ZTermApplet.html", , "BBS", "A""
Button13, "Google 即時小字典"="Go to page, "javascript:function translate(word) { var glf = document.getElementById('glf'); glf.contentWindow.gtrans(word); }; function findAndReplace(searchText, replacement, searchNode) { var regex = typeof searchText === 'string' ? new RegExp(searchText, 'g') : searchText, childNodes = (searchNode || document.body).childNodes, cnLength = childNodes.length, excludes = 'html,head,style,title,link,meta,script,object,textarea,iframe'; while (cnLength--) { var currentNode = childNodes[cnLength]; if (currentNode.nodeType === 1 && (excludes + ',').indexOf(currentNode.nodeName.toLowerCase() + ',') === -1) { arguments.callee(searchText, replacement, currentNode); } if (currentNode.nodeType !== 3 || !regex.test(currentNode.data) ) { continue; } var parent = currentNode.parentNode, frag = ( function(){ var html = currentNode.data.replace(regex, replacement), wrap = document.createElement('div'), frag = document.createDocumentFragment(); wrap.innerHTML = html; while (wrap.firstChild) { frag.appendChild(wrap.firstChild); } return frag; } )(); parent.insertBefore(frag, currentNode); parent.removeChild(currentNode); } }; function inject(){ findAndReplace('\\b[^ ]+\\b', function(term){ return '<span onmouseover=\'translate(this)\'>' + term + '</span>'; }); }; function init() { var glf = document.createElement('iframe'); glf.id = 'glf'; glf.width=0; glf.height=0; glf.frameborder=0; glf.style.borderWidth='0'; glf.style.borderStyle='none'; glf.style.position='fixed'; glf.style.top='10px'; glf.style.right='10px'; document.body.appendChild(glf); var doc = glf.contentDocument; doc.open(); doc.write('<head><title>Sample html</title><script type=\'text/javascript\' src=\'http://www.google.com/jsapi\'></script><script type=\'text/javascript\'>google.load(\'language\', \'1\');function gtrans(word) {if(word.title) return; word.title = \'translating...\'; var text = word.innerHTML; google.language.detect(text, function(result) { if (!result.error && result.language) { google.language.translate(text, result.language, \'zh-tw\', function(result) {if (result.translation) { word.title = text + \': \' + result.translation;}});}});};</script></head><body style=\'margin:0; background-color: transparent;\'><div id=\'branding\' style=\'width : 0px; height : 0px; text-align: left;\'></div></body>'); doc.close(); inject(); }; init();", , "Google 即時小字典", "Window Chat Room Icon""
Button14, "搜尋已選詞"="Hotclick search, , , "搜尋已選詞", "Search Web""
Button15, "站內搜尋"="Go to page, "javascript:var t=window.location.hostname;var s=prompt('Google site search - enter search string:','');if(s){if(s.match(/^d%5cs.+/)){s=s.substring(2,s.length);t=t.match(/%5b^%5c.%5d+%5c.%5cw{2,4}$/)+''};void(location.href='http://www.google.com/search?q=site:'+t+'+'+s+'&sourceid=opera')}", 1, "站內搜尋", "Search Web""

All customized buttons stored here will show up in the "My buttons" toolbar. The a potential problem here is that users might install different third party components, and one standard_toolbar.ini might not be able to fit them all. During the installation/patch process, Nalakuvara copies one of sixteen predefined standard_toolbar.ini files to OPERA_INSTALL_PATH\ui\, according to the users' selection.

The modified standard_toolbar.ini is renamed to "Opera Nalakuvara Standard" to distinguish between it and the original one. What if it just doesn't show up? There is still a way forward — users could still install Nalakuvara's customized buttons from user documents, which will be discussed in Part 4 of the series.

Menus are a little tricky. Nalakuvara's guidelines state that there should be as little change as possible in menus. The only "must-have" is Opera's built-in dictionary function.

Dictionary and translation features

There seems to be a bug in the current Opera 10.50 Labs pre-alpha snapshot — the Hotclick menu does not work properly yet. This will be fixed in future 10.5 releases.

By default, the "Opera Standard" menu contains one Hotclick (right-click) search entry for Merriam-Webster Online Dictionary, one for English Wikipedia, and one set of translation functions using Yahoo! BabelFish which includes:

  • English to French
  • English to German
  • English to Italian
  • English to Portuguese
  • English to Spanish
  • French to English
  • French to German
  • French to Italian
  • French to Portuguese
  • French to Spanish
  • German to English
  • German to French
  • Italian to English
  • Italian to French
  • Portuguese to English
  • Spanish to English
  • Spanish to French
  • English to Japanese
  • Japanese to English

These are quite useful for American/European users, however for Taiwanese users they do not help much. There are some local popular web dictionary services in Taiwan, and Yahoo! BabelFish supports Traditional Chinese to/from English too. It was better to include these feature into Nalakuvara's Hotclick searches.

The goal is to expand the "Dictionary" and "Encyclopedia" entries into submenus (original Merriam-Webster Online Dictionary and English Wikipedia), and tweak "Translate" submenu to serve the needs of Taiwanese users:

  • Dictionary
    • Yahoo! Taiwan Dictionary
    • Merriam-Webster Online Dictionary
    • Taiwan National Language Composite Search
  • Encyclopedia
    • Chinese Wikipedia
    • English Wikipedia
    • Japanese Wikipedia
    • Uncyclopedia
  • Translate
    • English to Traditional Chinese
    • Traditional Chinese to English
    • Japanese to English
    • French to English
    • German to English
    • Italian to English
    • Portuguese to English
    • Spanish to English
    • English to Japanese
    • English to French
    • English to German
    • English to Italian
    • English to Portuguese
    • English to Spanish

This modification was achieved through three files:

  • LANGUAGE_CODE.lng, which changes menu text according to the specific UI language
  • search.ini, which defines actual Hotclick searches
  • standard_menu.ini, which defines the actual Hotclick menu

The default searches are predefined in the search.ini file. Just like bookmarks.adr of default bookmarks, search.ini can be locale-based. This makes more sense for we can tweak the above menu just for Taiwanese users, ie, those who use Traditional Chinese as their UI language.

Let's start with the Hotclick translate submenu. The [Translate menu] section of Nalakuvara's OPERA_INSTALL_PATH\ui\standard_menu.ini is as follows:

[Translate menu]
Item, MI_IDM_SELTRANSLATE_FR_DE	= Hotclick search, 107
Item, MI_IDM_SELTRANSLATE_FR_IT	= Hotclick search, 108
--------------------1
Item, MI_IDM_SELTRANSLATE_JA_EN	= Hotclick search, 119
Item, MI_IDM_SELTRANSLATE_FR_EN	= Hotclick search, 106
Item, MI_IDM_SELTRANSLATE_DE_EN	= Hotclick search, 111
Item, MI_IDM_SELTRANSLATE_IT_EN	= Hotclick search, 113
Item, MI_IDM_SELTRANSLATE_PT_EN	= Hotclick search, 115
Item, MI_IDM_SELTRANSLATE_ES_EN	= Hotclick search, 116
--------------------2
Item, MI_IDM_SELTRANSLATE_EN_JA	= Hotclick search, 118
Item, MI_IDM_SELTRANSLATE_EN_FR	= Hotclick search, 100
Item, MI_IDM_SELTRANSLATE_EN_DE	= Hotclick search, 101
Item, MI_IDM_SELTRANSLATE_EN_IT	= Hotclick search, 102
Item, MI_IDM_SELTRANSLATE_EN_PT	= Hotclick search, 103
Item, MI_IDM_SELTRANSLATE_EN_ES	= Hotclick search, 104

OPERA_INSTALL_PATH\locale\zh-tw\zh-tw.lng is also modified, to match this change:

1208490414="英文 > 法文(F)"
1208490335="英文 > 德文(G)"
1208490515="英文 > 義大利文(I)"
1208490746="英文 > 葡萄牙文(P)"
1208490382="英文 > 西班牙文(S)"
1209820046="法文 > 英文(2)"
1209820004="英文 > 繁體中文(T)"
1209820184="繁體中文 > 英文(E)"
1206981023="德文 > 英文(3)"
1213449683="義大利文 > 英文(4)"
1221751130="葡萄牙文 > 英文(5)"
1208670062="西班牙文 > 英文(6)"
1208490529="英文 > 日文(J)"
1213952801="日文 > 英文(1)"

And OPERA_INSTALL_PATH\locale\zh-tw\search.ini is changed, to modify the actual Hotclick search:

[Search Engine 7]
UNIQUEID=96D0060E5FC311DDBEA89A1656D89593
Name=
URL=http://redir.opera.com/translation/?text=%s&from=en&to=fr
ICON=http://babelfish.yahoo.com/favicon.ico
Query=
Key=
Is post=0
Has endseparator=0
Encoding=utf-8
Search Type=100
Verbtext=0
Position=-1
Nameid=291960

[Search Engine 8]
UNIQUEID=C1629A765FC311DDB2CB3F1956D89593
Name=
URL=http://redir.opera.com/translation/?text=%s&from=en&to=de
ICON=http://babelfish.yahoo.com/favicon.ico
Query=
Key=
Is post=0
Has endseparator=0
Encoding=utf-8
Search Type=101
Verbtext=0
Position=-1
Nameid=291960

[Search Engine 9]
UNIQUEID=EED3C7145FC311DD82E4CE1A56D89593
Name=
URL=http://redir.opera.com/translation/?text=%s&from=en&to=it
ICON=http://babelfish.yahoo.com/favicon.ico
Query=
Key=
Is post=0
Has endseparator=0
Encoding=utf-8
Search Type=102
Verbtext=0
Position=-1
Nameid=291960

[Search Engine 10]
UNIQUEID=14E03A145FC411DD97AE5E1C56D89593
Name=
URL=http://redir.opera.com/translation/?text=%s&from=en&to=pt
ICON=http://babelfish.yahoo.com/favicon.ico
Query=
Key=
Is post=0
Has endseparator=0
Encoding=utf-8
Search Type=103
Verbtext=0
Position=-1
Nameid=291960

[Search Engine 11]
UNIQUEID=090D0C025FC511DD88CAAB2856D89593
Name=
URL=http://redir.opera.com/translation/?text=%s&from=en&to=es
ICON=http://babelfish.yahoo.com/favicon.ico
Query=
Key=
Is post=0
Has endseparator=0
Encoding=utf-8
Verbtext=017063
Search Type=104
Position=-1
Nameid=291960

[Search Engine 12]
UNIQUEID=37F636385FC511DDA9FAC42A56D89593
Name=
URL=http://redir.opera.com/translation/?text=%s&from=fr&to=en
ICON=http://babelfish.yahoo.com/favicon.ico
Query=
Key=
Is post=0
Has endseparator=0
Encoding=utf-8
Search Type=106
Verbtext=0
Position=-1
Nameid=291960

[Search Engine 13]
UNIQUEID=6E70644A5FC511DD89AD0F2D56D89593
Name=
URL=http://redir.opera.com/translation/?text=%s&from=en&to=zt
ICON=http://babelfish.yahoo.com/favicon.ico
Query=
Key=
Is post=0
Has endseparator=0
Encoding=utf-8
Search Type=107
Verbtext=0
Position=-1
Nameid=291960

[Search Engine 14]
UNIQUEID=95C831945FC511DD952DE52E56D89593
Name=
URL=http://redir.opera.com/translation/?text=%s&from=zt&to=en
ICON=http://babelfish.yahoo.com/favicon.ico
Query=
Key=
Is post=0
Has endseparator=0
Encoding=AUTODETECT-ZH
Search Type=108
Verbtext=0
Position=-1
Nameid=291960

[Search Engine 17]
UNIQUEID=DF49D89E5FC611DD9581F43E56D89593
Name=
URL=http://redir.opera.com/translation/?text=%s&from=de&to=en
ICON=http://babelfish.yahoo.com/favicon.ico
Query=
Key=
Is post=0
Has endseparator=0
Encoding=utf-8
Search Type=111
Verbtext=0
Position=-1
Nameid=291960

[Search Engine 19]
UNIQUEID=88383F7C5FC711DDBC78BD4756D89593
Name=
URL=http://redir.opera.com/translation/?text=%s&from=it&to=en
ICON=http://babelfish.yahoo.com/favicon.ico
Query=
Key=
Is post=0
Has endseparator=0
Encoding=utf-8
Search Type=113
Verbtext=0
Position=-1
Nameid=291960

[Search Engine 21]
UNIQUEID=FF719C3C5FC711DD986F284E56D89593
Name=
URL=http://redir.opera.com/translation/?text=%s&from=pt&to=en
ICON=http://babelfish.yahoo.com/favicon.ico
Query=
Key=
Is post=0
Has endseparator=0
Encoding=utf-8
Search Type=115
Verbtext=0
Position=-1
Nameid=291960

[Search Engine 22]
UNIQUEID=BD0EEE0A5FCA11DDAE6D867456D89593
Name=
URL=http://redir.opera.com/translation/?text=%s&from=es&to=en
ICON=http://babelfish.yahoo.com/favicon.ico
Query=
Key=
Is post=0
Has endseparator=0
Encoding=utf-8
Search Type=116
Verbtext=0
Position=-1
Nameid=291960

[Search Engine 24]
UNIQUEID=0B7FB2A45FCB11DD8980147856D89593
Name=
URL=http://redir.opera.com/translation/?text=%s&from=en&to=ja
ICON=http://babelfish.yahoo.com/favicon.ico
Query=
Key=
Is post=0
Has endseparator=0
Encoding=utf-8
Search Type=118
Verbtext=0
Position=-1
Nameid=291960

[Search Engine 25]
UNIQUEID=4031DD385FCB11DDAE6A3E7B56D89593
Name=
URL=http://redir.opera.com/translation/?text=%s&∓from=ja&to=en
ICON=http://babelfish.yahoo.com/favicon.ico
Query=
Key=
Is post=0
Has endseparator=0
Encoding=EUC-JP
Search Type=119
Verbtext=0
Position=-1
Nameid=291960

The "Translate" sub menu works now; now it's time to expand the "Dictionary" and "Encyclopedia" entries into submenus by modifying the [Hotclick Popup Menu] section of the OPERA_INSTALL_PATH\ui\standard_menu.ini:

[Hotclick Popup Menu]
Item, MI_IDM_DOCCOPY			= Copy
Item, M_COPY_TO_NOTE			= Copy to note
Platform Win2000-Unix-Mac-QNX, Feature Voice, Item, M_HOTCLICK_MENU_ITEM_SPEAK = Speak selection
--------------------1
Item, MI_IDM_SELSEARCH				= Hotclick search, 200
Submenu, MI_IDM_SEARCH_DUMMY_PARENT, Internal Search With
Submenu, 999999999, Dictionary menu
Submenu, 999999998, Encyclopedia menu
--------------------2
Submenu, MI_IDM_SELTRANSLATE_EN_FR_PARENT, Translate menu
--------------------3
Item, M_HOTCLICK_POPUP_MENU_GOTO_URL				= Go to page, "%t"
Item, MI_IDM_SELMAIL			= Send text in mail

The Submenu command creates a submenu — since the language string numbering schema remains unknown to the public, the locale-specific submenu names are using 999999999 and 999999998 as language string numeric identifiers. We have to add these two strings in the OPERA_INSTALL_PATH\locale\zh-tw\zh-tw.lng too:

999999999="查字典(D)"
999999998="查百科(P)"

And we mustn't forget to define the actual "Dictionary" and "Encyclopedia" submenus in OPERA_INSTALL_PATH\ui\standard_menu.ini:

[Dictionary menu]
Item, MI_IDM_SELTRANSLATE_FR_PT			= Hotclick search, 109
Item, MI_IDM_SELDICTIONARY			= Hotclick search, 50
--------------------1
Item, MI_IDM_SELTRANSLATE_DE_FR			= Hotclick search, 112

[Encyclopedia menu]
Item, MI_IDM_SELTRANSLATE_FR_ES			= Hotclick search, 110
Item, MI_IDM_SELENCYCLOPED			= Hotclick search, 51
Item, MI_IDM_SELTRANSLATE_IT_FR			= Hotclick search, 114
--------------------1
Item, MI_IDM_SELTRANSLATE_ES_FR			= Hotclick search, 117

Again, the locale-specific names are also added into the OPERA_INSTALL_PATH\locale\zh-tw\zh-tw.lng:

-1539396211="韋氏英英字典(W)"
1634087069="英文維基百科(E)"
1209820415="Yahoo!奇摩字典"
1209820051="中文維基百科(Z)"
1206981060="國家語文綜合連結檢索"
1213449720="日文維基百科(J)"
1208670099="偽基百科(U)"

And the actual Hotkey searches in the OPERA_INSTALL_PATH\locale\zh-tw\search.ini:

[Search Engine 5]
UNIQUEID=CD139D765FC211DDA345390D56D89593
Name=
URL=http://en.wikipedia.org/wiki/Special:Search?search=%s
ICON=http://redir.opera.com/favicons/wikipedia/favicon.ico
Query=
Key=
Is post=0
Has endseparator=0
Encoding=utf-8
Search Type=51
Verbtext=0
Position=-1
Nameid=65188

[Search Engine 6]
UNIQUEID=9923D42C5FC211DDA01C470B56D89593
Name=
URL=http://www.merriam-webster.com/dictionary/%s
ICON=http://www.merriam-webster.com/favicon.ico
Query=
Key=
Is post=0
Has endseparator=0
Encoding=utf-8
Search Type=50
Verbtext=0
Position=-1
Nameid=65187

[Search Engine 15]
UNIQUEID=C482AAFA5FC511DD9EE1413256D89593
Name=
URL=http://tw.dictionary.yahoo.com/search?ei=UTF-8&p=%s
ICON=http://babelfish.yahoo.com/favicon.ico
Query=
Key=
Is post=0
Has endseparator=0
Encoding=utf-8
Search Type=109
Verbtext=0
Position=-1
Nameid=291960

[Search Engine 16]
UNIQUEID=EBB05C8A5FC511DD829BD83356D89593
Name=
URL=http://zh.wikipedia.org/w/index.php?title=Special%3A%E6%90%9C%E7%B4%A2&redirs=0&search=%s&fulltext=Search&ns0=1
ICON=http://redir.opera.com/favicons/wikipedia/favicon.ico
Query=
Key=
Is post=0
Has endseparator=0
Encoding=utf-8
Search Type=110
Verbtext=0
Position=-1
Nameid=291960

[Search Engine 18]
UNIQUEID=515B56A65FC711DD99D77C4556D89593
Name=
URL=http://www.nlcsearch.moe.gov.tw/EDMS/admin/dict3/search_go.php
Query=dictlist=47?2C46?2C51?2C18?2C16?2C13?2C20?2C19?2C53?2C12?2C14?2C17?2C48?2C57?2C24?2C25?2C26?2C29?2C30?2C31?2C32?2C33?2C34?2C35?2C36?2C37?2C39?2C38?2C41?2C42?2C43?2C45?2C50?2C&qstr=%s&chkSubject=on&hdnSubject=A&dict=&hdnCheckAll=checked&dict0=&dict0=47&dict0=46&dict0=51&dict1=&dict1=18&dict1=16&dict1=13&dict1=20&dict1=19&dict1=53&dict1=12&dict1=14&dict1=17&dict1=48&dict2=&dict2=57&dict2=24&dict3=&dict3=25&dict3=26&dict3=29&dict3=30&dict3=31&dict4=&dict4=32&dict4=33&dict4=34&dict4=35&dict4=36&dict4=37&dict4=39&dict4=38&dict4=41&dict5=&dict5=42&dict5=43&dict5=45&dict5=50&pageno=
Key=
Is post=1
Has endseparator=0
Encoding=big5
Search Type=112
Verbtext=0
Position=-1
Nameid=291960

[Search Engine 20]
UNIQUEID=B2227D485FC711DD9F8DA84956D89593
Name=
URL=http://ja.wikipedia.org/wiki/特別:検索?search=%s&go=%E8%A8%98%E4%BA%8B%E8%A1%A8%E7%A4%BA
ICON=http://redir.opera.com/favicons/wikipedia/favicon.ico
Query=
Key=
Is post=0
Has endseparator=0
Encoding=utf-8
Search Type=114
Verbtext=0
Position=-1
Nameid=291960

[Search Engine 23]
UNIQUEID=E71079445FCA11DDBA1D577656D89593
Name=
URL=http://zh.uncyclopedia.info/index.php?title=%E7%89%B9%E6%AE%8A%3A%E6%90%9C%E5%B0%8B&search=%s&go=%E9%80%B2%E5%85%A5
ICON=http://images.uncyc.org/zh-tw/6/64/Favicon.ico
Query=
Key=
Is post=0
Has endseparator=0
Encoding=utf-8
Search Type=117
Verbtext=0
Position=-1
Nameid=291960

Any search for which Search Type is not =0 will not be shown in the Search Bar, but these can be invoked using the "Hotclick search" command. The reason to use "Hotclick search" rather than "Go to page" is to specify input encoding (Encoding=foo) and/or specify GET/POST submission (Is post=0_OR_1).

Since the Hotclick menu can be locale-based, we could go further and add English, Simplified Chinese, or versions for any other UI languages. To summarise, the following table describes the language file changes made in this section of the work:

OPERA_INSTALL_PATH\locale\zh-tw\zh-tw.lng
OPERA_INSTALL_PATH\locale\zh-cn\zh-cn.lng
OPERA_INSTALL_PATH\locale\en\en.lng
String numeric identifier Opera's original Nalakuvara modification
-1539396211 字典(D) 韋氏英英字典(W)
字典 iCIBA爱词霸
Dictionary Merriam-Webster online dictionary
1634087069 百科全書(E) 英文維基百科(E)
百科全书 英语维基百科(E)
Encyclopedia English Wikipedia
1209820046 法文 > 英文(E) 法文 > 英文(2)
法语译英语 法语译英语(2)
French to English (2) French to English
1209820004 法文 > 德文(M) 英文 > 繁體中文(T)
法语译德语 英语译中文(C)
French to German (T) English to Traditional Chinese
1209820184 法文 > 義大利文(T) 繁體中文 > 英文(E)
法语译意大利语 中文译英语(E)
French to Italian (E) Traditional Chinese to English
1209820415 法文 > 葡萄牙文(O) Yahoo!奇摩字典
法语译葡萄牙语 台湾Yahoo!奇摩字典
French to Portuguese Yahoo! Taiwan dictionary
1209820051 法文 > 西班牙文(A) 中文維基百科(Z)
法语译西班牙语 中文维基百科(Z)
French to Spanish Chinese Wikipedia
1206981023 德文 > 英文(N) 德文 > 英文(3)
德语译英语 德语译英语(3)
German to English (3) German to English
1206981060 德文 > 法文(R) 國家語文綜合連結檢索
德语译法语 台湾国家语文综合连结检索
German to French National Language Composite Search
1213449683 義大利文 > 英文(L) 義大利文 > 英文(4)
意大利语译英语 意大利语译英语(4)
Italian to English (4) Italian to English
1213449720 義大利文 > 法文(Y) 日文維基百科(J)
意大利语译法语 日语维基百科(J)
Italian to French Japanese Wikipedia
1221751130 葡萄牙文 > 英文(U) 葡萄牙文 > 英文(5)
葡萄牙语译英语 葡萄牙语译英语(5)
Portuguese to English (5) Portuguese to English
1208670062 西班牙文 > 英文(H) 西班牙文 > 英文(6)
西班牙语译英语 西班牙语译英语(6)
Spanish to English (6) Spanish to English
1208670099 西班牙文 > 法文(B) 偽基百科(U)
西班牙语译法语 伪基百科(U)
Spanish to French Uncyclopedia
1208490529 英文 > 繁體中文(C) 英文 > 日文(J)
英语译日语 英语译日语(J)
English to Japanese (J) English to Japanese
1213952801 繁體中文 > 英文(V) 日文 > 英文(1)
日语译英语 日语译英语(1)
Japanese to English (1) Japanese to English
999999999 查字典(D)
查字典(D)
Dictionary
999999998 查百科(E)
查百科(E)
Encyclopedia

The reason to provide this functionality is that some Taiwanese users might use computers in other countries, such as America and China, and not always be able to use Opera with the Traditional Chinese UI. With the English and Simplified Chinese UI predefined, these users have an way of using the tweaked menu too.

The English (en) and Simplified Chinese (zh-cn) versions of search.ini are different from the Traditional Chinese (zh-tw) one. Most locale-specific searches are preserved during Nalakuvara's editing process.

A note on encoding

This is not over yet. Encoding is always a big problem in CJK, so Taiwanese users often switch web page encodings. Many users asked if an encoding submenu could be included in the right-click menu, so here it is:

[Document Popup Menu]

Item, MI_IDM_Prev_PM,				= Back
Item, MI_IDM_Next_PM,				= Forward
Item, M_REWIND,				= Rewind
Item, M_FAST_FORWARD,				= Fast Forward
--------------------1
Item, MI_IDM_Reload_PM,				= Reload
Submenu, MI_IDM_AUTORELOAD_TOGGLE_PARENT, Reload Menu
--------------------2
Item, M_DOCUMENT_POPUP_MENU_BOOKMARK_PAGE		= Add to bookmarks, 1
Item, MI_IDM_POPUP_ADDRESS			= Copy document address
Item, MI_IDM_SEND_URL_EMAIL		= Send document address in mail
--------------------3
Item, MI_IDM_Print				= Print document
Item, MI_IDM_Kilde				= View document source
Item, M_DOCUMENT_POPUP_MENU_VALIDATE			= Validate frame source
Submenu, M_OPEN_WITH, Open in menu
--------------------5
Include, Internal Frame
Include, Internal Document Background
--------------------7
Submenu, MI_IDM_ENCODING_AUTOMATIC_PARENT, Encoding Menu
Item, M_BLOCK_CONTENT = Content block mode on | Content block mode off
Item, M_EDIT_SITE_PREFERENCES = Edit site preferences
--------------------8
Item, MI_IDM_FULLSCREENTOGGLE			= Enter fullscreen | Leave fullscreen

Another requested feature is the ability to∓ merge notes. It is quite simple:

[Note Item Popup Menu]
Item, MI_IDM_SELMAIL       = Send text in mail
--------------------1
Item, MI_IDM_HLITEM_CUT                            = Cut
Item, MI_IDM_HLITEM_COPY                            = Copy
Item, MI_IDM_HLITEM_PASTE                            = Paste
Item, 999999997                            = Copy & Paste to note
Item, 999999996                            = Copy & Delete & Paste to note
Item, MI_IDM_HLITEM_DELETE                            = Delete
--------------------5
Item, MI_IDM_HLITEM_SELECTALL                     = Select all
--------------------6
Item, M_BOOKM_PANEL_VIEW_MENU_SORT_BY_MY_ORDER       = Sort by column, -1
Item, M_BOOKM_PANEL_VIEW_MENU_SORT_BY_NAME       = Sort by column, 0
--------------------7
Item, M_NEW_NOTE       = New note
Item, SI_NEW_FOLDER_BUTTON_TEXT       = New folder
Item, M_NEW_SEPARATOR        = New Seperator

Here I am introducing two more customized language string numeric identifiers, 999999997 and 999999996. Again, we have to add these two strings to OPERA_INSTALL_PATH\locale\zh-tw\zh-tw.lng:

; item for Nalakuvara
999999997="合併且保留"
999999996="合併"

And to summarise:

OPERA_INSTALL_PATH\locale\zh-tw\zh-tw.lng
OPERA_INSTALL_PATH\locale\zh-cn\zh-cn.lng
OPERA_INSTALL_PATH\locale\en\en.lng
String numeric identifier Opera's original Nalakuvara modification
999999997 合併且保留
合并且保留
Merge and keep
999999996 合併
合并
Merge

This article is licensed under a Creative Commons Attribution, Non Commercial - Share Alike 2.5 license.

Comments

The forum archive of this article is still available on My Opera.

No new comments accepted.