Commit b6aae74c authored by Alex Brazier's avatar Alex Brazier

Tidy up spell checker and fix contractions

parent a20901f7
......@@ -26,7 +26,11 @@
"mac": {
"helperBundleId": "chat.rocket.electron.helper",
"category": "public.app-category.productivity",
"target": ["dmg", "pkg", "zip"]
"target": [
"dmg",
"pkg",
"zip"
]
},
"nsis": {
"include": "build/win/installer.nsh",
......@@ -36,7 +40,10 @@
"allowToChangeInstallationDirectory": true
},
"linux": {
"target": ["deb", "rpm"]
"target": [
"deb",
"rpm"
]
}
},
"scripts": {
......@@ -52,11 +59,11 @@
"e2e": "mocha app/e2e.js.autogenerated --require source-map-support/register"
},
"dependencies": {
"fs-jetpack": "^0.10.5",
"@paulcbetts/system-idle-time": "^1.0.4",
"spellchecker": "^3.3.1",
"electron-rebuild": "^1.5.7",
"fs-jetpack": "^0.10.5",
"lodash": "^4.17.4",
"electron-rebuild": "^1.5.7"
"spellchecker": "^3.3.1"
},
"devDependencies": {
"chai": "^3.5.0",
......
const { ipcRenderer } = require('electron');
class Notification extends window.Notification {
constructor (title, options) {
super(title, options);
ipcRenderer.send('notification-shim', title, options);
// Handle correct notification using unique tag
ipcRenderer.once(`clicked-${options.tag}`, () => this.onclick());
}
get onclick () {
return super.onclick;
}
set onclick (fn) {
var result = super.onclick = () => {
ipcRenderer.send('focus');
ipcRenderer.sendToHost('focus');
fn.apply(this, arguments);
};
return result;
}
}
module.exports = Notification;
This diff is collapsed.
/* globals Meteor, Tracker, RocketChat */
'use strict';
const { ipcRenderer } = require('electron');
class Notification extends window.Notification {
constructor (title, options) {
super(title, options);
ipcRenderer.send('notification-shim', title, options);
// Handle correct notification using unique tag
ipcRenderer.once(`clicked-${options.tag}`, () => this.onclick());
}
get onclick () {
return super.onclick;
}
set onclick (fn) {
var result = super.onclick = () => {
ipcRenderer.send('focus');
ipcRenderer.sendToHost('focus');
fn.apply(this, arguments);
};
return result;
}
}
const { ipcRenderer, shell } = require('electron');
const Notification = require('./lib/Notification');
const SpellCheck = require('./lib/SpellCheck');
window.Notification = Notification;
......@@ -48,8 +26,6 @@ window.addEventListener('load', function () {
});
});
const {shell} = require('electron');
var supportExternalLinks = function (e) {
var href;
var isExternal = false;
......@@ -78,282 +54,8 @@ var supportExternalLinks = function (e) {
document.addEventListener('click', supportExternalLinks, false);
const {webFrame} = require('electron');
const {remote} = require('electron');
var webContents = remote.getCurrentWebContents();
var menu = new remote.Menu();
var path = remote.require('path');
// // set the initial context menu so that a context menu exists even before spellcheck is called
var getTemplate = function () {
return [
{
label: 'Undo',
role: 'undo'
},
{
label: 'Redo',
role: 'redo'
},
{
type: 'separator'
},
{
label: 'Cut',
role: 'cut'
},
{
label: 'Copy',
role: 'copy'
},
{
label: 'Paste',
role: 'paste'
},
{
label: 'Select All',
role: 'selectall'
}
];
};
let languagesMenu;
let checker;
const enabledDictionaries = [];
let availableDictionaries = [];
let dictionariesPath;
if (localStorage.getItem('spellcheckerDictionaries')) {
let spellcheckerDictionaries = JSON.parse(localStorage.getItem('spellcheckerDictionaries'));
if (Array.isArray(spellcheckerDictionaries)) {
enabledDictionaries.push.apply(enabledDictionaries, spellcheckerDictionaries);
}
}
const saveEnabledDictionaries = function () {
localStorage.setItem('spellcheckerDictionaries', JSON.stringify(enabledDictionaries));
};
const isCorrect = function (text) {
if (!checker || enabledDictionaries.length === 0) {
return true;
}
let isCorrect = false;
enabledDictionaries.forEach(function (enabledDictionary) {
if (availableDictionaries.indexOf(enabledDictionary) === -1) {
return;
}
checker.setDictionary(enabledDictionary, dictionariesPath);
if (!checker.isMisspelled(text)) {
isCorrect = true;
}
});
return isCorrect;
};
const getCorrections = function (text) {
// Create an array of arrays of corrections
// One array of corrections per language
let allCorrections = [];
enabledDictionaries.forEach(function (enabledDictionary) {
if (availableDictionaries.indexOf(enabledDictionary) === -1) {
return;
}
checker.setDictionary(enabledDictionary, dictionariesPath);
const languageCorrections = checker.getCorrectionsForMisspelling(text);
if (languageCorrections.length > 0) {
allCorrections.push(languageCorrections);
}
});
// Get the size of biggest array
let length = 0;
allCorrections.forEach(function (items) {
length = Math.max(length, items.length);
});
// Merge all arrays until the size of the biggest array
// To get the best suggestions of each language first
// Ex: [[1,2,3], [a,b]] => [1,a,2,b,3]
const corrections = [];
for (let i = 0; i < length; i++) {
for (var j = 0; j < allCorrections.length; j++) {
if (allCorrections[j][i]) {
corrections.push(allCorrections[j][i]);
}
}
}
// Remove duplicateds
corrections.forEach(function (item, index) {
const dupIndex = corrections.indexOf(item, index+1);
if (dupIndex > -1) {
corrections.splice(dupIndex, 1);
}
});
return corrections;
};
try {
checker = require('spellchecker');
availableDictionaries = checker.getAvailableDictionaries();
if (availableDictionaries.length === 0) {
dictionariesPath = path.join(remote.app.getAppPath(), '../dictionaries');
availableDictionaries = [
'en_US',
'es_ES',
'pt_BR'
];
} else {
for (let i = 0; i < availableDictionaries.length; i++) {
availableDictionaries[i] = availableDictionaries[i].replace('-', '_');
}
}
availableDictionaries = availableDictionaries.sort(function (a, b) {
if (a > b) {
return 1;
}
if (a < b) {
return -1;
}
return 0;
});
for (var i = enabledDictionaries.length - 1; i >= 0; i--) {
if (availableDictionaries.indexOf(enabledDictionaries[i]) === -1) {
enabledDictionaries.splice(i, 1);
}
}
if (enabledDictionaries.length === 0) {
if (localStorage.getItem('userLanguage')) {
let userLanguage = localStorage.getItem('userLanguage').replace('-', '_');
if (availableDictionaries.indexOf(userLanguage) > -1) {
enabledDictionaries.push(userLanguage);
}
if (userLanguage.indexOf('_') > -1) {
userLanguage = userLanguage.split('_')[0];
if (availableDictionaries.indexOf(userLanguage) > -1) {
enabledDictionaries.push(userLanguage);
}
}
}
let navigatorLanguage = navigator.language.replace('-', '_');
if (availableDictionaries.indexOf(navigatorLanguage) > -1) {
enabledDictionaries.push(navigatorLanguage);
}
if (navigatorLanguage.indexOf('_') > -1) {
navigatorLanguage = navigatorLanguage.split('_')[0];
if (availableDictionaries.indexOf(navigatorLanguage) > -1) {
enabledDictionaries.push(navigatorLanguage);
}
}
}
if (enabledDictionaries.length === 0) {
let defaultLanguage = 'en_US';
if (availableDictionaries.indexOf(defaultLanguage) > -1) {
enabledDictionaries.push(defaultLanguage);
}
defaultLanguage = defaultLanguage.split('_')[0];
if (availableDictionaries.indexOf(defaultLanguage) > -1) {
enabledDictionaries.push(defaultLanguage);
}
}
languagesMenu = {
label: 'Spelling languages',
submenu: []
};
availableDictionaries.forEach((dictionary) => {
const menu = {
label: dictionary,
type: 'checkbox',
checked: enabledDictionaries.indexOf(dictionary) > -1,
click: function (menuItem) {
menu.checked = menuItem.checked;
if (menuItem.checked) {
enabledDictionaries.push(dictionary);
} else {
enabledDictionaries.splice(enabledDictionaries.indexOf(dictionary), 1);
}
saveEnabledDictionaries();
}
};
languagesMenu.submenu.push(menu);
});
webFrame.setSpellCheckProvider('', false, {
spellCheck: function (text) {
return isCorrect(text);
}
});
} catch (e) {
console.log('Spellchecker module unavailable \n' + e.message);
}
window.addEventListener('contextmenu', function (event) {
event.preventDefault();
const template = getTemplate();
if (languagesMenu) {
template.unshift({ type: 'separator' });
template.unshift(languagesMenu);
}
setTimeout(function () {
if (['TEXTAREA', 'INPUT'].indexOf(event.target.nodeName) > -1) {
const text = window.getSelection().toString().trim();
if (text !== '' && !isCorrect(text)) {
const options = getCorrections(text);
const maxItems = Math.min(options.length, 6);
if (maxItems > 0) {
const suggestions = [];
const onClick = function (menuItem) {
webContents.replaceMisspelling(menuItem.label);
};
for (let i = 0; i < options.length; i++) {
const item = options[i];
suggestions.push({ label: item, click: onClick });
}
template.unshift({ type: 'separator' });
if (suggestions.length > maxItems) {
const morSuggestions = {
label: 'More spelling suggestions',
submenu: suggestions.slice(maxItems)
};
template.unshift(morSuggestions);
}
template.unshift.apply(template, suggestions.slice(0, maxItems));
} else {
template.unshift({ label: 'no suggestions', click: function () { } });
}
}
}
menu = remote.Menu.buildFromTemplate(template);
menu.popup(remote.getCurrentWindow());
}, 0);
}, false);
const spellChecker = new SpellCheck();
spellChecker.enable();
/**
* Keep user online if they are still using their computer
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment