Skip to content

Commit 5ca9473

Browse files
committed
Allow users to create user-specified rules. Rules are saved in local storage and automatically loaded when the browser / extension starts up.
TODO: This change does not allow users to edit/delete existing rules or to submit them to a central location. This change doesn't support exceptions or cookie rules yet (but no reason they couldn't be easily added). I also introduced a structure for a JS object that can be used to represent rules.
1 parent a6f23fd commit 5ca9473

File tree

5 files changed

+117
-1
lines changed

5 files changed

+117
-1
lines changed

chromium/background.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,25 @@
1+
var USER_RULE_KEY = 'userRules';
12

3+
var getStoredUserRules = function() {
4+
var oldUserRuleString = localStorage.getItem(USER_RULE_KEY);
5+
var oldUserRules = []
6+
if (oldUserRuleString) {
7+
oldUserRules = JSON.parse(oldUserRuleString);
8+
}
9+
return oldUserRules;
10+
};
211
var all_rules = new RuleSets();
312
var wr = chrome.webRequest;
13+
var loadStoredUserRules = function() {
14+
var rules = getStoredUserRules();
15+
var i;
16+
for (i = 0; i < rules.length; ++i) {
17+
all_rules.addUserRule(rules[i]);
18+
}
19+
log('INFO', 'loaded ' + i + ' stored user rules');
20+
};
421

22+
loadStoredUserRules();
523
/*
624
for (var v in localStorage) {
725
log(DBUG, "localStorage["+v+"]: "+localStorage[v]);
@@ -29,6 +47,24 @@ function displayPageAction(tabId) {
2947
}
3048
}
3149

50+
51+
var addNewRule = function(params, cb) {
52+
if (all_rules.addUserRule(params)) {
53+
// If we successfully added the user rule, save it in local
54+
// storage so it's automatically applied when the extension is
55+
// reloaded.
56+
var oldUserRules = getStoredUserRules();
57+
// TODO: there's a race condition here, if this code is ever executed from multiple
58+
// client windows in different event loops.
59+
oldUserRules.push(params);
60+
// TODO: can we exceed the max size for storage?
61+
localStorage.setItem(USER_RULE_KEY, JSON.stringify(oldUserRules));
62+
cb(true);
63+
} else {
64+
cb(false);
65+
}
66+
};
67+
3268
function AppliedRulesets() {
3369
this.active_tab_rules = {};
3470

chromium/jquery.min.js

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

chromium/popup.html

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,28 @@
55
<link href="chrome-resources/css/chrome_shared.css" rel="stylesheet" type="text/css"/>
66

77
<link href="popup.css" rel="stylesheet" type="text/css"/>
8+
<script src="jquery.min.js"></script>
9+
<script src="URI.js"></script>
810
<script src="popup.js"></script>
11+
912
</head>
1013

1114
<body>
1215
<header>
1316
<h1 i18n="about_ext_name"></h1>
1417
</header>
18+
<section>
19+
<a href="#" id="add-rule-link">Add this site</a>
20+
<div id="add-new-rule-div" style="display:none">
21+
<h3> Add a new rule</h3>
22+
<label for="new-rule-host">Host</label> <br><input size="50" id="new-rule-host" type="text" disabled><br>
23+
<label for="new-rule-name">Rule name</label><br><input size="50" id="new-rule-name" type="text"><br>
24+
<label for="new-rule-regex">Matching regex</label> <br><input size="50" id="new-rule-regex" type="text"><br>
25+
<label for="new-rule-redirect">Redirect to</label> <br><input size="50" id="new-rule-redirect" type="text"><br>
26+
<button id="add-new-rule-button">Add new Rule</button><br>
27+
<button id="cancel-new-rule">Cancel</button>
28+
</div>
29+
</section>
1530
<section id="StableRules" class="rules">
1631
<h3 i18n="chrome_stable_rules"></h3>
1732
<p class="description" i18n="chrome_stable_rules_description"></p>
@@ -22,7 +37,7 @@ <h3 i18n="chrome_experimental_rules"></h3>
2237
</section>
2338
<footer>
2439
<a id="whatIsThis" href="https://www.eff.org/https-everywhere" target="_blank" tabindex="-1" i18n="chrome_what_is_this">blah</a>
25-
<!-- <a href="" title="HTTPS Everywhere Options">Options</a> --->
40+
<!-- <a href="" title="HTTPS Everywhere Options">Options</a> -->
2641
</footer>
2742

2843
</body>

chromium/popup.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,3 +90,46 @@ document.addEventListener("DOMContentLoaded", function () {
9090
document.getElementById("whatIsThis").setAttribute("title", chrome.i18n.getMessage("chrome_what_is_this_title"));
9191
});
9292

93+
94+
var escapeForRegex = function( value ) {
95+
return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
96+
};
97+
98+
$(function() {
99+
$('#add-rule-link').click(function() {
100+
101+
chrome.tabs.getSelected(null, function(tab) {
102+
103+
$('#add-rule-link').hide();
104+
$('#add-new-rule-div').show();
105+
var newUrl = new URI(tab.url);
106+
newUrl.scheme('https');
107+
$('#new-rule-host').val(newUrl.host());
108+
var oldUrl = new URI(tab.url);
109+
oldUrl.scheme('http');
110+
var oldMatcher = '^' + escapeForRegex(oldUrl.scheme() + '://' + oldUrl.host() + '/');
111+
$('#new-rule-regex').val(oldMatcher);
112+
var redirectPath = newUrl.scheme() + '://' + newUrl.host() + '/';
113+
$('#new-rule-redirect').val(redirectPath);
114+
$('#new-rule-name').val('Manual rule for ' + oldUrl.host());
115+
$('#add-new-rule-button').click(function() {
116+
var params = {
117+
host : $('#new-rule-host').val(),
118+
redirectTo : $('#new-rule-redirect').val(),
119+
urlMatcher : $('#new-rule-regex').val(),
120+
};
121+
backgroundPage.addNewRule(params,
122+
function() {
123+
location.reload();
124+
});
125+
});
126+
127+
$('#cancel-new-rule').click(function() {
128+
$('#add-rule-link').show();
129+
$('#add-new-rule-div').hide();
130+
});
131+
});
132+
});
133+
return false;
134+
135+
});

chromium/rules.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,22 @@ RuleSets.prototype = {
116116
}
117117
},
118118

119+
addUserRule : function(params) {
120+
log(INFO, 'adding new user rule for ' + JSON.stringify(params));
121+
var new_rule_set = new RuleSet(params.host, null, true, "user rule");
122+
var new_rule = new Rule(params.urlMatcher, params.redirectTo);
123+
new_rule_set.rules.push(new_rule);
124+
if (!(params.host in this.targets)) {
125+
this.targets[params.host] = [];
126+
}
127+
ruleCache.remove(params.host);
128+
// TODO: maybe promote this rule?
129+
// TODO: look for duplicates.
130+
this.targets[params.host].push(new_rule_set);
131+
log(INFO, 'done adding rule');
132+
return true;
133+
},
134+
119135
parseOneRuleset: function(ruletag) {
120136
var default_state = true;
121137
var note = "";

0 commit comments

Comments
 (0)