Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make use of CodeMirror in "Advanced settings" page #271

Merged
merged 1 commit into from
Oct 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion src/advanced-settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title data-i18n="advancedSettingsPageName"></title>

<link rel="stylesheet" href="lib/codemirror/lib/codemirror.css">

<link rel="stylesheet" type="text/css" href="css/common.css">
<link rel="stylesheet" type="text/css" href="css/dashboard-common.css">
<link rel="stylesheet" type="text/css" href="css/advanced-settings.css">
<link rel="stylesheet" href="css/codemirror.css">
<link rel="shortcut icon" type="image/png" href="img/icon_16.png"/>
</head>

Expand All @@ -14,9 +19,13 @@
<p><span data-i18n="advancedSettingsWarning"></span> <a class="fa info important" href="https://github.com/gorhill/uBlock/wiki/Advanced-settings" target="_blank">&#xf05a;</a>
<p>
<button id="advancedSettingsApply" class="custom important" type="button" disabled data-i18n="genericApplyChanges"></button>&ensp;
<p><textarea id="advancedSettings" dir="auto" spellcheck="false"></textarea>
</div>

<div id="advancedSettings" class="codeMirrorContainer codeMirrorFillVertical"></div>

<script src="lib/codemirror/lib/codemirror.js"></script>
<script src="lib/codemirror/addon/selection/active-line.js"></script>

<script src="js/vapi.js"></script>
<script src="js/vapi-common.js"></script>
<script src="js/vapi-client.js"></script>
Expand Down
15 changes: 10 additions & 5 deletions src/css/advanced-settings.css
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
textarea {
box-sizing: border-box;
height: 60vh;
html {
height: 100vh;
overflow: hidden;
}
body {
overflow: hidden;
}
#advancedSettings {
border-top: 1px solid #ddd;
height: 75vh;
text-align: left;
white-space: pre;
width: 100%;
word-wrap: normal;
}
96 changes: 57 additions & 39 deletions src/js/advanced-settings.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*******************************************************************************

uBlock Origin - a browser extension to block requests.
Copyright (C) 2016 Raymond Hill
Copyright (C) 2016-present Raymond Hill

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand All @@ -19,96 +19,114 @@
Home: https://github.com/gorhill/uBlock
*/

/* global uDom */
/* global CodeMirror, uDom, uBlockDashboard */

'use strict';

/******************************************************************************/

(function() {
(function() { // >>>> Start of private namespace

/******************************************************************************/

var messaging = vAPI.messaging;
var cachedData = '';
var rawAdvancedSettings = uDom.nodeFromId('advancedSettings');
let messaging = vAPI.messaging;
let noopFunc = function(){};

let beforeHash = '';

let cmEditor = new CodeMirror(
document.getElementById('advancedSettings'),
{
autofocus: true,
lineNumbers: true,
lineWrapping: true,
styleActiveLine: true
}
);

uBlockDashboard.patchCodeMirrorEditor(cmEditor);

/******************************************************************************/

var hashFromAdvancedSettings = function(raw) {
let hashFromAdvancedSettings = function(raw) {
return raw.trim().replace(/\s+/g, '|');
};

/******************************************************************************/

// This is to give a visual hint that the content of user blacklist has changed.

var advancedSettingsChanged = (function () {
var timer = null;
let advancedSettingsChanged = (function () {
let timer = null;

var handler = function() {
let handler = ( ) => {
timer = null;
var changed = hashFromAdvancedSettings(rawAdvancedSettings.value) !== cachedData;
let changed = hashFromAdvancedSettings(cmEditor.getValue()) !== beforeHash;
uDom.nodeFromId('advancedSettingsApply').disabled = !changed;
CodeMirror.commands.save = changed ? applyChanges : noopFunc;
};

return function() {
if ( timer !== null ) {
clearTimeout(timer);
}
if ( timer !== null ) { clearTimeout(timer); }
timer = vAPI.setTimeout(handler, 100);
};
})();

cmEditor.on('changes', advancedSettingsChanged);

/******************************************************************************/

function renderAdvancedSettings() {
var onRead = function(raw) {
cachedData = hashFromAdvancedSettings(raw);
var pretty = [],
let renderAdvancedSettings = function(first) {
let onRead = function(raw) {
beforeHash = hashFromAdvancedSettings(raw);
let pretty = [],
whitespaces = ' ',
lines = raw.split('\n'),
max = 0,
pos,
i, n = lines.length;
for ( i = 0; i < n; i++ ) {
pos = lines[i].indexOf(' ');
if ( pos > max ) {
max = pos;
}
max = 0;
for ( let line of lines ) {
let pos = line.indexOf(' ');
if ( pos > max ) { max = pos; }
}
for ( let line of lines ) {
let pos = line.indexOf(' ');
pretty.push(whitespaces.slice(0, max - pos) + line);
}
for ( i = 0; i < n; i++ ) {
pos = lines[i].indexOf(' ');
pretty.push(whitespaces.slice(0, max - pos) + lines[i]);
cmEditor.setValue(pretty.join('\n') + '\n');
if ( first ) {
cmEditor.clearHistory();
}
rawAdvancedSettings.value = pretty.join('\n') + '\n';
advancedSettingsChanged();
rawAdvancedSettings.focus();
cmEditor.focus();
};
messaging.send('dashboard', { what: 'readHiddenSettings' }, onRead);
}
};

/******************************************************************************/

var applyChanges = function() {
let applyChanges = function() {
messaging.send(
'dashboard',
{
what: 'writeHiddenSettings',
content: rawAdvancedSettings.value
content: cmEditor.getValue()
},
renderAdvancedSettings
);
};

/******************************************************************************/

// Handle user interaction
uDom('#advancedSettings').on('input', advancedSettingsChanged);
uDom('#advancedSettingsApply').on('click', applyChanges);
uDom.nodeFromId('advancedSettings').addEventListener(
'input',
advancedSettingsChanged
);
uDom.nodeFromId('advancedSettingsApply').addEventListener(
'click',
applyChanges
);

renderAdvancedSettings();
renderAdvancedSettings(true);

/******************************************************************************/

})();
})(); // <<<< End of private namespace