三太子(Nalakuvara)計畫:Building Opera Nalakuvara
Nalakuvara is one of the most famous customized Opera packages in Taiwan. It is cross-platformed, open-sourced, unobtrusive, multi-lingual and fully localized for Taiwan users. This article focuses on technical details of managing such an Opera customization project.
Introduction
Opera Desktop Browser ("Opera") is an elegant web browser. It follows web standards strictly, ships with so many functions built-in, and still runs so fast, even on older computers. Although Opera remains proprietary, it have an open mind: basically Opera encourages user communities to build their own customized Opera to suit their own needs, as long as people do not break Opera's End-User License Agreement. (i.e., people shall not modify, translate, reverse engineer, decompile or disassemble Opera Browser or any part thereof or otherwise attempt to derive source code, create or use derivative works therefrom. etc.)
As the result, there are many customized Opera around the world. Some customized Opera are semi-officially supported, while some are even becoming official. Opera Ibis ("Ibis"), once a community-based customized Opera from China, is now listed as an official download on Opera's official website. Ibis is basically identical to international version of Opera, but available only in Simplified Chinese and English interface, and with some default setting modified. (In v9.6x era, Ibis also ships with special skin, and has a slightly different rendering system for Simplified Chinese characters. The rendering system in Ibis 9.6x later merged into Opera 10.00 trunk.)
Ibis reveals some special needs from OperaChina community. Not too surprising, users from Taiwan have similar yet different needs, which will be discussed later, in "Background Analysis" section.
Thus there is Opera Nalakuvara ("Nalakuvara"), a customized Opera project for users from Taiwan. Nalakuvara is still young, but already attracts more than 5,000 downloads in the first half month since its Beta 1 release. Web media such as Chinese Engadget and Plurk spread Nalakuvara widely. Some local web service providers also promise to improve their products to be compatible with Nalakuvara.
Nalakuvara is quite special among all Opera customization projects. First of all, Nalakuvara is quite open. The whole Nalakuvara is well documented and reveals almost everything to users. One could easily adapt Nalakuvara and fork to his/her own project. Second, Nalakuvara is extremely flexible and cross-platformed. For now, there are 9 packages for various systems including Windows, Linux (Ubuntu, Fedora, and generic Linux), and FreeBSD; package for Mac OS X is on the way, too. Third, Nalakuvara is exceedingly user-friendly; users could choose if he/she would like to install any of 3rd party components in Nalakuvara. Nalakuvara confirms before deleting exist user profiles (or make backup instead, in some platforms). It also enables User JavaScript related options only if users choose to install any of them. If there is anything users need to do by themselves, Nalakuvara provides detailed information. Even if installed in Windows other than Traditional Chinese environment, Nalakuvara still displays and works mostly correctly.
In this article, I will describe how I manage Nalakuvara project, piece by piece, with lots of technical details. Take this article as a reference, one could easily start-up a brand new customized Opera project that works. The outline of this article is as follows:
OK, here we go!
Planning
Always plan first for any project. Think carefully before action. In this stage, a project manager has to figure out what to do, and what not to do. Without planning, a project might lose focus and finally be forgotten. Make sure your project will be noticed, remembered, and understood once made public, one way or another.
Background Analysis
First step in the plan stage is to see what has to be done in the first place. To achieve this, one has to understand the (possible) community behind the project. There are many different methodologies to do this job. In Nalakuvara, I took some relatively easy ways: first I did some hallway tests, then I study from local forums.
A hallway test is a common usability test: you randomly invite people who just walk through a hallway to use your product, and watch his/her action and response. So I ask several random people using Opera 10.00 to do their daily browsing. If they complain anything, no matter a feature just disabled by default or totally absent in Opera, I write it down. On the other hand, if they find any feature quite handy or lovely, I write it down too.
A hallway test allows to observe common average users. But I have to understand heavy users and newbies, too. Therefore, I visited a forum focusing on "Browser" in Ptt BBS, the largest local telnet-based BBS in Taiwan. There are over 100,000 unique users logged-in PTT at the same time every night. Heavy users and newbies exchange their knowledge in PTT, so one could see most frequently requested features among all browsers there.
With information from hallway tests and PTT, I figure out that most of users from Taiwan would like to:
- Change Opera's UI font to MingLiU (the default Traditional Chinese font from Traditional Chinese version of Windows) rather than SimSun (the default Simplified Chinese font from Simplified Chinese version of Windows);
- Use mouse gesture;
- Use drag and drop;
- Open new tab in background when possible;
- Avoid using Chinese URL;
- Search strings directly in the location (URL) bar;
- Use Gmail / Ymail / Hotmail;
- Search with Google Taiwan / Yahoo! Taiwan / other search engines popular in Taiwan;
- Use dictionaries;
- Block web advertisement;
- Convert Simplified Chinese characters to Traditional Chinese within a web page;
- Render web page with IE's engine (Trident) to use ActiveX or view IE-only web page in an Opera tab, without opening IE (so called "IE Tab");
- Connect to BBS sites via
telnet://
protocol within the browser; - Use popular Firefox Extensions or equivalence.
So the stage is set. Luckily, most of these requested functions are built in Opera, one just need to enable them; some others are doable via User JavaScript. It seems not so hard, at least so far.
Then I prepare for the first test run. I grab a portable Opera@USB 10.00 build, enable and tweak some settings, which would be discussed in "Dive Into Opera" section, and do a hallway test again!
The Love-to-Complain rate is significant higher then first hallway tests. With this result, I knew this project is worth to do, and there is still a long way to go.
Naming
So next step is to pack a beta package available for public. But wait, before any project is made public, it need a name.
Name, the magic word in human languages. It is name that makes invisible things visible, abstract ideas concrete, communication focused. With a name, people know what each other are talking about.
So you have to name your project.
Before I name mine, I start thinking of Ibis. Ibis, the Vermillion Bird of the South, one of the Four Symbols of the Chinese constellations, is an elegant and noble red bird both in appearance and behavior. Ibis is, thus, a great name for Chinese customized Opera project. It got the right color and meaning. "What will be a good name for Taiwanese customized Opera project?" I asked myself.
One night, I had small talk with one of my friends. He suggested that I choose from some Deity names in Taiwanese traditional religion. Soon, Nalakuvara jumped into my mind. Nalakuvara, or Nezha, is a Deity in sanskrit sutra. Taiwanese people adapted this Deity into our own religion system, just like we adapted numerous different culture and technologies into our own. In Taiwanese folk tale, Nalakuvara is a vigorous and dexterous Deity. He has many talismans, including Wind-Fire-Wheel, with he runs faster than others. The theme color of Nalakuvara is also red. So this project is named Nalakuvara.
When naming your project, please remember that it is impossible to satisfy all users. No matter how brilliant your project is named, there is always someone who does not like it. A name is a name. Do not spend too much time on naming. Keep yourself concentrating on the actual project, and let your project do the talking job.
So there was Opera Nalakuvara Beta 1, the very first public release of Nalakuvara project. From that time, Nalakuvara has faced living and changing user environment. There must be something I missed. I had to improve its overall usability, fix its bugs, add features people still desire. Tons of work to do, how could I keep it straight?
Guidelines
For every scaled project, there are road-map, milestone, and etc. These documents are the rules of a project. Nalakuvara is not one of these projects. Remember, it is still tiny from beginning. However, to keep Nalakuvara moving toward the same direction, there must be some guidelines. In Nalakuvara, these guidelines are:
- Do no harm first, do something useful second;
- Keep Opera look and feel just like Opera;
- Cross-platform as possible;
- Use as less 3rd party components as possible;
- In case a 3rd party component is unavoidable, at least let users to make the final decision.
It is critical to write down these guidelines first. Anytime a dispute is raised, it is easy and clear to judge with these guidelines. When you work on a project on your own, you will find it your savior when facing user community; when you have a group of core members, these guidelines keep everyone on his track, minify possible misunderstanding among you.
By Nalakuvara's guidelines, I could respond to communities that might and might not be part of Nalakuvara:
- Nalakuvara may not modify the official Opera installation package;
- Nalakuvara may not cause security flaw;
- Nalakuvara may not use Add-On applications such as eDown and oGet;
- Nalakuvara might alter default menus and toolbars to provide additional feature;
- Nalakuvara might use User JavaScript to provide additional feature;
- Nalakuvara may not use User JavaScript that alters web page rendering result too much (so that it will not look and feel like Opera anymore);
- Nalakuvara should enable User JavaScript options only if there is any User JavaScript installed;
- Nalakuvara should allow users to select install location when possible;
- Nalakuvara should allow users to choose what 3rd party components to install;
- Nalakuvara should allow users to override default setting.
So far Nalakuvara almost meets all these goals, with the "IE Tab" feature the only exception: it works only on Windows platform, and a 3rd party Plug-In is required.
Tools
A good project needs good planning, and a handy set of tools. Good planning keeps your project on track, while handy set of tools get real things done. Here are some "must haves" while developing software project such as Nalakuvara:
Version Control
Version control not only is for team work but also for individual development. When using with team, version control mainly solves conflict from different team members; when out of team, version control helps you manage your project "versions." You could fork your project, merge fork back to trunk, tag versions, diff two versions, and most importantly, revert files to working versions.
Eventually, people make mistakes. Minor mistake costs you minutes to fix, a huge one destroys the whole project. You might accidentally delete a directory, convert important file to wrong format, or forget what you have done last night. Even worse, your system might fail, hardware might damage, or be stolen.
Version control could almost save you from such a disaster. Plus, it helps further collaboration with others (or tomorrow version of yourself). There is no reason not to use version control.
There are many popular version control systems, such as Subversion/svk, Perforce, git, and so on. In Nalakuvara, I choose Perforce. The reasons are:
- I already use Perforce for years;
- Perforce provides free licensing for Open Source development, and two-users with five-client-workspaces without a license for non-commercial usage;
- Perforce is suitable for wide range situation, from single simple project to huge company like Google (that is right, Google uses customized Perforce);
- Perforce is cross-platformed, with native binaries on several operating systems;
- Perforce works great with both command-line and GUI;
- Perforce does not leave
.svn
directory everywhere (which Subversion does).
Of course, you do not have to use Perforce. But any version control system is at least 1,000 times better than none! In my case, all my working, including text writing, commit to my Perforce server.
When working with version control systems, you should always check out files before editing, check in files after daily work, bug fixed, or things going right, and write logs when committing. There are hundreds of commit I made in the first two weeks of developing Nalakuvara. Without commit logs, it is impossible to target the right version to work with.
Scripting
In Nalakuvara, I do not alter the original installer of Opera. All changes I made are applied via script. There are several concerns on choosing script languages:
- Should be native supported by operating systems, or could be compiled to native binary so that users will not have to install additional runtime environment;
- Should be consistent with original Opera installers on different operating systems so that users will have better experience during installation or patch;
- Should have GUI or command-line interface base on different conveniences on different operating systems;
- Should be able to do specific works, such as reading/writing
.ini
files or Windows registry.
Opera supports many different operating systems. On Windows, original Opera installer is GUI-based, and allows users to choose install path and options; on Linux, Opera packages work with different package management systems like RPM, or are distributed as a tarball, with minimal or none install option; on FreeBSD, most users install Opera via ports; Mac OS X is totally another story. Sorry I will not talk much about Mac in this article for I never have a Mac.
I choose AutoHotKey for Windows jobs. Because:
- AutoHotKey is a free and open-sourced;
- Syntax is simple and easy, including GUI creation;
- Could do Windows-specific works;
- Could be compiled to Windows standalone
.exe
executable (and could be de-compiled back to.ahk
source script);
And shell script for Linux/FreeBSD jobs, more specificly, BASH shell script. Because:
- BASH is free and open-sourced;
- Common among all Linux/BSD distributions, and is the default shell in some;
- Could do Linux/FreeBSD-specific works.
If there is Nalakuvara for Mac OS X, Automator. Because:
- Automator is part of Mac OS X;
- Deals with GUI;
- Could do Mac-specific works.
You could also do jobs with much regular languages. But please consider your effort and release size too. My opinion is: keep things simple and tiny, so that people could spread it out and work on it, with or without you.
Virtual Machine
To support different platforms, it is critical to know what exactly happened. The traditional way to do this is to prepare several systems on several machines. It is quite expensive and time-consuming. The most painful part is that you have to rebuild/reinstall them all, from time to time, in order to perform a "clean test."
Virtual technology could save your time. You could have many "guest" systems on a single "host" system. Many virtual machines give you the ability to take snapshots of current system states. So you could easily revert any system to prepared but clean states, just in a minute or two.
I used VMware Workstation. If you are looking for some free alternatives, try these:
- VMware Server and VMware Player, both are free for charge;
- VirtualBox by Sun Microsystems, free and open-sourced;
- Virtual PC and Windows Virtual PC, both are free for charge.
There are many other alternatives. Just pick any suitable and handy.
For now, I have a Windows XP Professional with SP3, a Ubuntu 9.04 Desktop, and a Fedora 11 Desktop, all in my VMware Workstation (in a tiny laptop). Too bad it is impossible to run a Snow Leopard guest for I am using x86 version of Windows XP as host. (Basically a x64 guest OS has to be in a x64 host OS.)
Dive Into Opera
Playground is ready. This is where the fun begins.
Installation and Initial Phase
Let us take a closer look at what happened during Opera's installation and initial phase. On Windows, Opera installer extracts a MSI installer and runs. During the installation, users could choose where to install Opera, and whether to create shortcut icons on Desktop, Quick Launch Bar, or Start Menu. The MSI Installer language is based on Windows system environment. By default, Opera will be installed at %PROGRAMFILES%\Opera\
and the multiple users support is enabled as well.
If this is the first installation of Opera, for now, all Opera related files are in the Opera install path. At the very first time Opera is launched, several files are copied from Opera's install path to, or created at, %APPDATA%\Opera\
and %USERPROFILE%\Local Settings\Application Data\Opera\
. I refer this as Opera's "initial phase." If there was another Opera installed on this system before, user setting and files usually remain at %APPDATA%
and %USERPROFILE%
, thus Opera does not overwrite those existent files. The initial phase might happen again, at anytime you launch Opera with user files missing.
So the best occasion to interfere with Opera is after its (whole new) installation and before its first run. Just touch files in Opera's install path and everything should work just as you imagine. This works with multiple users situation. All users get the same improved setting, and are free to tweak by their own. If you interfere after Opera's initial phase, you might have to delete all existent user profile, setting, files so that Opera will run into initial phase again, or to carefully handle files in Opera's install path, %APPDATA%
, and %USERPROFILE%
altogether.
On Linux, things are different. There are three types of Opera package on Linux:
- Deb package (
.deb
) for Ubuntu and Debian; - RPM package (
.rpm
) for Fedora, Mandriva, RedHat, SuSE; - Tarball (
.tar.gz
) for generic Linux.
RPM and deb package require almost no user interaction to install Opera. They basically put application binary into /usr/share/opera
, library into /usr/lib/opera
, and two default preference setting files operaprefs_default.ini
and operaprefs_fixed.ini
into /etc
. Tarball does the same, except that it will prompt users every path to put files, with the same default paths as RPM and deb package. Later during initial phase, Opera puts (copies or creates) user files and settings in ~/.opera
.
Again, the best opportunity to interfere is just like on Windows. Otherwise you will have to deal with files in /usr/share/opera
, /etc
, and ~/.opera
.
On FreeBSD, things are almost the same with Linux, except application binary is in /usr/local/share/opera
rather than /usr/share/opera
, and /usr/local/lib/opera
rather than /usr/lib/opera
.
Silent Installation
In order to keep users away from triggering initial phase right after installation, the best way is do not let users install Opera by themselves. This means Nalakuvara package should be able to install Opera for users.
On Windows, we could use Opera's MSI (Windows Installer) with several FOO=BAR variables in command-line, to specify a silent install. FOO is the variable name, BAR is its value; multiple variables is allowed and should be divided by a single space. The variables that could be used include:
CREATE_DESKTOP_ICON_REG
: create shortcut icon on Desktop for all users if value is1
, not if0
;CREATE_DESKTOP_ICON_REG_USR
: create shortcut icon on Desktop for current user if value is1
, not if0
;CREATE_QUICKLAUNCH_ICON_REG
: create shortcut icon on Quick Launch Bar for all users if value is1
, not if0
;CREATE_QUICKLAUNCH_ICON_REG_USR
: create shortcut icon on Quick Launch Bar for current user if value is1
, not if0
;CREATE_STARTMENU_ICONS
: create shortcut icon on Start Menu for all users if value is1
, not if0
;CREATE_STARTMENU_ICONS_REG_USR
: create shortcut icon on Start Menu for current user if value is1
, not if0
;ISCHECKFORPRODUCTUPDATES
: check if there is updated version available if value is1
, not if0
;ALLUSERS
: install for all users if value is1
, not if0
;LAUNCH_OPERA_ON_FINISH
: launch Opera on installation finish if value is1
, not if0
;SET_DEFAULT_BROWSER
: register Opera as system's default web browser if value is1
, not if0
;MULTI_USER_SETTING
: enable multiple user setting support if value is1
, not if0
;INSTALLER_LANGUAGE
: specify UI language of MSI installer with language code (i.e.,zh-tw
means Traditional Chinese, and so on);INSTALLDIR
: specify where to install Opera.
By default, Opera installer will create those three shortcut icons (on Desktop, Quick Launch Bar, and Start menu), enable multiple user setting support, install Opera at %PROGRAMFILES%\Opera
, set Opera as default browser, and launch Opera on finish. You could perform such a default install without user interaction by execute:
msiexec /i Opera_1060_int_Setup.msi /qn CREATE_DESKTOP_ICON_REG=1 CREATE_DESKTOP_ICON_REG_USR=1 CREATE_QUICKLAUNCH_ICON_REG=1 CREATE_QUICKLAUNCH_ICON_REG_USR=1 CREATE_STARTMENU_ICONS=1 CREATE_STARTMENU_ICONS_REG_USR=1 ISCHECKFORPRODUCTUPDATES=0 ALLUSERS=1 LAUNCH_OPERA_ON_FINISH=1 SET_DEFAULT_BROWSER=1
But we do not want Opera launched on finish. So let us change LAUNCH_OPERA_ON_FINISH
to 0
:
msiexec /i Opera_1060_int_Setup.msi /qn CREATE_DESKTOP_ICON_REG=1 CREATE_DESKTOP_ICON_REG_USR=1 CREATE_QUICKLAUNCH_ICON_REG=1 CREATE_QUICKLAUNCH_ICON_REG_USR=1 CREATE_STARTMENU_ICONS=1 CREATE_STARTMENU_ICONS_REG_USR=1 ISCHECKFORPRODUCTUPDATES=0 ALLUSERS=1 LAUNCH_OPERA_ON_FINISH=0 SET_DEFAULT_BROWSER=1
What if users want to specify Opera's install path? Here are some sample codes in Nalakuvara's AutoHotKey script to do so:
FileSelectFolder, OperaInstallPath, ::{20d04fe0-3aea-1069-a2d8-08002b30309d}, 1, Please choose the location you would like to install Opera. Press `"Cancel`" to apply default vaule %ProgramFiles%\Opera RunWait, msiexec /i %OperaInstaller% /qn CREATE_DESKTOP_ICON_REG=1 CREATE_DESKTOP_ICON_REG_USR=1 CREATE_QUICKLAUNCH_ICON_REG=1 CREATE_QUICKLAUNCH_ICON_REG_USR=1 CREATE_STARTMENU_ICONS=1 CREATE_STARTMENU_ICONS_REG_USR=1 ISCHECKFORPRODUCTUPDATES=0 ALLUSERS=1 LAUNCH_OPERA_ON_FINISH=0 SET_DEFAULT_BROWSER=1 INSTALLDIR="%OperaInstallPath%"
First I use FileSelectFolder
to ask users to specify a folder to install Opera. Its 2nd option value, ::{20d04fe0-3aea-1069-a2d8-08002b30309d}
, is a CLSID folder name for My Computer, where users starting with. The 3rd option value, 1
, turns on a folder creation button. So users have to either select an existent folder or create a new folder before selecting it. Either way, the folder now exists, and its long path name is stored as %OperaInstallPath%
variable.
What if users have already installed Opera before? It is a little complicated to determine whether Opera is installed, and where if it was. I check Windows registry first. If Opera is installed, there should be something at HKLM\SOFTWARE\Classes\Opera.HTML\shell\open\command
. We could use AutoHotKey's RegRead
to read its default value and store it as a variable:
RegRead, OperaInstallPathReg, HKLM, SOFTWARE\Classes\Opera.HTML\shell\open\command
If Opera is installed, the %OperaInstallPathReg%
shoulde now be something like:
"C:\Program Files\Opera\opera.exe" "%1"
We only need the path part in this variable. So let us extract it with some simple regular expression tricks and check with AutoHotKey's IfExist
:
OperaInstallPath := RegExReplace(OperaInstallPathReg, ".(.:.+)\\[Oo]pera\.exe.+$", "$1") IfExist, %OperaInstallPath%
But even if %OperaInstallPathReg%
is null, which means there is nothing at HKLM\SOFTWARE\Classes\Opera.HTML\shell\open\command
, users might still have already installed Opera before but uninstalled it later, leaving something in user profile behind. So I then check those path:
IfExist, %APPDATA%\Opera
and:
IfExist, %USERPROFILE%\Local Settings\Application Data\Opera
If any of these three paths exists on the system, it means that Opera is installed before. You might like to remove old files first, or patch those old files too.
What if not only users install Opera before, but Opera is also running currently? Do not forget to close all existent Opera process in AutoHotKey script before doing anything else:
Process, Close, opera.exe
The actual code used in Nalakuvara's script is much complicated. There are other details to care about. What if users press "Cancel" while selecting Opera install path? What if users select a file rather than a folder? Check and re-check, prepare defaults and fallbacks, and make your scripts bullet proof.
These are things on Windows. What about Linux?
Deb packages invoke gdebi-gtk package manager on Ubuntu with GUI. But you could install deb packages with dpkg
in command-line:
dpkg -i opera_10.00.deb
However, dpkg
does not install all necessary dependencies for you. In order to do so, you have to use APT package manager's apt-get
command:
apt-get -f -y install
RPM packages invoke gnome-packagekit package manager on Fedora with GUI. Again you could install RPM packages with rpm
in command-line:
rpm -i --force opera-10.00.rpm
Luckily rpm
deals with dependency so you do not have to do it manually.
If you fetch a tarball for generic Linux, just install it as usual way:
tar -xzf opera-10.00.tar.gz cd opera-10.00 ./install.sh
Is it that simple? No.
The main problem here is you have to be root to install packages. One way is to ask users to su
as root to run the script, another is to ask users to install and setup sudo
. I prefer using sudo
rather than su
for its security.
Ubuntu has a working sudo
by default, how nice. Linux destributions using APT package manager (such as Fedora) could install and setup sudo
with these commands:
su root apt-get install sudo visudo
Those using Easy Urpmi package manager (such as Mandriva) could do with these commands:
su root urpmi sudo visudo
The manual way to do so is to fetch sudo
source from http://www.sudo.ws/ and then compile it. That works too. But still, users have to visudo
themselves into sudoers.
FreeBSD way is to work with ports:
cd /usr/ports/www/opera sudo make clean install
And if sudo
is not usable yet, do this first:
su root cd /usr/ports/security/sudo make clean install visudo
On Linux or FreeBSD, too, do not forget to close all existent Opera process before doing anything else:
killall opera
Files Location and Priority
Once Opera is installed and has not yet triggered the initial phase, what files should we touch? You might find the "Files Used by Opera for Windows" and the "Files Used by Opera for Linux, FreeBSD and Solaris" documents quite useful but a little outdated. To be short, here are our primary targets:
operaprefs.ini
: stored program settings;search.ini
: default settings for the search engines available in Opera;bookmarks.adr
: default bookmarks file;webmailproviders.ini
: default settings for the web mail providers available in Opera;fastforward.ini
: defines what activates the Fast Forward button;standard_menu.ini
: Opera standard menu configuration;standard_toolbar.ini
: Opera standard toolbar configuration.
If you are careful enough, you might have already found that some files that have multiple instance in your system. Which one is the one? The "Configuration Priority Scheme" section from Opera's System Administrator's Handbook gives a clue. Yet this document is not detailed enough.
Studying from Ibis plus some experiments, I finally figure out the actual priority order:
operaprefs.ini
:%SYSTEMROOT%\SYSTEM32\operaprefs_fixed.ini
%APPDATA%\Opera\OPERA_DIR_NAME\operaprefs.ini
%USERPROFILE%\Local Settings\Application Data\Opera\OPERA_DIR_NAME\custom\defaults\operaprefs.ini
OPERA_INSTALL_PATH\custom\defaults\operaprefs.ini
OPERA_INSTALL_PATH\defaults\operaprefs.ini
OPERA_INSTALL_PATH\operaprefs_default.ini
search.ini
:%APPDATA%\Opera\OPERA_DIR_NAME\search.ini
OPERA_INSTALL_PATH\locale\LANGUAGE_CODE\search.ini
OPERA_INSTALL_PATH\defaults\search.ini
bookmarks.adr
:%APPDATA%\Opera\OPERA_DIR_NAME\bookmarks.adr
OPERA_INSTALL_PATH\locale\LANGUAGE_CODE\bookmarks.adr
OPERA_INSTALL_PATH\defaults\bookmarks.adr
webmailproviders.ini
:OPERA_INSTALL_PATH\defaults\webmailproviders.ini
fastforward.ini
:%USERPROFILE%\Local Settings\Application Data\Opera\OPERA_DIR_NAME\custom\defaults\fastforward.ini
OPERA_INSTALL_PATH\custom\defaults\fastforward.ini
OPERA_INSTALL_PATH\defaults\fastforward.ini
standard_menu.ini
:%APPDATA%\Opera\OPERA_DIR_NAME\menu\standard_menu.ini
OPERA_INSTALL_PATH\ui\standard_menu.ini
standard_toolbar.ini
:%APPDATA%\Opera\OPERA_DIR_NAME\toolbar\standard_toolbar.ini
OPERA_INSTALL_PATH\ui\standard_toolbar.ini
Allow me to explain some details:
OPERA_INSTALL_PATH
: where you install Opera, "%PROGRAMFILES%\Opera
" by default;OPERA_DIR_NAME
: the final part ofOPERA_INSTALL_PATH
, "Opera
" by default;LANGUAGE_CODE
: the UI language that Opera is currently running with. "zh-tw
" for Traditional Chinese, "zh-cn
" for Simplified Chinese, "en
" for English, etc;%USERPROFILE%\Local Settings\Application Data\Opera\OPERA_DIR_NAME\custom\defaults\*
are copied fromOPERA_INSTALL_PATH\custom\defaults\*
during initial phase;%PROGRAMFILES%
is a Windows environment variable, usually "C:\Program Files
";%APPDATA%
is a Windows environment variable, usually "%USERPROFILE%\Application Data
";%USERPROFILE%
is a Windows environment variable, usually "C:\Documents and Settings\USER_NAME
" whereUSER_NAME
is the Windows user name of current user;%SYSTEMROOT%
is a Windows environment variable, usually "C:\WINDOWS
";standard_menu.ini
andstandard_toolbar.ini
will not be overthrown by higher priority ones. They will appear together and allow users to switch between them.
It is quite tricky and complicated to decide which file to work on. Doing files with priority too high causes users to be unable to change their own preferences; files with priority too low could not make things work since everything you do is overthrown as some of these files could be locale-based. So you could deliver different tweak to users using different locales. This makes great sense. Too bad that not every part works this way.
In the end, I picked up these files:
OPERA_INSTALL_PATH\custom\defaults\operaprefs.ini
OPERA_INSTALL_PATH\locale\zh-tw\search.ini
OPERA_INSTALL_PATH\locale\zh-cn\search.ini
OPERA_INSTALL_PATH\locale\en\search.ini
OPERA_INSTALL_PATH\locale\zh-tw\bookmarks.adr
OPERA_INSTALL_PATH\locale\zh-cn\bookmarks.adr
OPERA_INSTALL_PATH\locale\en\bookmarks.adr
OPERA_INSTALL_PATH\defaults\webmailproviders.ini
OPERA_INSTALL_PATH\custom\defaults\fastforward.ini
OPERA_INSTALL_PATH\ui\standard_menu.ini
OPERA_INSTALL_PATH\ui\standard_toolbar.ini
Opera on Linux is basically the same, except operaprefs_fixed.ini
and operaprefs_default.ini
both located at /etc
(on FreeBSD, /usr/local/etc
).
Tweak Defaults
First thing first. Most of the features users want is available through changing Opera's setting:
[User Prefs] | |||
---|---|---|---|
Feature | opera:config Link | Opera Default | Nalakuvara Tweak |
Enable Mouse Gesture (Note: default to 1 since Opera 10.50) |
opera:config#UserPrefs|EnableGesture | 0 | 1 |
Enable All Drag & Drop Feature | opera:config#UserPrefs|EnableDrag | 247 | 255 |
Double Click on Tab to Close It | opera:config#UserPrefs|DoubleclicktoCloseTab | 0 | 1 |
Open New Tab/Window Rather Than Re-use Current One | opera:config#UserPrefs|NewWindow | 0 | 1 |
Open New Tab/Window in Background (Note: does not work anymore since Opera 10.50) |
opera:config#UserPrefs|OpenNewWindowinBackground | 0 | 1 |
Show Panel Toggle Area at the Window Edge | opera:config#UserPrefs|Showpaneltoggle | 0 | 1 |
Open Dragged Link in Background Teb/Window (Note: added since Opera 10.60) |
opera:config#UserPrefs|OpenDraggedLinkInBackground | 0 | 1 |
[Fonts] (Note: modifing this session does not needed anymore since Opera 10.60) |
|||
Feature | opera:config Link | Opera Default | Nalakuvara Tweak |
Browser Dialog Fonts for Traditional Chinese | opera:config#Fonts|Dialog | 15,4,0,0,0,0,SimSun | 12,4,0,0,0,0,新細明體 |
Browser Menu Fonts for Traditional Chinese | opera:config#Fonts|Menu | 15,4,0,0,0,0,SimSun | 12,4,0,0,0,0,新細明體 |
Browser Panel Fonts for Traditional Chinese | opera:config#Fonts|Panel | 15,4,0,0,0,0,SimSun | 12,4,0,0,0,0,新細明體 |
Browser Toolbar Fonts for Traditional Chinese | opera:config#Fonts|Toolbar | 15,4,0,0,0,0,SimSun | 12,4,0,0,0,0,新細明體 |
Browser Tooltip Fonts for Traditional Chinese | opera:config#Fonts|Tooltip | 15,4,0,0,0,0,SimSun | 12,4,0,0,0,0,新細明體 |
[Network] | |||
Feature | opera:config Link | Opera Default | Nalakuvara Tweak |
(HTTP) Accept Traditional Chinese and English, Avoid Simplified Chinese | opera:config#Network|HTTPAcceptLanguage | zh-TW,zh;q=0.9,en;q=0.8 | zh-tw,en;q=0.9 |
Do Not Check Local Host Name While Entering Invalid URL | opera:config#Network|CheckLocalHostName | 1 | 0 |
Do Not Append Host Name Prefix/Postfix While Entering Invalid URL | opera:config#Network|EnableHostNameExpansion | 1 | 0 |
Use Web (Search Engine) to Lookup Host Name While Entering Invalid URL | opera:config#Network|EnableHostNameWebLookup | 0 | 1 |
The Web Search URL to Lookup Host Name | opera:config#Network|HostNameWebLookupAddress | http://www.google.com/search?q=%s&sourceid=opera&num=%i&ie=utf-8&oe=utf-8 |
The reason to change Browser fonts is that SimSun looks good in Simplified Chinese, but horrible in Traditional Chinese. We also have to tweak default HTTP Accept languages to rule out zh
, otherwise some sites wrongly send Simplified Chinese content to Taiwanese users. Traditional Chinese and Simplified Chinese are more like two different languages; treating one as the subset of the other one causes troubles.
Host Name Expansion (append prefix/postfix to invalid host name automatically) is also disabled. Because Traditional Chinese host name such as http://網頁設計.tw/
is still not popular in Taiwan, enabling this expansion often brings users to docked page of domain name retailers.
We could do these for users by editing OPERA_INSTALL_PATH\custom\defaults\operaprefs.ini
:
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 [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
新細明體 (MingLiU) is the default system font on Traditional Chinese version of Windows, and not available on Linux/FreeBSD. There is also a bug on these platforms of Opera, causing Traditional Chinese and Simplified Chinese fonts to be mixed up in web contents, and resulting in inconsistency and ugly display. The workaround is to use "AR PL UMing TW MBE
" and "AR PL UKai TW MBE
" for browser UI and default (preferred) fonts:
[Fonts] | |||
---|---|---|---|
Feature | opera:config Link | Opera Default | Nalakuvara Tweak |
Browser Dialog Fonts for Traditional Chinese | opera:config#Fonts|Dialog | 12,4,0,0,0,0,Nimbus Sans L [urw] | 14,4,0,0,0,0,AR PL UMing TW MBE [unknown] |
Browser Menu Fonts for Traditional Chinese | opera:config#Fonts|Menu | 12,4,0,0,0,0,Nimbus Sans L [urw] | 14,4,0,0,0,0,AR PL UMing TW MBE [unknown] |
Browser Panel Fonts for Traditional Chinese | opera:config#Fonts|Panel | 12,4,0,0,0,0,Nimbus Sans L [urw] | 14,4,0,0,0,0,AR PL UMing TW MBE [unknown] |
Browser Toolbar Fonts for Traditional Chinese | opera:config#Fonts|Toolbar | 12,4,0,0,0,0,Nimbus Sans L [urw] | 14,4,0,0,0,0,AR PL UMing TW MBE [unknown] |
Browser Tooltip Fonts for Traditional Chinese | opera:config#Fonts|Tooltip | 12,4,0,0,0,0,Nimbus Sans L [urw] | 14,4,0,0,0,0,AR PL UMing TW MBE [unknown] |
Web Page Normal Text Font | opera:config#Fonts|Normal | 16,4,0,0,0,0,Nimbus Roman No9 L [urw] | 16,4,0,0,0,0,AR PL UMing TW MBE [unknown] |
Web Page <pre> Text Font | opera:config#Fonts|PRE | 16,4,0,0,0,0,Nimbus Mono L [urw] | 16,4,0,0,0,0,AR PL UKai TW MBE [unknown] |
[Preferred fonts] | |||
Feature | opera:config Link | Opera Default | Nalakuvara Tweak |
Preferred Traditional Chinese Font | N/A | Nimbus Sans L [urw] | AR PL UMing TW MBE [unknown] |
[Preferred fonts monospace] | |||
Feature | opera:config Link | Opera Default | Nalakuvara Tweak |
Preferred Traditional Chinese Monospace Font | N/A | Nimbus Mono L [urw] | AR PL UKai TW MBE [unknown] |
[CSS Generic Font Family] | |||
Feature | opera:config Link | Opera Default | Nalakuvara Tweak |
Generic CSS Sans-Serif Font Family | opera:config#CSSGenericFontFamily|Sans-Serif | Nimbus Roman No9 L [urw] | AR PL UMing TW MBE [unknown] |
Generic CSS Serif Font Family | opera:config#CSSGenericFontFamily|Serif | Nimbus Mono L [urw] | AR PL UKai TW MBE [unknown] |
Which results the following /usr/share/opera/operadefaults.ini
:
; Put any default settings here that are overridable by users [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 NavigationBar Alignment=2 NavigationBar Auto Alignment=1 [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 [Fonts] Menu=14,4,0,0,0,0,AR PL UMing TW MBE [unknown] Toolbar=14,4,0,0,0,0,AR PL UMing TW MBE [unknown] Dialog=14,4,0,0,0,0,AR PL UMing TW MBE [unknown] Panel=14,4,0,0,0,0,AR PL UMing TW MBE [unknown] Tooltip=14,4,0,0,0,0,AR PL UMing TW MBE [unknown] Normal=16,4,0,0,0,0,AR PL UMing TW MBE [unknown] PRE=16,4,0,0,0,0,AR PL UKai TW MBE [unknown] [Preferred fonts] 59=AR PL UMing TW MBE [unknown] [Preferred fonts monospace] 59=AR PL UKai TW MBE [unknown] [CSS Generic Font Family] Sans-Serif=AR PL UMing TW MBE [unknown] Serif=AR PL UKai TW MBE [unknown]
This is just a workaround, not a solution, for Ming (明體) is not a Sans-Serif font. Using this setting, web pages in English do not looks well. Limited by Linux's default fonts availability, Nalakuvara hardly tweaks better.
Some Linux distributions are more lucky. Ubuntu has two Traditional Chinese Gothic font (文泉驛等寬正黑 and 文泉驛正黑, monospace and not) installed by default, which are Sans-Serif, and better in quality. That is why Nalakuvara provides an alternative default for Ubuntu users:
[Fonts] | |||
---|---|---|---|
Feature | opera:config Link | Opera Default | Nalakuvara Tweak |
Browser Dialog Fonts for Traditional Chinese | opera:config#Fonts|Dialog | 12,4,0,0,0,0,Nimbus Sans L [urw] | 14,4,0,0,0,0,文泉驛正黑 [unknown] |
Browser Menu Fonts for Traditional Chinese | opera:config#Fonts|Menu | 12,4,0,0,0,0,Nimbus Sans L [urw] | 14,4,0,0,0,0,文泉驛正黑 [unknown] |
Browser Panel Fonts for Traditional Chinese | opera:config#Fonts|Panel | 12,4,0,0,0,0,Nimbus Sans L [urw] | 14,4,0,0,0,0,文泉驛正黑 [unknown] |
Browser Toolbar Fonts for Traditional Chinese | opera:config#Fonts|Toolbar | 12,4,0,0,0,0,Nimbus Sans L [urw] | 14,4,0,0,0,0,文泉驛正黑 [unknown] |
Browser Tooltip Fonts for Traditional Chinese | opera:config#Fonts|Tooltip | 12,4,0,0,0,0,Nimbus Sans L [urw] | 14,4,0,0,0,0,文泉驛正黑 [unknown] |
Web Page Normal Text Font | opera:config#Fonts|Normal | 16,4,0,0,0,0,Nimbus Roman No9 L [urw] | 16,4,0,0,0,0,文泉驛正黑 [unknown] |
Web Page <pre> Text Font | opera:config#Fonts|PRE | 16,4,0,0,0,0,Nimbus Mono L [urw] | 16,4,0,0,0,0,文泉驛等寬正黑 [unknown] |
[Preferred fonts] | |||
Feature | opera:config Link | Opera Default | Nalakuvara Tweak |
Preferred Traditional Chinese Font | N/A | Nimbus Sans L [urw] | 文泉驛正黑 [unknown] |
[Preferred fonts monospace] | |||
Feature | opera:config Link | Opera Default | Nalakuvara Tweak |
Preferred Traditional Chinese Monospace Font | N/A | Nimbus Mono L [urw] | 文泉驛等寬正黑 [unknown] |
[CSS Generic Font Family] | |||
Feature | opera:config Link | Opera Default | Nalakuvara Tweak |
Generic CSS Sans-Serif Font Family | opera:config#CSSGenericFontFamily|Sans-Serif | Nimbus Roman No9 L [urw] | 文泉驛正黑 [unknown] |
Generic CSS Serif Font Family | opera:config#CSSGenericFontFamily|Serif | Nimbus Mono L [urw] | AR PL UKai TW MBE [unknown] |
So Ubuntu users get following /usr/share/opera/operadefaults.ini
:
; Put any default settings here that are overridable by users [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 NavigationBar Alignment=2 NavigationBar Auto Alignment=1 [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 [Fonts] Menu=14,4,0,0,0,0,文泉驛正黑 [unknown] Toolbar=14,4,0,0,0,0,文泉驛正黑 [unknown] Dialog=14,4,0,0,0,0,文泉驛正黑 [unknown] Panel=14,4,0,0,0,0,文泉驛正黑 [unknown] Tooltip=14,4,0,0,0,0,文泉驛正黑 [unknown] Normal=16,4,0,0,0,0,文泉驛正黑 [unknown] PRE=16,4,0,0,0,0,文泉驛等寬正黑 [unknown] [Preferred fonts] 59=文泉驛正黑 [unknown] [Preferred fonts monospace] 59=文泉驛等寬正黑 [unknown] [CSS Generic Font Family] Sans-Serif=文泉驛正黑 [unknown] Serif=AR PL UKai TW MBE [unknown]
It is very important to ensure UTF-8 encoding is used in the .ini
files, especially when dealing with preferences in Traditional Chinese such as font names.
Opera by default includes some web mail service providers with OPERA_INSTALL_PATH\defaults\webmailproviders.ini
. By editing this file, we could comment out those unpopular, and add some more popular for Taiwanese users:
Opera Preferences version 2.1 ; Do not edit this file while Opera is running ; This file is stored in UTF-8 encoding ; %t = to ; %j = subject ; %m = body ; %k = cc ; %l = bcc ; %s = full mailto URI ; i.e., %s = to=%t&subject=%j&body=%m&cc=%k&bcc=%l ;[Yandex] ;ID=4 ;URL=http://mail.yandex.ru/compose?mailto=%s ;ICON=http://img.yandex.net/i/favicon.ico ;[Fastmail] ;ID=5 ;URL=http://www.fastmail.fm/action/compose/?mailto=%s ;ICON=http://www.fastmail.fm/favicon.ico [Opera Web Mail] ID=6 URL=http://mymail.operamail.com/scripts/mail/Outblaze.mail?compose=1&did=1&a=1&to=%t&subject=%j&body=%m&cc=%k ICON=http://www.opera.com/favicon.ico ;[Mail.ru] ;ID=7 ;URL=http://win.mail.ru/cgi-bin/sentmsg?To=%t&CC=%k&BCC=%l&Subject=%j&Body=%m ;ICON=http://img.imgsmail.ru/r/favicon.ico [Gmail - HTML5] ID=8 URL=https://mail.google.com/mail/?extsrc=mailto&url=%s ICON=https://mail.google.com/favicon.ico [Gmail] ID=9 URL=https://mail.google.com/mail/?compose=1&view=cm&fs=1&to=%t&su=%j&body=%m&cc=%k&bcc=%l ICON=https://mail.google.com/favicon.ico [Hotmail] ID=10 URL=http://mail.live.com/mail/EditMessageLight.aspx?n=&to=%t&cc=%k&subject=%j&body=%m&bcc=%l ICON=http://mail.live.com/favicon.ico [Ymail - Generic] ID=11 URL=http://compose.mail.yahoo.com/?To=%t&Subj=%j&Body=%m&Cc=%k&Bcc=%l ICON=http://mail.yahoo.com/favicon.ico [Ymail - Classic Compose + New UI] ID=12 URL=http://us.mg1.mail.yahoo.com/mc/compose?ymv=0&body=%m&Subj=%j&to=%t&cc=%k&bcc=%l ICON=http://mail.yahoo.com/favicon.ico [Ymail - New UI + Blocking Workaround] ID=13 URL=http://us.mg1.mail.yahoo.com/dc/launch?sysreq=ignore&action=compose&login=1&To=%t&Subj=%j&Cc=%k&Bcc=%l&Body=%m ICON=http://mail.yahoo.com/favicon.ico [Mail2000] ID=14 URL=http://www.mail2000.com.tw/cgi-bin/genMail.pl?adr=%t&content=%m&subject=%j ICON=http://www.mail2000.com.tw/favicon.ico [PChome Mail] ID=20 URL=http://mail.pchome.com.tw/compose_content?MailTo=%t&MailSubject=%j&MailCc=%k&MailBcc=%l&text2=%m ICON=http://www.pchome.com.tw/favicon.ico [Webmail@URL (wm1)] ID=21 URL=http://wm1.url.com.tw/src/compose.php?mailbox=INBOX&startMessage=1&send_to=%t&sed_to_cc=%k&send_to_bcc=%l&subject=%j&body=%m ICON=http://www.url.com.tw/images/url.ico [Webmail@URL (wm2)] ID=22 URL=http://wm2.url.com.tw/src/compose.php?mailbox=INBOX&startMessage=1&send_to=%t&sed_to_cc=%k&send_to_bcc=%l&subject=%j&body=%m ICON=http://www.url.com.tw/images/url.ico [Webmail@URL (wm3)] ID=23 URL=http://wm3.url.com.tw/src/compose.php?mailbox=INBOX&startMessage=1&send_to=%t&sed_to_cc=%k&send_to_bcc=%l&subject=%j&body=%m ICON=http://www.url.com.tw/images/url.ico [Webmail@URL (wm4)] ID=24 URL=http://wm4.url.com.tw/src/compose.php?mailbox=INBOX&startMessage=1&send_to=%t&sed_to_cc=%k&send_to_bcc=%l&subject=%j&body=%m ICON=http://www.url.com.tw/images/url.ico [Webmail@URL (wm5)] ID=25 URL=http://wm5.url.com.tw/src/compose.php?mailbox=INBOX&startMessage=1&send_to=%t&sed_to_cc=%k&send_to_bcc=%l&subject=%j&body=%m ICON=http://www.url.com.tw/images/url.ico [Webmail@URL (wm6)] ID=26 URL=http://wm6.url.com.tw/src/compose.php?mailbox=INBOX&startMessage=1&send_to=%t&sed_to_cc=%k&send_to_bcc=%l&subject=%j&body=%m ICON=http://www.url.com.tw/images/url.ico [Webmail@URL (wm7)] ID=27 URL=http://wm7.url.com.tw/src/compose.php?mailbox=INBOX&startMessage=1&send_to=%t&sed_to_cc=%k&send_to_bcc=%l&subject=%j&body=%m ICON=http://www.url.com.tw/images/url.ico [Webmail@URL (wm8)] ID=28 URL=http://wm8.url.com.tw/src/compose.php?mailbox=INBOX&startMessage=1&send_to=%t&sed_to_cc=%k&send_to_bcc=%l&subject=%j&body=%m ICON=http://www.url.com.tw/images/url.ico [Webmail@URL (wm9)] ID=29 URL=http://wm9.url.com.tw/src/compose.php?mailbox=INBOX&startMessage=1&send_to=%t&sed_to_cc=%k&send_to_bcc=%l&subject=%j&body=%m ICON=http://www.url.com.tw/images/url.ico [Webmail@URL (wm10)] ID=30 URL=http://wm10.url.com.tw/src/compose.php?mailbox=INBOX&startMessage=1&send_to=%t&sed_to_cc=%k&send_to_bcc=%l&subject=%j&body=%m ICON=http://www.url.com.tw/images/url.ico
Nalakuvara adapts a modified OPERA_INSTALL_PATH\custom\defaults\fastforward.ini
from Ibis, which adds more strings to trigger Fast Forward button, then adds some additional strings used in Taiwan. Here is part of it:
;Chinese (traditional and simplified) 前进 继续 翻页 下页 下頁 下篇 后页 后页> 往后>> 下一頁 下一页=101 下一页> 下一页>> 下一个 下一张 下一张 > 下一幅 下一幅 > 下一章 下一节 下一節 下一篇 后一页=90 下一步 翻下页 翻下頁 看下一页 下一页(快捷键→) "[下頁]" "[下页]" "[继续]" "[下一頁]" "[下一页]" "[翻下頁]" "[翻下页]" 下一張 (C) 下一頁 (C)
Default bookmarks and searches could also be modified. Since these two default files could be locale-based, it is much reasonable to so that way. For example, adding more searches in OPERA_INSTALL_PATH\locale\zh-tw\search.ini
only takes effect while using Traditional Chinese UI of Opera:
[Search Engine 1] UNIQUEID=7A8CADE6677811DDBA4B5E9D55D89593 Name= URL=http://www.google.com/search?q=%s&sourceid=opera&num=%i&ie=utf-8&oe=utf-8 ICON=http://redir.opera.com/favicons/google/favicon.ico Query= Key=g Is post=0 Has endseparator=0 Encoding=utf-8 Search Type=0 Verbtext=0 Position=-1 Nameid=17171 UseTLD=1 [Search Engine 2] UNIQUEID=C62302A2FBB8E8469557BD47409F8747 Name=Yahoo!奇摩搜尋 Verbtext=0 URL=http://tw.search.yahoo.com/search?ei=&fr=sfp&fr2=&p=%s&_adv_prop=web&fl=0&vl=0&vf=all&vd=all&iscqry= ICON=http://tw.search.yahoo.com/favicon.ico Query= Key=ys Is post=0 Has endseparator=0 Encoding=utf-8 Search Type=0 Position=-1 Nameid=0 Deleted=0 [Search Engine 3] UNIQUEID=8FF7B2066FB77449B62B04D1D40EF8F8 Name=Bing Verbtext=0 URL=http://www.bing.com/search?q=%s&go=&form=QBLH&filt=all ICON=http://www.bing.com/favicon.ico Query= Key=b Is post=0 Has endseparator=0 Encoding=utf-8 Search Type=0 Position=-1 Nameid=0 Deleted=0 [Search Engine 4] UNIQUEID=AE41FF7A5FC011DDAE47DBEF55D89593 Name=維基百科 URL=http://zh.wikipedia.org/wiki/Special:Search?search=%s ICON=http://redir.opera.com/favicons/wikipedia/favicon.ico Query= Key=w Is post=0 Has endseparator=0 Encoding=utf-8 Search Type=0 Verbtext=0 Position=-1 [Search Engine 26] UNIQUEID=17488DC9AE770545B642C790CAB3C9D2 Name=Internet Archive Verbtext=0 URL=http://web.archive.org/web/*%s ICON=http://www.archive.org/images/logo-16.jpg Query= Key=ia Is post=0 Has endseparator=0 Encoding=big5 Search Type=0 Position=-1 Nameid=0 Deleted=0 [Search Engine 27] UNIQUEID=829D47CC797B29459E6F38E927BABCF2 Name=全國法規資料庫法規名稱檢索 Verbtext=0 URL=http://law.moj.gov.tw/Scripts/SimpleQ.asp?rb=lname&K1=%s Query= Key=jn Is post=0 Has endseparator=0 Encoding=big5 Search Type=0 Position=-1 Nameid=0 Deleted=0 [Search Engine 28] UNIQUEID=B980F29D8FEF9A4D896C5D035DF1270D Name=全國法規資料庫法條內容檢索 Verbtext=0 URL=http://law.moj.gov.tw/Scripts/SimpleQ1.asp?K1=%s&K2=&K3=&K4=&Fusekey=%B1%60%A5%CE%BBy%B7J&rb=la Query= Key=j Is post=0 Has endseparator=0 Encoding=big5 Search Type=0 Position=-1 Nameid=0 Deleted=0 [Search Engine 29] UNIQUEID=F290D3865FC011DD83CDD4F355D89593 Name= URL=http://redir.opera.com/amazon/?q=%s ICON=http://redir.opera.com/favicons/amazon/favicon.ico Query= Key=z Is post=0 Has endseparator=0 Encoding=utf-8 Search Type=0 Verbtext=0 Nameid=69678 Position=-1 [Search Engine 30] UNIQUEID=82EB048A5FCE11DDAFCFE0AA56D89593 Name= URL=http://redir.opera.com/ebay/?q=%s ICON=http://redir.opera.com/favicons/ebay/favicon.ico Query= Key=e Is post=0 Has endseparator=0 Encoding=utf-8 Search Type=0 Verbtext=0 Position=-1 Nameid=69679 [Search Engine 31] UNIQUEID=2C42B3DE30288847A11B871C19A3D7E2 Name=PChome線上購物 Verbtext=0 URL=http://shopping.pchome.com.tw/?m=search&f=doSearch&STYPE=&target=%s&Submit=%A7%E4%B0%D3%AB%7E ICON=http://shopping.pchome.com.tw/favicon.ico Query= Key=pch Is post=0 Has endseparator=0 Encoding=big5 Search Type=0 Position=-1 Nameid=0 Deleted=0 [Search Engine 32] UNIQUEID=6EA8C2D1619F7442827906A8D25E53B0 Name=露天拍賣 Verbtext=0 URL=http://search.ruten.com.tw/search/s000.php?searchfrom=indexbar&k=%s&t=0 ICON=http://www.ruten.com.tw/favicon.ico Query= Key=rb Is post=0 Has endseparator=0 Encoding=big5 Search Type=0 Position=-1 Nameid=0 Deleted=0 [Search Engine 33] UNIQUEID=77C25A05B0E75A4B81DBE19E88644DC5 Name=Yahoo!奇摩拍賣 Verbtext=0 URL=http://tw.search.bid.yahoo.com/search/ac?ei=BIG-5&p=%s ICON=http://tw.bid.yahoo.com/favicon.ico Query= Key=yb Is post=0 Has endseparator=0 Encoding=big5 Search Type=0 Position=-1 Nameid=0 Deleted=0 [Search Engine 34] UNIQUEID=A56370F8D5684A4A82184AA4B796FFCD Name=射手網字幕 Verbtext=0 URL=http://shooter.cn/sub/?searchword=%s&x=0&y=0 ICON=http://shooter.cn/favicon.ico Query= Key=sub Is post=0 Has endseparator=0 Encoding=big5 Search Type=0 Position=-1 Nameid=0 Deleted=0 [Search Engine 35] UNIQUEID=F182FB89FD59FB4BAB0CD8C71E2C3234 Name=海盜灣 BT Verbtext=0 URL=http://thepiratebay.org/search/%s/0/99/0 ICON=http://thepiratebay.org/favicon.ico Query= Key=tpb Is post=0 Has endseparator=0 Encoding=big5 Search Type=0 Position=-1 Nameid=0 Deleted=0 [Search Engine 36] UNIQUEID=016F899833096540B36B4F52569C723A Name=Mininova BT Verbtext=0 URL=http://www.mininova.org/search/?search=%s ICON=http://mnstat.com/images/favicon.ico Query= Key=m Is post=0 Has endseparator=0 Encoding=big5 Search Type=0 Position=-1 Nameid=0 Deleted=0 [Search Engine 37] UNIQUEID=AF5D5F3752D1F84BB2F3D54F9EDD4999 Name=isoHunt BT Verbtext=0 URL=http://isohunt.com/torrents.php?ihq=%s ICON=http://isohunt.com/favicon.ico Query= Key=ih Is post=0 Has endseparator=0 Encoding=big5 Search Type=0 Position=-1 Nameid=0 Deleted=0
Above are part of modified OPERA_INSTALL_PATH\locale\zh-tw\search.ini
in Nalakuvara, featureing more popular searches among Taiwanese users. If you use English or Simplified Chinese UI, you will not see these. So it is quite fine to use Nalakuvara in multiple users situation. search.ini
does more than just defining default searches. I will talk about this later in "Altering Menus and Toolbars" section.
Default bookmarks are locale-based, too. The OPERA_INSTALL_PATH\locale\zh-tw\bookmarks.adr
for Traditional Chinese UI users strips unpopular entries, and adds important Traditional Chinese resource about Opera:
Opera Hotlist version 2.0 Options: encoding = utf8, version=3 #FOLDER ID=11 NAME=回收桶 TRASH FOLDER=YES UNIQUEID=4E1601F6F30511DB9CA51FD19A7AAECA - #FOLDER ID=12 NAME=Opera UNIQUEID=826CF25AF11C491899711FC93513A4F4 #URL ID=13 NAME=Download Opera URL=http://www.opera.com/download/ VISITED=1252173878 UNIQUEID=6346265318C548DC831B7DF6D8EBB577 #URL ID=14 NAME=My Opera Community URL=http://my.opera.com/ ON PERSONALBAR=YES PERSONALBAR_POS=1 UNIQUEID=6081957B53904ED6BAD072D157C8D408 ICONFILE=my.opera.com.ico #URL ID=15 NAME=Opera Web Mail URL=http://www.operamail.com/ UNIQUEID=CF79297898B24364A89ED412D9B43B89 #URL ID=16 NAME=Support Desk URL=http://www.opera.com/support/ VISITED=1252173859 UNIQUEID=BDBBEF1FCB2844A980752782E0D9670C #URL ID=17 NAME=Opera Nalakuvara 三太子 URL=http://Jedi.org/opera/ CREATED=1252173550 DESCRIPTION= UNIQUEID=D4A427CF2F790642909162DED1FCA7D8 #URL ID=18 NAME=Opera 官方論壇正體中文版 URL=http://my.opera.com/tradchinese/forums/ CREATED=1252173758 DESCRIPTION= UNIQUEID=115491135268A74C8E5B2E60C98C13C2 #URL ID=19 NAME=Opera第一手最新消息繁體中文版 URL=http://my.opera.com/ting0619/blog/ CREATED=1252173839 DESCRIPTION= UNIQUEID=AFC07AA46717884BB243A755BD59228A
Please also notice that bookmarks.adr
has to be in UTF-8 encoding, too.
And last, Opera has a built-in function to fake User Agent string. This is because some web sites reject Opera for no reason. Those sites in fact work well in Opera, but they just do not accept Opera's User Agent string. Once Opera fakes itself as Firefox or Internet Explorer, everything goes fine.
Each time Opera is running, it checks and downloads an up-to-dated fake list to %APPDATA%\Opera\OPERA_DIR_NAME\override_downloaded.ini
. Editing this file is a waste of time, since it is always overwritten. All manually site preferences (including fake User Agent string) are stored at %APPDATA%\Opera\OPERA_DIR_NAME\override.ini
. That is our true target:
Opera Preferences version 2.1 ; Do not edit this file while Opera is running ; This file is stored in UTF-8 encoding [Overrides] soweb.kcg.gov.tw web2.cc.ntu.edu.tw [soweb.kcg.gov.tw] User Agent|Spoof UserAgent ID=5 [web2.cc.ntu.edu.tw] User Agent|Spoof UserAgent ID=5
The numeric value of User Agent|Spoof UserAgent ID
means:
1
: identify as Opera, i.e.,Opera/9.80 (Windows NT 5.1; U; zh-tw) Presto/2.2.15 Version/10.00
2
: identify as Firefox, i.e.,Mozilla/5.0 (Windows NT 5.1; U; zh-tw; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 10.00
3
: identify as Internet Explorer, i.e.,Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; zh-tw) Opera 10.00
4
: fake as Firefox, i.e.,Mozilla/5.0 (Windows NT 5.1; U; zh-tw; rv:1.8.1) Gecko/20061208 Firefox/2.0.0
5
: fake as Internet Explorer, i.e.,Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; zh-tw)
Those listed sites are from user reports. I will talk about this later in the "Feedback" section.
3rd Party Components
And there are somethings Opera could not do by itself. As mentioned in "Guidelines" section before, it has no choice but use 3rd party components to achieve some functions. There are several parts we could plug these components into Opera:
- User CSS: put in
OPERA_INSTALL_PATH\styles\user\
by default; - User JavaScript: disabled by default;
- Plug-In: put in
OPERA_INSTALL_PATH\program\plugins\
by default; - Java Applet: requires Java Runtime Environment.
User CSS has minor impacts. CSS, by definition, means Cascade Style Sheets. Opera is the one browser that implements CSS web standard cascade-like. Users could apply multiple user CSS cascading. With the power of CSS, Opera has already achieved some leading functions such as Fit Width. Opera is also the one browser that implements all CSS3 selectors. Opera@USB, for example, includes some handy advertisement blocking functions purely via CSS.
User CSS could be applied or disapplied on demand through View menu in Opera. Other ways, such as through Toolbar buttons, are, however, quite difficult. The Opera's internal command "Select user CSS file
" targets particular CSS file by its order in the User CSS path. In order to make buttons using User CSS on demand, we have to take control of particular CSS files order.
On Windows, files are arranged by its filename. I take CSS files from Opera@USB, rename them to 000_Antiflash.css
and 000_bantiad.css
to make sure they are the first two files among all. On Linux or FreeBSD, however, do not work that way. So sad these buttons work only on Windows. I will talk about these buttons later, in "Altering Menus and Toolbars" section.
000_Antiflash.css
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 size of images in 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 selector.
User JavaScript extends more possibility but might bring compatibility and security issue, and is disabled by default. To enable User JavaScript feature, tweak 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, OPERA_INSTALL_PATH\custom\defaults\operaprefs.ini
on Windwos should be:
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, rethink again, and warn users explicitly too.
User JavaScript File
could be either 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 here is that working directory is different on Windows and on Linux/FreeBSD. On Windows, Opera's working directory is where opera.exe
is located, i.e., OPERA_INSTALL_PATH
. On Linux or 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
makes OPERA_INSTALL_PATH\userjs\
on Windows, ~/userjs/
on Linux or FreeBSD.
Nalakuvara chooses User JavaScript based on guidelines carefully. Here is my final list:
- AdBlock Plus to block web elements using CSS selector.
- Auotsizer 2 to resize large images;
- CustomizeGoogle to customize Google services as the Firefox extension "CustomizeGoogle" does;
- HanConvert to convert characters between Traditional Chinese and Simplified Chinese;
- HTML Ruby to expand W3C Ruby Annotation support in Opera;
- Open in Background with Long Press to open link to new tab in background with long mouse press;
- Textarea Backup with Emulate GM functions to backup <textarea> input automatically.
The pure-JavaScript version of AdBlock Plus uses CSS attribution selector and optional CSS3 nth-child
selector to target web elements to block. All "blocker" CSS rules are stored in cookies. All AdBlock Plus functions could be accessed via Toolbar buttons, which will be discussed in "Altering Menus and Toolbars" section, and hotkeys:
- 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 lets users click on large images to resize it to fit browser window size. Click again to restore its original size. It also uses cookies to store this resize setting for each image.
CustomizeGoogle uses a separate customizegoogle_prefs.js
to adjust its behavior. Here is the predefined option 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 Continuous | 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) |
false |
Google Cache /* cachetab */ | ||
Options | Description | Nalakuvara's Predefined Value |
cache.continue | Rewrite Links to Google Cached | 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)
|
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 is not a mature solution yet. It could not translate between Traditional Chinese and Simplified Chinese yet. It can, however, at least do characters level conversion between these two language. Next step will be improving it to phrase level conversion. Later, full translation maybe. HanConvert could be accessed via Toolbar buttons, which will be discussed later, in "Altering Menus and Toolbars" section. There is also another User JavaScript file to enable conversion automatically for all web pages; this is undesirable for it does too much compared with Opera's clean nature.
Opera follows W3C Web Standards but fails on W3C Ruby Annotation. HTML Ruby makes up this gap via JavaScript and CSS. It comes with a seperate ruby.settings.js
to adjust its behavior:
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)
|
-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, too.
Open in Background with Long Press is for those who do not use mouse gesture. It works only on actual <a> links. Sadly some users reported that this User JavaScript might slow down web games on Facebook. Nalakuvara notes this issue before insltalling it.
Textarea Backup is a Greasemonkey User JavaScript. It 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 Stored, in Seconds. | 3600 |
Again, Nalakuvara prompts users to change these values upon installation.
Remember: if and only if any of User JavaScript above is installed, enable and tweak User JavaScript related preferences in operaprefs,ini
.
Finally, there are Plug-Ins to connect Opera to other applications. Usually Plug-Ins are platform specified and thus will not be cross-platformed. There is only one Plug-In used in Nalakuvara, and only available on Windows: npviewinie, to render web pages using IE's trident engine without leaving Opera, just like Firefox extension "IE Tab" does.
The core of npviewinie is a npie_opera.dll
, which should be in OPERA_INSTALL_PATH\program\plugins\
or anywhere listed in the opera:config#UserPrefs|PluginPath preference. Then we could embed an ie_opera
object using an <embed>
tag with type="application/ie_opera"
attribution. This, too, could be performed via a Toolbar button, which will be discussed later, in "Altering Menus and Toolbars" section. There is also a seperate Autorender.in.IE.js
to load listed web pages with ie_opera
object automatically. This Autorender.in.IE.js
, surely, should be in the User JavaScript path, with related perferences 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 invoked by Administrator:
bcdedit /set nx alwaysoff
Users have to reboot their system to take effect, too. With DEP disabled, other security issues might be raised. This infomation should be revealed to users, too.
Java Applets, on the other hand, provides a cross-platformed solution, which might be slower but work just fine. If users do not have JRE installed before, Opera might prompt to install JRE at the first run of any Java Applet. On some platforms users have to install JRE through system's package management system. On Ubuntu, for example, one has to intsall sun-java6-bin package via Synaptic Package Manager to make Java Applet work.
Nalakuvara uses ZTerm Applet to handle telnet://
and ssh://
protocols which are necessary for telnet-based BBS. There are two different ways to include this 3rd party component into Nalakuvara: install files locally, or use applet page hosted at http://ztermapplet.z6i.org/. Either way, ZTerm Applet stores its preferences in a .ztermrc
file. This file is located at %USERPROFILE%
on Windows, ~
on Linux/FreeBSD.
By default, ZTerm Applet uses IE as an external browser on Windows, and Firefox on Linux/FreeBSD. We could predefine it to Opera by editing .ztermrc
:
external-browser-command::opera %u
On Linux, we could 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
And the applet page (local or remote) could be accessed via Bookmark, Bookmarklet, or Toolbar button. I prefer using Toolbar button and will talk about this later in "Altering Menus and Toolbars" section.
Altering Menus and Toolbars
With 3rd party components installed, there should be some ways to access them conveniently. Toolbar buttons is one of the best practical ways. New features (buttons) could be hidden by default, preserving Opera's default UI layout; users could 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"="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, "Select user CSS file"="Select user CSS file, 0, , "Flash Blocker 啟用中", "Transfer Loading" > Deselect user CSS file, 0, , "Flash Blocker 已停用", "Transfer Failure"" Button2, "Select user CSS file"="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(){var h=location.href;if(!h||/^(javascript|about|opera):/i.test(h)){return}window.open().document.write('<html>'+'<head>'+'<title>'+(document.title?document.title:location.href).replace(/</g,'<')+' - view in ie</title>'+'<style type=\x22text/css\x22>body{margin:0;padding:0;}embed{width:100\x25;height:100\x25;}</style>'+'</head>'+'<body>'+'<script type=\x22text/javascript\x22'+'src=\x22data:text/javascript,'+encodeURIComponent('document.write(\'<embed type=\x22application/viewinie\x22 param-location=\x22'+location.href+'\x22></embed>\');')+'\x22>'+'</script>'+'</body>'+'</html>')})();", , "View in IE", "View"" Button9, "View in IE Same Tab"="Go to page, "javascript:(function(){var h=location.href;if(!h||/^(javascript|about|opera):/i.test(h)){return}document.write('<html>'+'<head>'+'<title>'+(document.title?document.title:location.href).replace(/</g,'<')+' - view in ie</title>'+'<style type=\x22text/css\x22>body{margin:0;padding:0;}embed{width:100\x25;height:100\x25;}</style>'+'</head>'+'<body>'+'<script type=\x22text/javascript\x22'+'src=\x22data:text/javascript,'+encodeURIComponent('document.write(\'<embed type=\x22application/viewinie\x22 param-location=\x22'+location.href+'\x22></embed>\');')+'\x22>'+'</script>'+'</body>'+'</html>')})();", , "View in IE Same Tab", "View"" Button10, "繁"="Go to page, "javascript:void(TongWen.trans2Trad(document));", , "繁", "A"" Button11, "简"="Go to page, "javascript:void(TongWen.trans2Simp(document));", , "简", "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?autoload=%7B%22modules%22%3A%5B%7B%22name%22%3A%22language%22%2C%22version%22%3A%221%22%7D%5D%7D\'></script><script type=\'text/javascript\'>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();", 1, "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 here will show up in the "My buttons." The main problem here is that users might install different 3rd party components and one standard_toolbar.ini
could not fit them all. During installation/patch process, Nalakuvara copies one of sixteen predefined standard_toolbar.ini
to OPERA_INSTALL_PATH\ui\
according to users' selection.
The modified standard_toolbar.ini
is renamed to "Opera Nalakuvara Standard" to distinguish with the original one. What if it just does not show up? No problem, users could still install Nalakuvara's customized buttons from user documents, which will be discussed later, in "User Documents" section.
Menus are a little tricky. By Nalakuvara's guidelines, there should be as less change as possible in menus. The only "have-to" is Opera's built-in dictionary function.
By default, "Opera Standard" menu contains one Hotclick (right-click) search entry for Merriam-Webster Online Dictionary, one for English Wikipedia, and one set of translation function 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. For Taiwanese users, however, 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 is better to include these feature into Hotclick searches.
The goal here is to expand "Dictionary" and "Encyclopedia" entries to submenus (original Merriam-Webster Online Dictionary and English Wikipedia), and tweak "Translate" submenu to fit the need 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 is through three files:
LANGUAGE_CODE.lng
which changes menu text according to specific UI language;search.ini
which defines actual Hotclick searches;standard_menu.ini
which defines actual Hotclick menu.
The default searches are predefined in the search.ini
. Just like bookmarks.adr
of default bookmarks, search.ini
could be locale-based. This makes more sense for we could tweak above menu just for Taiwanese users, i.e., those who use Traditional Chinese UI language.
Let us start with Hotclick translate submenu. The [Translate menu]
section of OPERA_INSTALL_PATH\ui\standard_menu.ini
is as below:
[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
Then modify OPERA_INSTALL_PATH\locale\zh-tw\zh-tw.lng
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
to change 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" submenu works now. Now let us expand "Dictionary" and "Encyclopedia" entries to submenus by modifying [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 identifier. We have to add these two strings in OPERA_INSTALL_PATH\locale\zh-tw\zh-tw.lng
too:
999999999="查字典(D)" 999999998="查百科(P)"
Do not forget to define 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 in 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=472C462C512C182C162C132C202C192C532C122C142C172C482C572C242C252C262C292C302C312C322C332C342C352C362C372C392C382C412C422C432C452C502C&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 which Search Type
is not 0
will not be shown in Search Bar, but could be invoked by "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 Hotclick menu could be locale-based, we could do further for English, Simplified Chinese, or any other UI languages. In sum, this following table describes language files changing:
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 do this is that some Taiwanese users might use computer in other countries, such as America and China, and not always be able to use Opera with Traditional Chinese UI. With English and Simplified Chinese UI predefined, these users could also use tweaked menu, too.
The English (en
) and the Simplified Chinese (zh-cn
) versions of search.ini
are different with the Traditional Chinese (zh-tw
) one. Most locale-specific searches are preserved during Nalakuvara's editing process.
This is not over yet. Encoding is always a big problem in CJK, so Taiwanese users often switch web page encoding. Many users asked if encoding submenu could be included in the right click menu. Here you are:
[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
Right, here is introduced another two 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 multiple languages:
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 |
Packing
Nalakuvara is almost done. We now have to pack bits and bytes into one.
On Windows, I first compile AutoHotKey scripts into .exe
executive, then pack all necessary files into RAR SFX archive. RAR SFX archive could launch specific file upon file extraction. You could use NSIS too. RAR SFX is much easier to extract by standalone application, but sadly could not handle multiple languages well.
On Linux/FreeBSD, packing is quite simple. Just make tarballs. I specially use different tarball formats for different platforms: tar.bz2
for Ubuntu (deb) and FreeBSD, tar.gz
for Fedora (rpm), tgz
for generic Linux. This somehow helps users to distinguish their downloads.
To help users make sure that their downloads are intact, the file download page also provides MD5 checksum of each files. MD5, however, is a little too geeky. In order to help average users, there is a standalone file checker based on MD5 checksum and compiled from AutoHotKey script too. It is the one checker to check them all. If the downloaded file belongs to any one of the current releases, it reports file's detail, otherwise it asks users to download again. By providing this checker, novice users and advanced users could both make sure that their download file is correct with no trouble.
Documentation
Documentation is the basis for communication. I spend more time on documentation then coding/scripting. The importance of documentation is very clear; otherwise this article would not appear.
Documentation is just like making Nalakuvara: you have to fit the needs of geek and average users. User documents help users to understand the whole project, know where to tweak options back if needed, or how to apply changes manually. Geek documents are for geeks, for those who want to know actual process behind Nalakuvara, and for those who want to do a similar project.
Because Nalakuvara is for Taiwanese users, currently all documents are only in Traditional Chinese. This article you are reading now is the first English document of Nalakuvara.
User Documents
Nalakuvara documents often update, so they are only available on web so far. Main index of Nalakuvara describes the history of this project, TODOs, and knwon issues. Feature page introduces guidelines of Nalakuvara, details all features with screenshots, and links to add customized buttons. Download page lists all available downloads of current Nalakuvara version, with some supplied files such as script to enable mouse gesture trail. Change Log page records all changes since the first release of Nalakuvara. Users who use Patch Package will be led to the patched result page, which provides information in regard to several Nalakuvara's tweaked defaults, such as bookmarks and Toolbar buttons. In case Nalakuvara's patch does not work, users still know how to fix them by theirselves.
All these documents are user-oriented. This means that all information is in plain language, with images, lists, and tables to facilitate understanding. With these documents on hand, most users could easily find what they need, and I could easily answer most user questions by providing a single URL.
Geek Documents
Geek documents provide something extra for geek. Technical details page is just like a shorter version of this article, which explains many things, including how and why I made certain decisions, and how I implement all of those.
For hardcore geek, however, the actual documents are within scripts source. That is right, all scripts are commented nicely, line-by-line, in Traditional Chinese. There are even more details in those comments than in this article. (Would anyone like to see thousands lines of code in this article? I doubt that.) Studying these scripts, one could not only learn how to modify Opera, but also learn some AutoHotKey basis.
Geek documents help geeks to truly take control of Nalakuvara. I myself is one of its biggest beneficiary. Weeks have passed, I could still tell which line of the codes is doing what at a glance.
Test and Release
Packages could not be released even when files are well packed and documents are fully updated. It must be tested first. Also how should I release these packages is a question to consider first. In the following passage I will talk about these: test and release.
Test Environment
The first step of test is to prepare test environments. As mentioned before, virtual machine helps a lot. For any one of the platforms (OSes), it is better to take several snapshots to test with:
- Brand new default intsallation;
- Brand new default installation with all service packs from venders;
- Brand new customized installation;
- Brand new customized installation with all service packs from venders;
- Brand new customized installation with all service packs from venders, and Opera 9.64 is installed with default options;
- Brand new customized installation with all service packs from venders, and Opera 9.64 is installed with customized options;
- Brand new customized installation with all service packs from venders, and Opera 10.00 is installed with default options;
- Brand new customized installation with all service packs from venders, and Opera 10.00 is installed with customized options;
- Brand new customized installation with all service packs from venders, with 3rd party web browser as system's default web browser;
- Upgrade installation from previous versions.
You could add more situations in the list above. However, once you could make sure there will not be difference in certain situations, you should eliminate them to prevent from wasting time.
Route
A "route" is how users complete one process. Take Full Installation Package as an example, there are 249 possible routes. Nightmare begins with 10 test situations times 10 different systems, which makes 24,900 routes to test in total. It is quite impossible to fulfil them all. But at least you should perform all 249 routes in one situation, one system. Once or twice I was too lazy to do all the test, and some packages just fail stupidly.
Tips: save your own time by doing unit test. 249 routes could be two units with only 20 routes in total. You could also use debug code to help you:
; debug mode switch DEBUGMODE = 1 ; blah blah blah... ; ; some code here ; ; yada yada yada... ; print debug message only when debug mode is on if ( DEBUGMODE = "1" ) { MsgBox, 64, DEBUG MESSAGE, variable foo = %foo% } ; blah blah blah... ; ; code continues ; ; yada yada yada...
Deploy
Test goes well. It is time to make project release public. Since I am using Perforce as version control system, that is the same way I pull updates to my web server. I set up a crontab
:
P4PORT=HOST:PORT P4USER=USERNAME 45 * * * * /usr/local/bin/p4 sync
This keeps files up-to-date hourly. It is enough for minor changes or routine maintenance. When I am ready to release a new build, just manually do p4 sync
. Please note that by default p4 login
gets a ticket that only validates for 43,200 seconds (i.e., 12 hours). In order to keep crontab
working, you have to first specify Timeout: unlimited
with p4 group
command to create a group of users issued tickets that never expire.
My web server, on the other hand, has another problem. I host my web server with a 10M/2M ADSL connection, thus it could not serve more than 2Mbps outgoing bandwidth in total. There are still a few ways to balance traffic:
Coral Content Distribution Network (CoralCDN) provides a free peer-to-peer content distribution network. Just append .nyud.net
to the hostname part of file downloading URLs:
<a href="http://Jedi.org.nyud.net/p4/Opera/pub/Release/Opera-10.00.Nalakuvara-RC2.exe">download</a>
I also use file hosting services such as RapidShare and other mirror sites to provide alternative downloads. Do not forget to provide file checksums (MD5/SHA1/SHA256 or so) to verify files.
Community
Community is the core value of any software projects. It is important to feed information to community, and get feedback from it.
Feed
When your project is exposed to public, thousands of visitors come. Most visitors come to visit only once; only very few will be back again. It means that most people will not pay much attention to any project.
If you want people to keep knowing your project progress, you have to do something. Feed, for example, is good to do this trick. People might subscribe your feeds during their one-time visit, and might come back again if you publish something interesting via feeds. There are also many other communication channels, such as Twitter or Plurk, which basically do the same job.
The point here is to create a "laziness-friendly" environment, so that people would like to involve at the first time.
Once the channel is set, talk often. Every time you find a bug, fix a bug, add a feature, write a document, or so, let people who scribed/followed to know. Feed your users and they will gather and grow up. That is the beginning of the community.
Feedback
The community, however, could not only rely on one-way communication. You have to listen to and talk to members. Some channels, such as Twitter and Plurk, are capable to joint conversation. You should use social platform where users used to be, too. Remember those place when doing background analysis? I spend lots of time on related forum like Ptt BBS every day. How users use your work might quite differ from your knowledge. The need of users evolves from time to time, so your project should evolve too. Of course, you still have to keep the guidelines in mind.
The fake User Agent string list mentioned in the end of "Tweak Defaults" section is one of the results of community contribution. About a month ago, I started a spreadsheet on Google Docs and Spreadsheets. The privilege of that spreadsheet is set to public, and every one is welcome to edit freely. Later I post this spreadsheet URL at Ptt BBS, and users start to contribute their finding.
It is neither easy nor simple to manage a community. Nalakuvara has a long way to go, and I still have a lot to learn. In the mean while, I want to recommand a new book, "The Art of Community," which is written by Jono Bacon, the Ubuntu Community Manager, and is published by O'Reilly. The best part of it is that this book is also released online under a Creative Commons Attribution-NonCommercial-ShareAlike license. Why not get a free PDF download right now?
Conclusion
There are many different ways to do things. You could do it quick-and-dirty, or make it step-by-step. From a long-term point of view, I believe that a solid path make things much easier. Even readers out of browser world still benefit from these details. That is why I take time to write documents and articles like this one.
Opera itself evolves, too. One day Opera might reach perfection and cover all features from Nalakuvara. At that time, there will be no need to continue Nalakuvara project. However, with all these documents, all contribution and community interaction will not be in vain.
Note: This article is published at Opera Developer Community, edited and splitted into 4 parts: Part 1, Part 2, Part 3, and Part 4.