|
| 1 | +# RFC Template |
| 2 | + |
| 3 | +- Start Date: 2025-02-20 |
| 4 | +- RFC PR: [electron/rfcs#0015](https://github.com/electron/rfcs/pull/15) |
| 5 | +- Electron Issues: https://github.com/electron/electron/issues/33692 |
| 6 | +- Reference Implementation: |
| 7 | +- Status: **Active** |
| 8 | + |
| 9 | +# Hyphenation data support |
| 10 | + |
| 11 | +## Summary |
| 12 | + |
| 13 | +Chromium uses a folder called `hyphen-data` downloaded after installation to enable automatic hyphenation of words in various |
| 14 | +languages. This RFC is to make the same hyphenation feature available to Electron apps. |
| 15 | + |
| 16 | +## Motivation |
| 17 | + |
| 18 | +One of the promises of Electron is that it renders the same as Chromium. Without hyphenation, this is not the case for |
| 19 | +languages like German or Dutch. As a result, text in these languages is not hyphenated across different text lines, |
| 20 | +causing the text to have different dimensions, break at different places and generally look worse than in Chromium. |
| 21 | + |
| 22 | +Adding support for hyphenation data will bring the rendering of long words across text lines in line with the rendering |
| 23 | +in Chromium |
| 24 | + |
| 25 | +## Guide-level explanation |
| 26 | + |
| 27 | +We propose an API for hyphenation data similar to the existing [spellChecker API](https://www.electronjs.org/docs/latest/tutorial/spellchecker) in Electron. The reason for this is that spell checking data in Chromium is similarly downloaded on launch (rather than shipping with the renderer) and Electron replicates this behavior. |
| 28 | + |
| 29 | +### Enabling hyphenation |
| 30 | + |
| 31 | +To enable hyphenation in your Electron app, you can use the following code: |
| 32 | + |
| 33 | +```javascript |
| 34 | +const myWindow = new BrowserWindow({ |
| 35 | + webPreferences: { |
| 36 | + hyphenation: true |
| 37 | + } |
| 38 | +}) |
| 39 | +``` |
| 40 | +_We should consider making this behavior the default, as the spellChecker API is also enabled by default_ |
| 41 | + |
| 42 | +This will enable hyphenation for the languages that are supported by the hyphenation data files, which is automatically downloaded. |
| 43 | + |
| 44 | +### Session APIs and events |
| 45 | + |
| 46 | +Like spellChecker, there should be an number of session methods and events available: |
| 47 | + |
| 48 | +**Instance methods** |
| 49 | + |
| 50 | +- `ses.setHyphenationEnabled(enable)` - sets whether to enable hyphenation. |
| 51 | +- `ses.isHyphenationEnabled()` - returns `boolean` Whether hyphenation is enabled |
| 52 | + |
| 53 | +**Instance Properties** |
| 54 | + |
| 55 | +- `ses.hyphenationEnabled` - a `boolean` indicating whether hyphenation is enabled |
| 56 | + |
| 57 | +**Instance Events** |
| 58 | + |
| 59 | +- `hyphenation-data-download-begin` - returns: `event`. Emits when hyphenation data starts downloading. |
| 60 | +- `hyphenation-data-download-success` - returns: `event`. Emits when hyphenation data has been successfully downloaded. |
| 61 | +- `hyphenation-data-download-failure` - returns: `event`. Emits when hyphenation download fails. |
| 62 | + |
| 63 | +_Note: I'm not sure it makes sense to download hyphenation data for just specific languages at once, so omitted that logic here_ |
| 64 | + |
| 65 | +### Use of Google services |
| 66 | + |
| 67 | +Like the spellChecker API, hyphen-data files are downloaded from a Google CDN. If you want to avoid this you can provide an alternative URL to download the hyphen-data from: |
| 68 | +```javascript |
| 69 | +myWindow.webContents.session.setHyphenationDataDownloadURL('https://example.com/hyphen-data/') |
| 70 | +``` |
| 71 | + |
| 72 | + |
| 73 | +### Consideration: list supported languages |
| 74 | + |
| 75 | +The spellcheck API has a method to list the supported languages. We should consider adding a similar method to list the supported languages for hyphenation: |
| 76 | + |
| 77 | +```js |
| 78 | +// an array of all available languages for hyphenation |
| 79 | +const possibleLanguages = myWindow.webContents.session.availableHyphenationLanguages |
| 80 | +``` |
| 81 | + |
| 82 | +## Reference-level explanation |
| 83 | +<!-- This is the technical portion of the RFC. Explain the design in sufficient detail that: |
| 84 | +
|
| 85 | +- Its interaction with other features is clear. |
| 86 | +- It is reasonably clear how the feature would be implemented. |
| 87 | +- Corner cases are dissected by example. |
| 88 | +- Any new dependencies on Chromium code are outlined. |
| 89 | +
|
| 90 | +The section should return to the examples given in the previous section, and explain more fully how |
| 91 | +the detailed proposal makes those examples work. |
| 92 | +
|
| 93 | +--> |
| 94 | + |
| 95 | +Chromium requests hyphenation data via [`ContentBrowserClient::GetHyphenationDictionary()`](https://source.chromium.org/chromium/chromium/src/+/main:content/public/browser/content_browser_client.h;l=2818;drc=b0423977b6ed86291838e90231b036b68784aae3). [`ChromeContentBrowserClient`'s override of this method](https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/chrome_content_browser_client.cc;l=8168;drc=f667feb8a5c6f227b49328ce78a062acc4f81187) uses the [ComponentUpdater](https://source.chromium.org/chromium/chromium/src/+/main:components/component_updater/README.md) to download the data. |
| 96 | + |
| 97 | +In Electron, `GetHyphenationDictionary()` can be overridden by `ElectronBrowserClient`. This needs to download the hyphenation data and then run the callback passed to it with the directory containing the downloaded files. |
| 98 | + |
| 99 | +Downloading the hyphenation data is the difficult part. Electron doesn't use the Component Updater, and manually downloading and extracting the hyphenation data component seems suboptimal. However, the data could instead be downloaded from <https://chromium.googlesource.com/chromium/src/+/refs/heads/main/third_party/hyphenation-patterns/hyb> ([gz'ed path](https://chromium.googlesource.com/chromium/src/+archive/refs/heads/main/third_party/hyphenation-patterns/hyb.tar.gz), 1086 KiB). The component downloaded by Chromium has exactly the same contents as that directory. Alternatively, Electron could move the responsibility of downloading the hyphenation data to the user. |
| 100 | + |
| 101 | +### Listing supported languages |
| 102 | + |
| 103 | +The hyphenation data is stored in one file per language, so listing the supported languages could be as easy as iterating over the contents of the data directory and returning the filenames (stripped of the `hyph-` prefix and the `.hyb` extension). |
| 104 | + |
| 105 | +## Drawbacks |
| 106 | + |
| 107 | +This adds a new API to Electron, which increases the complexity of the API surface. |
| 108 | + |
| 109 | +It also adds a new Google CDN download to Electron, which could be seen as a privacy concern. |
| 110 | + |
| 111 | +## Rationale and alternatives |
| 112 | + |
| 113 | +Conceptually, the hyphenation data is similar to the spellChecker data, which is already available in Electron. Keeping the APIs similar will make it easier for developers to use. |
| 114 | + |
| 115 | +An alternative would be to ship the hyphenation data with Electron and read it from disk, but this would increase the size of the Electron download and would not be in line with the way Chromium handles hyphenation data. |
| 116 | + |
| 117 | +Not adding hyphenation data means that people reading text in languages that make greater use of hyphenation, like German or Dutch, will have a worse experience in Electron than in Chromium. |
| 118 | + |
| 119 | +Because the hyphen-data needs to be read in by the renderer, it is not feasible to implement this in userland. |
| 120 | + |
| 121 | +## Prior art |
| 122 | + |
| 123 | +This feature brings Electron in line with Chromium. |
| 124 | + |
| 125 | +## Unresolved questions |
| 126 | + |
| 127 | +- Where should Electron download the hyphenation data from? |
| 128 | +- Should the API be enabled by default? |
| 129 | +- Should we provide a way to list the supported languages for hyphenation? |
| 130 | + |
| 131 | +## Future possibilities |
| 132 | + |
| 133 | +The primary goal is to bring Electron in line with Chromium. |
0 commit comments