dashboard tab to edit user rules

pull/2/head
gorhill 10 years ago
parent 6c6622056b
commit e06985fcc7

@ -23,6 +23,10 @@ h2 + * {
a {
text-decoration: none;
}
button {
padding: 0.4em;
}
.para {
width: 40em;
}

@ -78,6 +78,7 @@ iframe {
<span>µMatrix</span>
<a class="tabButton" id="settings" href="#settings" data-dashboard-panel-url="settings.html" data-i18n="settingsPageName"></a>
<a class="tabButton" id="privacy" href="#privacy" data-dashboard-panel-url="privacy.html" data-i18n="privacyPageName"></a>
<a class="tabButton" id="user-rules" href="#user-rules" data-dashboard-panel-url="user-rules.html" data-i18n="userRulesPageName"></a>
<a class="tabButton" id="ubiquitous-rules" href="#ubiquitous-rules" data-dashboard-panel-url="ubiquitous-rules.html" data-i18n="ubiquitousRulesPageName"></a>
<a class="tabButton" id="statistics" href="#statistics" data-dashboard-panel-url="info.html" data-i18n="statsPageName"></a>
<a class="tabButton" id="about" href="#about" data-dashboard-panel-url="about.html" data-i18n="aboutPageName"></a>
@ -86,7 +87,7 @@ iframe {
<iframe src=""></iframe>
<script src="lib/jquery-2.min.js"></script>
<script src="js/udom.js"></script>
<script src="js/i18n.js"></script>
<script src="js/dashboard.js"></script>
</body>

@ -165,6 +165,7 @@ tr.unused {
</div> <!-- end of detailed stats -->
<script src="lib/jquery-2.min.js"></script>
<script src="js/udom.js"></script>
<script src="js/i18n.js"></script>
<script src="js/dashboard-common.js"></script>
<script src="js/messaging-client.js"></script>

@ -21,18 +21,17 @@
/******************************************************************************/
$(function() {
uDom.onLoad(function() {
/******************************************************************************/
// Open links in the proper window
$('a').attr('target', '_blank');
$('a[href*="dashboard.html"]').attr('target', '_parent');
$('.whatisthis').on('click', function() {
$(this).parent()
.find('.whatisthis-expandable')
.toggleClass('whatisthis-expanded');
uDom('a').attr('target', '_blank');
uDom('a[href*="dashboard.html"]').attr('target', '_parent');
uDom('.whatisthis').on('click', function() {
uDom(this).parent()
.find('.whatisthis-expandable')
.toggleClass('whatisthis-expanded');
});

@ -24,12 +24,12 @@
(function() {
var loadDashboardPanel = function(hash) {
var button = $(hash);
var url = button.data('dashboardPanelUrl');
$('iframe')[0].src = url;
$('.tabButton').each(function(){
var button = $(this);
button.toggleClass('selected', button.data('dashboardPanelUrl') === url);
var button = uDom(hash);
var url = button.attr('data-dashboard-panel-url');
uDom('iframe').nodeAt(0).src = url;
uDom('.tabButton').toArray().forEach(function(tab){
var button = uDom(tab);
button.toggleClass('selected', button.attr('data-dashboard-panel-url') === url);
});
}
@ -41,8 +41,8 @@ var onTabClickHandler = function() {
/******************************************************************************/
$(function() {
$(window).on('hashchange', onTabClickHandler);
uDom.onLoad(function() {
window.addEventListener('hashchange', onTabClickHandler);
var hash = window.location.hash;
if ( hash.length < 2 ) {
hash = '#settings';

@ -442,7 +442,12 @@ Matrix.prototype.toString = function() {
if ( val === 0 ) {
continue;
}
out.push(srcHostname + ' ' + desHostname + ' ' + type + ' ' + stateToNameMap[val]);
out.push(
punycode.toUnicode(srcHostname) + ' ' +
punycode.toUnicode(desHostname) + ' ' +
type + ' ' +
stateToNameMap[val]
);
}
}
for ( srcHostname in this.switchedOn ) {
@ -450,7 +455,7 @@ Matrix.prototype.toString = function() {
continue;
}
val = this.switchedOn[srcHostname] ? 'on' : 'off';
out.push(srcHostname + ' switch: ' + val);
out.push('switch: ' + srcHostname + ' ' + val);
}
return out.sort().join('\n');
};
@ -461,7 +466,7 @@ Matrix.prototype.fromString = function(text) {
var textEnd = text.length;
var lineBeg = 0, lineEnd;
var line, pos;
var fields, nextField, fieldVal;
var fields, fieldVal;
var srcHostname = '';
var desHostname = '';
var type, state;
@ -487,70 +492,40 @@ Matrix.prototype.fromString = function(text) {
fields = line.split(/\s+/);
// Less than 2 fields make no sense
if ( fields.length < 2 ) {
continue;
}
fieldVal = fields[0];
// Special directives:
// title
pos = fields[0].indexOf('title:');
pos = fieldVal.indexOf('title:');
if ( pos !== -1 ) {
// TODO
continue;
}
// Name
pos = fields[0].indexOf('name:');
pos = fieldVal.indexOf('name:');
if ( pos !== -1 ) {
// TODO
continue;
}
// Valid rule syntax:
// srcHostname desHostname type state
// type = a valid request type
// state = [`block`, `allow`, `inherit`]
// srcHostname desHostname type
// type = a valid request type
// state = `allow`
// srcHostname desHostname
// type = `*`
// state = `allow`
// Switch on/off
// desHostname
// srcHostname from a previous line
// type = `*`
// state = `allow`
// srcHostname `switch:` state
// `switch:` srcHostname state
// state = [`on`, `off`]
// `switch:` state
// srcHostname from a previous line
// state = [`on`, `off`]
// Lines with invalid syntax silently ignored
if ( fields.length === 1 ) {
// Can't infer srcHostname: reject
if ( srcHostname === '' ) {
continue;
}
desHostname = punycode.toASCII(fields[0]);
nextField = 1;
} else {
srcHostname = punycode.toASCII(fields[0]);
desHostname = punycode.toASCII(fields[1]);
nextField = 2;
}
fieldVal = fields[nextField];
nextField += 1;
// Special rule: switch on/off
pos = fieldVal.indexOf('switch:');
if ( pos !== -1 ) {
srcHostname = punycode.toASCII(fields[1]);
if ( desHostname === 'switch:' ) {
// No state field: reject
fieldVal = fields[2];
if ( fieldVal === null ) {
continue;
}
@ -558,11 +533,38 @@ Matrix.prototype.fromString = function(text) {
if ( nameToSwitchMap.hasOwnProperty(fieldVal) === false ) {
continue;
}
this.setSwitch(srcHostname, nameToSwitchMap[fieldVal]);
continue;
}
// Standard rule
// Unknown directive
pos = fieldVal.indexOf(':');
if ( pos !== -1 ) {
continue;
}
// Valid rule syntax:
// srcHostname desHostname [type [state]]
// type = a valid request type
// state = [`block`, `allow`, `inherit`]
// srcHostname desHostname type
// type = a valid request type
// state = `allow`
// srcHostname desHostname
// type = `*`
// state = `allow`
// Lines with invalid syntax silently ignored
srcHostname = punycode.toASCII(fields[0]);
desHostname = punycode.toASCII(fields[1]);
fieldVal = fields[2];
if ( fieldVal !== null ) {
type = fieldVal;
@ -574,8 +576,7 @@ Matrix.prototype.fromString = function(text) {
type = '*';
}
fieldVal = fields[nextField];
nextField += 1;
fieldVal = fields[3];
if ( fieldVal !== null ) {
// Unknown state: reject

@ -428,6 +428,81 @@ var onMessage = function(request, sender, callback) {
/******************************************************************************/
/******************************************************************************/
// user-rules.js
(function() {
var µm = µMatrix;
/******************************************************************************/
var onMessage = function(request, sender, callback) {
// Async
switch ( request.what ) {
default:
break;
}
// Sync
var response;
switch ( request.what ) {
case 'getUserRules':
response = µm.pMatrix.toString();
break;
case 'setUserRules':
µm.pMatrix.fromString(request.rules);
µm.tMatrix.assign(µm.pMatrix);
µm.saveMatrix();
break;
default:
return µm.messaging.defaultHandler(request, sender, callback);
}
callback(response);
};
µMatrix.messaging.listen('user-rules.js', onMessage);
})();
/******************************************************************************/
/******************************************************************************/
// ubiquitous-rules.js
(function() {
var onMessage = function(request, sender, callback) {
var µm = µMatrix;
// Async
switch ( request.what ) {
default:
break;
}
// Sync
var response;
switch ( request.what ) {
default:
return µm.messaging.defaultHandler(request, sender, callback);
}
callback(response);
};
µMatrix.messaging.listen('ubiquitous-rules.js', onMessage);
})();
/******************************************************************************/
/******************************************************************************/
// info.js
(function() {
@ -514,37 +589,6 @@ var onMessage = function(request, sender, callback) {
/******************************************************************************/
/******************************************************************************/
// ubiquitous-rules.js
(function() {
var onMessage = function(request, sender, callback) {
var µm = µMatrix;
// Async
switch ( request.what ) {
default:
break;
}
// Sync
var response;
switch ( request.what ) {
default:
return µm.messaging.defaultHandler(request, sender, callback);
}
callback(response);
};
µMatrix.messaging.listen('ubiquitous-rules.js', onMessage);
})();
/******************************************************************************/
/******************************************************************************/
// about.js
(function() {

@ -95,6 +95,7 @@ ul > li {
</div>
<script src="lib/jquery-2.min.js"></script>
<script src="js/udom.js"></script>
<script src="js/i18n.js"></script>
<script src="js/dashboard-common.js"></script>
<script src="js/messaging-client.js"></script>

@ -82,6 +82,7 @@ ul > li {
<script src="lib/jquery-2.min.js"></script>
<script src="js/udom.js"></script>
<script src="js/i18n.js"></script>
<script src="js/dashboard-common.js"></script>
<script src="js/messaging-client.js"></script>

@ -46,6 +46,7 @@ ul > li {
</div>
<script src="lib/jquery-2.min.js"></script>
<script src="js/udom.js"></script>
<script src="js/i18n.js"></script>
<script src="js/dashboard-common.js"></script>
<script src="js/messaging-client.js"></script>

@ -19,14 +19,14 @@
"message": "Statistik",
"description": "appears as tab name in dashboard"
},
"userRulesPageName": {
"message": "Your rules",
"description": "appears as tab name in dashboard."
},
"ubiquitousRulesPageName" : {
"message": "Omnipräsente Regeln",
"description": "appears as tab name in dashboard"
},
"scopedRulesPageName": {
"message": "Regeln für einen bestimmten Geltungsbereich",
"description": "appears as tab name in dashboard"
},
"aboutPageName": {
"message": "Über",
"description": "appears as tab name in dashboard"
@ -439,6 +439,28 @@
},
"userRulesApplyChanges": {
"message": "Apply changes",
"description": "English: Apply changes"
},
"userRulesImport": {
"message": "Import from file...",
"description": "English: Import from file..."
},
"userRulesExport": {
"message": "Export to file...",
"description": "English: Export to file..."
},
"userRulesFormatHint": {
"message": "See this page for rule syntax.",
"description": "English: See this page for rule syntax."
},
"userRulesDefaultFileName": {
"message": "your-umatrix-rules.txt",
"description": "English: See this page for rule syntax."
},
"ubiquitousWhatIsThisHeader" : {
"message": "Was ist das?",
"description": "English: What is this?"
@ -493,84 +515,6 @@
},
"scopedCommitAllButton": {
"message": "Alle dauerhaft speichern",
"description": "English: Commit all"
},
"scopedRevertAllButton": {
"message": "Alle rückgängig machen",
"description": "English: Revert all"
},
"scopedMarkAllForDeletionButton": {
"message": "Alle zum Löschen markieren",
"description": "English: Mark all for deletion"
},
"scopedResetToFactoryButton": {
"message": "Auf Werkseinstellungen zurücksetzen",
"description": "English: Reset to factory"
},
"scopedRulesHeader": {
"message": "Regeln",
"description": "English: Rules"
},
"scopedRulesInfo": {
"message": "Hier kannst du für deine Geltungsbereiche und Regeln ein Backup anlegen: Klicke auf &ldquo;Regeln exportieren&rdquo;, klicke optional auf &ldquo;Als Rezept kodieren&rdquo;, und speichere das Ergebnis als Datei, dessen Inhalt später hier eingefügt werden kann.<p>Die Syntax ist strikt, nur fortgeschrittene Benutzer sollten es riskieren, hier zu editieren. Wenn du ein Rezept von einer nicht vertrauenswürdigen Quelle importierst, solltest du sicher sein, dass nichts damit verkehrt ist (Bsp.: <b>&ldquo;whitelist * evil.com&rdquo;</b>)</p>",
"description": "English: [see english message.json]"
},
"scopedRecipeHeader": {
"message": "Rezepte",
"description": "English: Recipes"
},
"scopedRecipesInfo": {
"message": "Ein &ldquo;Rezept&rdquo; ist einfach ein Satz von Regeln, die auf eine Weise kodiert sind, dass sie leicht gesichert oder mit anderen Benutzern ausgetauscht werden können. In der Hoffnung, dass fortgeschrittene Benutzer ihre sorgfältig erstellten Rezepte mit Neulingen teilen werden, um diese zu unterstützen.",
"description": "English: [see english message.json]"
},
"scopedBackupRecipeButton": {
"message": "Backup in eine Datei",
"description": "English: Backup to file"
},
"scopedRestoreRecipeButton": {
"message": "Aus einer Datei wiederherstellen",
"description": "English: Restore from file"
},
"scopedDecodeRecipeButton": {
"message": "Rezept dekodieren",
"description": "English: Decode recipe"
},
"scopedEncodeRecipeButton": {
"message": "Als Rezept kodieren",
"description": "English: Encode recipe"
},
"scopedImportRulesButton": {
"message": "Regeln importieren",
"description": "English: Import rules"
},
"scopedExportRulesButton": {
"message": "Regeln exportieren",
"description": "English: Export rules"
},
"scopedGlobalScopeHeader": {
"message": "Globaler Geltungsbereich",
"description": "English: Global scope"
},
"scopedBtsScopeHeader": {
"message": "Geltungsbereich Hintergrundanfragen",
"description": "English: Behind-the-scene scope"
},
"scopedDomainScopeHeader": {
"message": "Geltungsbereich Domain-Ebene",
"description": "English: Domain-level scope"
},
"scopedSiteScopeHeader": {
"message": "Geltungsbereich Webseiten-Ebene",
"description": "English: Site-level scope"
},
"scopedDeletionPrompt": {
"message": "Du bist dabei, {{deleteCount}} Regeln zu löschen.\nDas ist irreversibel.\nKlicke OK zur Bestätigung.",
"description": "English: You are about to delete {{deleteCount}} rules.\nIt is irreversible.\nClick OK to confirm."
},
"aboutChangelog" : {
"message": "<a href='https://github.com/gorhill/httpswitchboard/wiki/Changelog'>Changelog</a>",
"description": "English: <a href='https://github.com/gorhill/httpswitchboard/wiki/Change-log'>Change log</a>"

@ -19,12 +19,12 @@
"message": "Statistics",
"description": "appears as tab name in dashboard."
},
"ubiquitousRulesPageName" : {
"message": "Ubiquitous rules",
"userRulesPageName": {
"message": "Your rules",
"description": "appears as tab name in dashboard."
},
"scopedRulesPageName": {
"message": "Scoped rules",
"ubiquitousRulesPageName" : {
"message": "Ubiquitous rules",
"description": "appears as tab name in dashboard."
},
"aboutPageName": {
@ -439,6 +439,28 @@
},
"userRulesApplyChanges": {
"message": "Apply changes",
"description": "English: Apply changes"
},
"userRulesImport": {
"message": "Import from file...",
"description": "English: Import from file..."
},
"userRulesExport": {
"message": "Export to file...",
"description": "English: Export to file..."
},
"userRulesFormatHint": {
"message": "See this page for rule syntax.",
"description": "English: See this page for rule syntax."
},
"userRulesDefaultFileName": {
"message": "your-umatrix-rules.txt",
"description": "English: See this page for rule syntax."
},
"ubiquitousWhatIsThisHeader" : {
"message": "What is this?",
"description": "English: What is this?"
@ -493,84 +515,6 @@
},
"scopedCommitAllButton": {
"message": "Commit all",
"description": "English: Commit all"
},
"scopedRevertAllButton": {
"message": "Revert all",
"description": "English: Revert all"
},
"scopedMarkAllForDeletionButton": {
"message": "Mark all for deletion",
"description": "English: Mark all for deletion"
},
"scopedResetToFactoryButton": {
"message": "Reset to factory",
"description": "English: Reset to factory"
},
"scopedRulesHeader": {
"message": "Rules",
"description": "English: Rules"
},
"scopedRulesInfo": {
"message": "This is where you want to backup all of your scopes and rules: Click &ldquo;Export rules&rdquo;, optionally click &ldquo;Encode recipe&rdquo;, save the result into a file which content can be pasted here later. <p>Syntax is very strict, only advanced users should risk editing here. If you are importing a recipe from an untrusted source, be sure there is nothing wrong with it (ex.: <b>&ldquo;whitelist * evil.com&rdquo;</b>)</p>",
"description": "English: [see english message.json]"
},
"scopedRecipeHeader": {
"message": "Recipes",
"description": "English: Recipes"
},
"scopedRecipesInfo": {
"message": "A &ldquo;recipe&rdquo; is just a set of rules encoded in a way to make it easy to backup or exchange set of rules between users. Hopefully advanced users will share their carefully crafted recipes to help novice users.",
"description": "English: [see english message.json]"
},
"scopedBackupRecipeButton": {
"message": "Backup to file",
"description": "English: Backup to file"
},
"scopedRestoreRecipeButton": {
"message": "Restore from file",
"description": "English: Restore from file"
},
"scopedDecodeRecipeButton": {
"message": "Decode recipe",
"description": "English: Decode recipe"
},
"scopedEncodeRecipeButton": {
"message": "Encode recipe",
"description": "English: Encode recipe"
},
"scopedImportRulesButton": {
"message": "Import rules",
"description": "English: Import rules"
},
"scopedExportRulesButton": {
"message": "Export rules",
"description": "English: Export rules"
},
"scopedGlobalScopeHeader": {
"message": "Global scope",
"description": "English: Global scope"
},
"scopedBtsScopeHeader": {
"message": "Behind-the-scene scope",
"description": "English: Behind-the-scene scope"
},
"scopedDomainScopeHeader": {
"message": "Domain-level scope",
"description": "English: Domain-level scope"
},
"scopedSiteScopeHeader": {
"message": "Site-level scope",
"description": "English: Site-level scope"
},
"scopedDeletionPrompt": {
"message": "You are about to delete {{deleteCount}} rules.\nThis is irreversible.\nClick OK to confirm.",
"description": "English: You are about to delete {{deleteCount}} rules.\nThis is irreversible.\nClick OK to confirm."
},
"aboutChangelog" : {
"message": "<a href='https://github.com/gorhill/httpswitchboard/wiki/Change-log'>Change log</a>",
"description": "English: <a href='https://github.com/gorhill/httpswitchboard/wiki/Change-log'>Change log</a>"

@ -19,14 +19,14 @@
"message": "Statistiques",
"description": "appears as tab name in dashboard"
},
"userRulesPageName": {
"message": "Your rules",
"description": "appears as tab name in dashboard."
},
"ubiquitousRulesPageName" : {
"message": "Règles à portée universelle",
"description": "appears as tab name in dashboard"
},
"scopedRulesPageName": {
"message": "Règles à portée restreinte",
"description": "appears as tab name in dashboard"
},
"aboutPageName": {
"message": "À propos",
"description": "appears as tab name in dashboard"
@ -439,6 +439,28 @@
},
"userRulesApplyChanges": {
"message": "Apply changes",
"description": "English: Apply changes"
},
"userRulesImport": {
"message": "Import from file...",
"description": "English: Import from file..."
},
"userRulesExport": {
"message": "Export to file...",
"description": "English: Export to file..."
},
"userRulesFormatHint": {
"message": "See this page for rule syntax.",
"description": "English: See this page for rule syntax."
},
"userRulesDefaultFileName": {
"message": "your-umatrix-rules.txt",
"description": "English: See this page for rule syntax."
},
"ubiquitousWhatIsThisHeader" : {
"message": "De quoi s'agit-il ?",
"description": "English: What is this?"
@ -493,84 +515,6 @@
},
"scopedCommitAllButton": {
"message": "Tout valider",
"description": "English: Commit all"
},
"scopedRevertAllButton": {
"message": "Tout annuler",
"description": "English: Revert all"
},
"scopedMarkAllForDeletionButton": {
"message": "Tout supprimer",
"description": "English: Mark all for deletion"
},
"scopedResetToFactoryButton": {
"message": "Repartir à zéro",
"description": "English: Reset to factory"
},
"scopedRulesHeader": {
"message": "Règles",
"description": "English: Rules"
},
"scopedRulesInfo": {
"message": "Cette page vous permet de sauvegarder vos règles. Pour cela, il vous suffit de cliquer sur &ldquo;Exporter&rdquo;, &ldquo;Encoder&rdquo;, puis sur &ldquo;Exporter vers un fichier&rdquo;.<p>La syntaxe est très stricte, aussi seuls les utilisateurs expérimentés devraient s'aventurer à la modifier. Si vous importez une recette d'une source peu familière, assurez-vous que le contenu ne soit pas compromis (ex. : <b>&ldquo;whitelist * dangereusesource.com&rdquo;</b>)</p>",
"description": "English: [see english message.json]"
},
"scopedRecipeHeader": {
"message": "Recette",
"description": "English: Recipes"
},
"scopedRecipesInfo": {
"message": "Une &ldquo;recette&rdquo; est simplement un ensemble de règles encodées de façon à faciliter les échanges entre utilisateurs. Le but est d'encourager les utilisateurs chevronnés à aider les novices quand vient le temps de déterminer les règles nécessaires au bon fonctionnement d'un site quelconque.",
"description": "English: [see english message.json]"
},
"scopedBackupRecipeButton": {
"message": "Exporter vers un fichier",
"description": "English: Backup to file"
},
"scopedRestoreRecipeButton": {
"message": "Importer depuis un fichier",
"description": "English: Restore from file"
},
"scopedDecodeRecipeButton": {
"message": "Décoder",
"description": "English: Decode recipe"
},
"scopedEncodeRecipeButton": {
"message": "Encoder",
"description": "English: Encode recipe"
},
"scopedImportRulesButton": {
"message": "Importer les règles",
"description": "English: Import rules"
},
"scopedExportRulesButton": {
"message": "Exporter les règles",
"description": "English: Export rules"
},
"scopedGlobalScopeHeader": {
"message": "Contexte global",
"description": "English: Global scope"
},
"scopedBtsScopeHeader": {
"message": "Contexte des requêtes en coulisse",
"description": "English: Behind-the-scene scope"
},
"scopedDomainScopeHeader": {
"message": "Contexte(s) des règles à portée domaine",
"description": "English: Domain-level scope"
},
"scopedSiteScopeHeader": {
"message": "Contexte(s) des règles à portée site",
"description": "English: Site-level scope"
},
"scopedDeletionPrompt": {
"message": "{{deleteCount}} règle(s) sera/seront\nirrémédiablement supprimée(s).\nCliquez sur OK pour confirmer",
"description": "English: You are about to delete {{deleteCount}} rules.\nIt is irreversible.\nClick OK to confirm."
},
"aboutChangelog" : {
"message": "<a href='https://github.com/gorhill/httpswitchboard/wiki/Change-log'>Journal des changements (en Anglais)</a>",
"description": "English: <a href='https://github.com/gorhill/httpswitchboard/wiki/Change-log'>Change log</a>"

@ -19,14 +19,14 @@
"message": "Статистика",
"description": "appears as tab name in dashboard."
},
"userRulesPageName": {
"message": "Your rules",
"description": "appears as tab name in dashboard."
},
"ubiquitousRulesPageName" : {
"message": "Глобальные правила",
"description": "appears as tab name in dashboard"
},
"scopedRulesPageName": {
"message": "Правила для сайтов",
"description": "appears as tab name in dashboard."
},
"aboutPageName": {
"message": "О расширении",
"description": "appears as tab name in dashboard."
@ -439,6 +439,28 @@
},
"userRulesApplyChanges": {
"message": "Apply changes",
"description": "English: Apply changes"
},
"userRulesImport": {
"message": "Import from file...",
"description": "English: Import from file..."
},
"userRulesExport": {
"message": "Export to file...",
"description": "English: Export to file..."
},
"userRulesFormatHint": {
"message": "See this page for rule syntax.",
"description": "English: See this page for rule syntax."
},
"userRulesDefaultFileName": {
"message": "your-umatrix-rules.txt",
"description": "English: See this page for rule syntax."
},
"ubiquitousWhatIsThisHeader" : {
"message": "Что это?",
"description": "English: What is this?"
@ -493,84 +515,6 @@
},
"scopedCommitAllButton": {
"message": "Применить все",
"description": "English: Commit all"
},
"scopedRevertAllButton": {
"message": "Вернуть все",
"description": "English: Revert all"
},
"scopedMarkAllForDeletionButton": {
"message": "Отметить все для удаления",
"description": "English: Mark all for deletion"
},
"scopedResetToFactoryButton": {
"message": "Сброс к заводским",
"description": "English: Reset to factory"
},
"scopedRulesHeader": {
"message": "Правила",
"description": "English: Rules"
},
"scopedRulesInfo": {
"message": "Тут вы можете сохранить все ваши области и правила: Нажмите &ldquo;Экспорт правил&rdquo;, можно нажать &ldquo;закодировать рецепт&rdquo;, сохраняем данные в файл, который может быть загружен сюда. <p>Синтаксис простой, только продвинутым пользователям рекомендуется изменять их. Если вы импортируете рецепт из ненадежного источника, убедитесь, в белые списки не попали вредоносные сайты (типа.: <b>&ldquo;whitelist * вирусы.рф&rdquo;</b>)</p>",
"description": "English: [see english message.json]"
},
"scopedRecipeHeader": {
"message": "Рецепт",
"description": "English: Recipes"
},
"scopedRecipesInfo": {
"message": "&ldquo;Рецепт&rdquo; - это набор правил закодированый для облегчения его сохранения или обмена между пользователями. Надеюсь, продвинутые пользователи будут делиться своими готовыми рецептами, чтобы помочь новичкам.",
"description": "English: [see english message.json]"
},
"scopedBackupRecipeButton": {
"message": "Сохранить в файл",
"description": "English: Backup to file"
},
"scopedRestoreRecipeButton": {
"message": "Восстановить из файла",
"description": "English: Restore from file"
},
"scopedDecodeRecipeButton": {
"message": "Декодировать рецепт",
"description": "English: Decode recipe"
},
"scopedEncodeRecipeButton": {
"message": "Закодировать рецепт",
"description": "English: Encode recipe"
},
"scopedImportRulesButton": {
"message": "Импорт правил",
"description": "English: Import rules"
},
"scopedExportRulesButton": {
"message": "Экспорт правил",
"description": "English: Export rules"
},
"scopedGlobalScopeHeader": {
"message": "Глобальная область",
"description": "English: Global scope"
},
"scopedBtsScopeHeader": {
"message": "Behind-the-scene scope",
"description": "English: Behind-the-scene scope"
},
"scopedDomainScopeHeader": {
"message": "Область домена",
"description": "English: Domain-level scope"
},
"scopedSiteScopeHeader": {
"message": "Область сайта",
"description": "English: Site-level scope"
},
"scopedDeletionPrompt": {
"message": "Вы собираетесь удалить {{deleteCount}} правил.\nЭто необратимо.\nНажмите Да для продолжения.",
"description": "English: You are about to delete {{deleteCount}} rules.\nIt is irreversible.\nClick OK to confirm."
},
"aboutChangelog" : {
"message": "<a href='https://github.com/gorhill/httpswitchboard/wiki/Change-log'>Список изменений</a>",
"description": "English: <a href='https://github.com/gorhill/httpswitchboard/wiki/Change-log'>Change log</a>"

@ -19,12 +19,12 @@
"message": "统计信息",
"description": "appears as tab name in dashboard."
},
"ubiquitousRulesPageName" : {
"message": "通用规则",
"userRulesPageName": {
"message": "Your rules",
"description": "appears as tab name in dashboard."
},
"scopedRulesPageName": {
"message": "作用域规则",
"ubiquitousRulesPageName" : {
"message": "通用规则",
"description": "appears as tab name in dashboard."
},
"aboutPageName": {
@ -439,6 +439,28 @@
},
"userRulesApplyChanges": {
"message": "Apply changes",
"description": "English: Apply changes"
},
"userRulesImport": {
"message": "Import from file...",
"description": "English: Import from file..."
},
"userRulesExport": {
"message": "Export to file...",
"description": "English: Export to file..."
},
"userRulesFormatHint": {
"message": "See this page for rule syntax.",
"description": "English: See this page for rule syntax."
},
"userRulesDefaultFileName": {
"message": "your-umatrix-rules.txt",
"description": "English: See this page for rule syntax."
},
"ubiquitousWhatIsThisHeader" : {
"message": "这是什么?",
"description": "English: What is this?"
@ -493,84 +515,6 @@
},
"scopedCommitAllButton": {
"message": "提交所有变更",
"description": "English: Commit all"
},
"scopedRevertAllButton": {
"message": "移除所有变更",
"description": "English: Revert all"
},
"scopedMarkAllForDeletionButton": {
"message": "把所有规则标志为删除",
"description": "English: Mark all for deletion"
},
"scopedResetToFactoryButton": {
"message": "重设至出厂状态",
"description": "English: Reset to factory"
},
"scopedRulesHeader": {
"message": "规则",
"description": "English: Rules"
},
"scopedRulesInfo": {
"message": "这里是您可以备份所有您的作用域和规则的地方:点击“导出规则”,可选地点击“编码配方”,把结果保存到一个文件里,这个文件的内容可以在日后粘帖到这里。<p>规则的语法是非常严格的,只有高级用户才适合冒险在此编辑。如果您将要导入一个来自非可信来源的配方时,请确保其没有任何错误(例如:<b>“whitelist * evil.com”</b></p>",
"description": "English: [see english message.json]"
},
"scopedRecipeHeader": {
"message": "配方",
"description": "English: Recipes"
},
"scopedRecipesInfo": {
"message": "一条“配方”只是一个,用某种方式编码了的,为了方便备份和用户间进行交流的,规则集。理想地,高级用户会共享出他们经过精雕细刻的配方,来帮助新手用户。",
"description": "English: [see english message.json]"
},
"scopedBackupRecipeButton": {
"message": "备份到文件",
"description": "English: Backup to file"
},
"scopedRestoreRecipeButton": {
"message": "从文件恢复",
"description": "English: Restore from file"
},
"scopedDecodeRecipeButton": {
"message": "解码配方",
"description": "English: Decode recipe"
},
"scopedEncodeRecipeButton": {
"message": "编码配方",
"description": "English: Encode recipe"
},
"scopedImportRulesButton": {
"message": "导入规则",
"description": "English: Import rules"
},
"scopedExportRulesButton": {
"message": "导出规则",
"description": "English: Export rules"
},
"scopedGlobalScopeHeader": {
"message": "全局作用域",
"description": "English: Global scope"
},
"scopedBtsScopeHeader": {
"message": "后台作用域",
"description": "English: Behind-the-scene scope"
},
"scopedDomainScopeHeader": {
"message": "域名级作用域",
"description": "English: Domain-level scope"
},
"scopedSiteScopeHeader": {
"message": "站点级作用域",
"description": "English: Site-level scope"
},
"scopedDeletionPrompt": {
"message": "您即将要删除{{deleteCount}}条规则。\n这是不可逆的操作。\n点击OK进行确认。",
"description": "English: You are about to delete {{deleteCount}} rules.\nThis is irreversible.\nClick OK to confirm."
},
"aboutChangelog" : {
"message": "<a href='https://github.com/gorhill/httpswitchboard/wiki/Change-log'>变更日志</a>",
"description": "English: <a href='https://github.com/gorhill/httpswitchboard/wiki/Change-log'>Change log</a>"

Loading…
Cancel
Save