Host switch
This commit is contained in:
parent
592e324f6e
commit
e7ecedccec
3 changed files with 151 additions and 94 deletions
209
lib/popup.js
209
lib/popup.js
|
@ -75,14 +75,17 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
storage: {
|
storage: {
|
||||||
data: {},
|
data: {
|
||||||
|
private: {},
|
||||||
|
global: {}
|
||||||
|
},
|
||||||
MODE: {
|
MODE: {
|
||||||
private: 1,
|
private: 1,
|
||||||
global: 2,
|
global: 2,
|
||||||
},
|
},
|
||||||
setMode: function(mode) {
|
setMode: function(mode) {
|
||||||
if( mode === this.MODE.private ) {
|
if( mode === this.MODE.private ) {
|
||||||
this.key = popup.key + "-" + popup.host;
|
this.key = popup.key + "-" + popup.protocol + "//" + popup.host;
|
||||||
this.mode = this.MODE.private;
|
this.mode = this.MODE.private;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,46 +94,52 @@
|
||||||
this.mode = this.MODE.global;
|
this.mode = this.MODE.global;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
load: function() {
|
||||||
|
this.setMode(this.MODE.private);
|
||||||
|
this._setData(JSON.parse(localStorage.getItem(this.key) || "{}"));
|
||||||
|
|
||||||
|
this.setMode(this.MODE.global);
|
||||||
|
this._setData(JSON.parse(localStorage.getItem(this.key) || "{}"));
|
||||||
|
},
|
||||||
_getData: function(key) {
|
_getData: function(key) {
|
||||||
if( this.mode == this.MODE.private ) {
|
var storage = popup.storage;
|
||||||
|
if( storage.mode == storage.MODE.private ) {
|
||||||
if( key ) {
|
if( key ) {
|
||||||
return this.data.private[key];
|
return storage.data.private[key];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return this.data.private;
|
return storage.data.private;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( this.mode == this.MODE.global ) {
|
if( storage.mode == storage.MODE.global ) {
|
||||||
if( key ) {
|
if( key ) {
|
||||||
return this.data.global[key];
|
return storage.data.global[key];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return this.data.global;
|
return storage.data.global;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_setData: function(data, key) {
|
_setData: function(data, key) {
|
||||||
if( this.mode == this.MODE.private ) {
|
var storage = popup.storage;
|
||||||
|
if( storage.mode == storage.MODE.private ) {
|
||||||
if( key ) {
|
if( key ) {
|
||||||
this.data.private[key] = data;
|
storage.data.private[key] = data;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.data.private = data;
|
storage.data.private = data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( this.mode == this.MODE.global ) {
|
if( storage.mode == storage.MODE.global ) {
|
||||||
if( key ) {
|
if( key ) {
|
||||||
this.data.global[key] = data;
|
storage.data.global[key] = data;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.data.global = data;
|
storage.data.global = data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
get: function(key) {
|
get: function(key) {
|
||||||
if( this._getData() === undefined ) {
|
|
||||||
this._setData(JSON.parse(localStorage.getItem(this.key) || "{}"));
|
|
||||||
}
|
|
||||||
return this._getData(key);
|
return this._getData(key);
|
||||||
},
|
},
|
||||||
set: function(arg1, arg2) {
|
set: function(arg1, arg2) {
|
||||||
|
@ -150,6 +159,7 @@
|
||||||
if( key ) {
|
if( key ) {
|
||||||
var data = this._getData();
|
var data = this._getData();
|
||||||
delete data[key];
|
delete data[key];
|
||||||
|
|
||||||
if( $.isEmptyObject(data) ) {
|
if( $.isEmptyObject(data) ) {
|
||||||
this.remove();
|
this.remove();
|
||||||
}
|
}
|
||||||
|
@ -165,70 +175,75 @@
|
||||||
},
|
},
|
||||||
apiclb: {
|
apiclb: {
|
||||||
onSelectedTab: function(tab) {
|
onSelectedTab: function(tab) {
|
||||||
var handlers = popup.apiclb;
|
|
||||||
|
|
||||||
popup.tabId = tab.id;
|
popup.tabId = tab.id;
|
||||||
|
chrome.tabs.sendRequest(popup.tabId, {method: "getData", reload: false}, popup.apiclb.onGetData);
|
||||||
chrome.tabs.sendRequest(popup.tabId, {method: "getHost", reload: false}, handlers.onGetHost);
|
|
||||||
chrome.tabs.sendRequest(popup.tabId, {method: "getCustomJS", reload: false}, handlers.onGetScript);
|
|
||||||
},
|
},
|
||||||
onGetHost: function(response) {
|
onGetData: function(response) {
|
||||||
if( !response || typeof response.host !== 'string' ) {
|
if( !response || typeof response.host !== 'string' ) {
|
||||||
popup.error();
|
popup.error();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create 'hosts select'
|
||||||
|
*/
|
||||||
|
|
||||||
popup.host = response.host;
|
popup.host = response.host;
|
||||||
|
popup.protocol = response.protocol;
|
||||||
|
|
||||||
|
// Set storage to store data accessible from all hosts
|
||||||
popup.storage.setMode(popup.storage.MODE.global);
|
popup.storage.setMode(popup.storage.MODE.global);
|
||||||
var hosts = popup.storage.get('hosts') || [];
|
|
||||||
|
|
||||||
if( hosts.indexOf(response.host) === -1 ) {
|
var hosts = popup.storage.get('hosts') || [],
|
||||||
hosts.push(response.host);
|
url = popup.protocol + "//" + response.host;
|
||||||
|
|
||||||
|
// Add current host to list
|
||||||
|
if( hosts.indexOf(url) === -1 ) {
|
||||||
|
hosts.push(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fill 'hosts select'
|
||||||
hosts.forEach(function(host) {
|
hosts.forEach(function(host) {
|
||||||
var option = $('<option>' + host + '</option>');
|
var option = $('<option>' + host + '</option>');
|
||||||
if( host === response.host ) {
|
if( host === url ) {
|
||||||
option.attr('selected', 'selected');
|
option.attr('selected', 'selected');
|
||||||
}
|
}
|
||||||
popup.el.hostSelect.append(option);
|
popup.el.hostSelect.append(option);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Store host (current included in array) if is customjs defined
|
||||||
|
if( response.customjs ) {
|
||||||
popup.storage.set('hosts', hosts);
|
popup.storage.set('hosts', hosts);
|
||||||
},
|
|
||||||
onGetScript: function(response) {
|
|
||||||
var data = response.customjs || {},
|
|
||||||
conf = response.customjs.config || {};
|
|
||||||
|
|
||||||
// Backward compatibility (version 1)
|
|
||||||
if( data.src ) {
|
|
||||||
data.source = decodeURI(data.src);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( data.source ) {
|
/**
|
||||||
// source is encoded as base64
|
* Set-up data (script, enable, include, extra)
|
||||||
if( data.source.indexOf('data:text/javascript;base64,') === 0 ) {
|
*/
|
||||||
data.source = data.source.replace('data:text/javascript;base64,', '');
|
|
||||||
popup.data.source = atob(data.source);
|
// Backward compatibility (version <1 and 1)
|
||||||
}
|
if( response.customjs && response.customjs.src ) {
|
||||||
else {
|
response.customjs.source = decodeURI(response.customjs.src); // Old format ...
|
||||||
popup.data.source = data.source;
|
delete response.customjs.src;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
popup.data.config.enable = conf.enable ? true : false;
|
// Merge host's data to defaults
|
||||||
|
popup.data = $.extend(popup.data, response.customjs);
|
||||||
|
|
||||||
if( conf.include ) {
|
// ... source is now encoded as base64
|
||||||
popup.data.config.include = conf.include;
|
if( popup.data.source.indexOf('data:text/javascript;base64,') === 0 ) {
|
||||||
|
popup.data.source = popup.data.source.replace('data:text/javascript;base64,', '');
|
||||||
|
popup.data.source = atob(popup.data.source);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( conf.extra ) {
|
// Set storage to store data accessible ONLY from current host
|
||||||
popup.data.config.extra = conf.extra;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply draft if exist
|
|
||||||
popup.storage.setMode(popup.storage.MODE.private);
|
popup.storage.setMode(popup.storage.MODE.private);
|
||||||
|
|
||||||
|
// Save local copy of live data
|
||||||
|
if( response.customjs ) {
|
||||||
|
popup.storage.set('data', popup.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply data (draft if exist)
|
||||||
popup.applyData(popup.storage.get('draft'));
|
popup.applyData(popup.storage.get('draft'));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -241,13 +256,14 @@
|
||||||
},
|
},
|
||||||
source: ''
|
source: ''
|
||||||
},
|
},
|
||||||
applyData: function(draft) {
|
applyData: function(data, notDraft) {
|
||||||
var data = draft || this.data;
|
|
||||||
|
|
||||||
if( draft ) {
|
if( data && !notDraft ) {
|
||||||
this.el.draftRemoveLink.removeClass('is-hidden');
|
this.el.draftRemoveLink.removeClass('is-hidden');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data = data || this.data;
|
||||||
|
|
||||||
// Default value for 'extra include'
|
// Default value for 'extra include'
|
||||||
if( !data.config.extra ) {
|
if( !data.config.extra ) {
|
||||||
data.config.extra = '# ' + popup.title.include.textarea + "\n";
|
data.config.extra = '# ' + popup.title.include.textarea + "\n";
|
||||||
|
@ -255,24 +271,18 @@
|
||||||
data.config.extra += '# ' + url + "\n";
|
data.config.extra += '# ' + url + "\n";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// Readable format for 'extra include'
|
||||||
|
else {
|
||||||
|
data.config.extra = data.config.extra.replace(';', "\n");
|
||||||
|
}
|
||||||
|
|
||||||
// Default value for source
|
// Default value for source
|
||||||
if( !data.source ) {
|
if( !data.source ) {
|
||||||
data.source = popup.editor.defaultValue;
|
data.source = popup.editor.defaultValue;
|
||||||
}
|
}
|
||||||
// Source copy is current, isn't necessary to highlight save button
|
|
||||||
else {
|
|
||||||
popup.el.saveBtn.removeClass('pure-button-primary');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set 'predefined include' value
|
// Set 'predefined include' value
|
||||||
if( data.config.include ) {
|
popup.el.includeSelect.val(data.config.include);
|
||||||
popup.include.predefined.forEach(function(lib) {
|
|
||||||
if( lib.path === data.config.include ) {
|
|
||||||
popup.el.includeSelect.val(lib.path);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set enable checkbox
|
// Set enable checkbox
|
||||||
popup.el.enableCheck.prop('checked', data.config.enable);
|
popup.el.enableCheck.prop('checked', data.config.enable);
|
||||||
|
@ -295,22 +305,36 @@
|
||||||
},
|
},
|
||||||
removeDraft: function() {
|
removeDraft: function() {
|
||||||
popup.storage.setMode(popup.storage.MODE.private);
|
popup.storage.setMode(popup.storage.MODE.private);
|
||||||
popup.storage.remove('draft', null);
|
popup.storage.remove('draft');
|
||||||
|
|
||||||
popup.applyData();
|
popup.applyData();
|
||||||
popup.el.draftRemoveLink.addClass('is-hidden');
|
popup.el.draftRemoveLink.addClass('is-hidden');
|
||||||
},
|
},
|
||||||
save: function(e) {
|
save: function(e) {
|
||||||
var data = popup.getCurrentData();
|
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
|
// Is allowed to save?
|
||||||
|
if( popup.el.saveBtn.hasClass('pure-button-disabled') ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var data = popup.getCurrentData();
|
||||||
|
|
||||||
|
// Transform source for correct apply
|
||||||
data.config.extra = data.config.extra.replace("\n", ';');
|
data.config.extra = data.config.extra.replace("\n", ';');
|
||||||
data.source = 'data:text/javascript;base64,' + btoa(data.source);
|
data.source = 'data:text/javascript;base64,' + btoa(data.source);
|
||||||
|
|
||||||
chrome.tabs.sendRequest(popup.tabId, {method: "setCustomJS", customjs: data, reload: true});
|
// Send new data to apply
|
||||||
|
chrome.tabs.sendRequest(popup.tabId, {method: "setData", customjs: data, reload: true});
|
||||||
|
|
||||||
|
// Save local copy of data
|
||||||
|
popup.storage.setMode(popup.storage.MODE.private);
|
||||||
|
popup.storage.set('data', popup.data);
|
||||||
|
|
||||||
|
// Clear draft
|
||||||
popup.removeDraft();
|
popup.removeDraft();
|
||||||
|
|
||||||
|
// Close popup
|
||||||
window.close();
|
window.close();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -322,6 +346,11 @@
|
||||||
|
|
||||||
window.popup = popup;
|
window.popup = popup;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load storage (global, local) IMPORTANT: Must be called first of all
|
||||||
|
*/
|
||||||
|
popup.storage.load();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add titles to elements
|
* Add titles to elements
|
||||||
*/
|
*/
|
||||||
|
@ -329,6 +358,37 @@
|
||||||
popup.applyTitles();
|
popup.applyTitles();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change host by select
|
||||||
|
*/
|
||||||
|
|
||||||
|
popup.el.hostSelect.on('change', function(e) {
|
||||||
|
var host = $(this).val();
|
||||||
|
if( host !== popup.protocol + '//' + popup.host ) {
|
||||||
|
popup.el.hostGoToLink.removeClass('is-hidden');
|
||||||
|
popup.el.saveBtn.addClass('pure-button-disabled');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
popup.el.hostGoToLink.addClass('is-hidden');
|
||||||
|
popup.el.saveBtn.removeClass('pure-button-disabled');
|
||||||
|
}
|
||||||
|
|
||||||
|
var hostData = JSON.parse(localStorage.getItem(popup.key + '-' + host), true);
|
||||||
|
popup.applyData(hostData.data, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Click to goTo host link
|
||||||
|
*/
|
||||||
|
popup.el.hostGoToLink.on('click', function() {
|
||||||
|
var link = popup.el.hostSelect.val();
|
||||||
|
chrome.tabs.sendRequest(popup.tabId, {method: "goTo", link: link, reload: false});
|
||||||
|
$(this).addClass('is-hidden');
|
||||||
|
popup.el.saveBtn.removeClass('pure-button-disabled');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fill predefined libs to include
|
* Fill predefined libs to include
|
||||||
*/
|
*/
|
||||||
|
@ -374,22 +434,19 @@
|
||||||
var draft = popup.getCurrentData(),
|
var draft = popup.getCurrentData(),
|
||||||
source = draft.source;
|
source = draft.source;
|
||||||
if( (source || !popup.data.source) && source !== popup.data.source ) {
|
if( (source || !popup.data.source) && source !== popup.data.source ) {
|
||||||
|
|
||||||
popup.storage.setMode(popup.storage.MODE.private);
|
popup.storage.setMode(popup.storage.MODE.private);
|
||||||
popup.storage.set('draft', draft);
|
popup.storage.set('draft', draft);
|
||||||
// Highlight save button
|
|
||||||
popup.el.saveBtn.addClass('pure-button-primary')
|
|
||||||
// Auto switch 'enable checkbox' on source edit
|
// Auto switch 'enable checkbox' on source edit
|
||||||
popup.el.enableCheck.prop('checked', true);
|
popup.el.enableCheck.prop('checked', true);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
// No changes or no source - remove save button highlight
|
|
||||||
popup.el.saveBtn.removeClass('pure-button-primary')
|
|
||||||
}
|
|
||||||
}, 2000);
|
}, 2000);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save script
|
* Save script
|
||||||
*/
|
*/
|
||||||
|
|
||||||
popup.el.popupForm.on('submit', popup.save);
|
popup.el.popupForm.on('submit', popup.save);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -56,18 +56,18 @@
|
||||||
|
|
||||||
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
|
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
|
||||||
switch(request.method) {
|
switch(request.method) {
|
||||||
case 'getHost':
|
case 'setData':
|
||||||
sendResponse({host: location.host});
|
|
||||||
break;
|
|
||||||
case 'setCustomJS':
|
|
||||||
localStorage['customjs'] = JSON.stringify(request.customjs);
|
localStorage['customjs'] = JSON.stringify(request.customjs);
|
||||||
case 'getCustomJS':
|
case 'getData':
|
||||||
var customjs = JSON.parse(localStorage['customjs'] || '{}');
|
var customjs = JSON.parse(localStorage['customjs'] || 'false');
|
||||||
sendResponse({customjs: customjs});
|
sendResponse({customjs: customjs, host: location.host, protocol: location.protocol});
|
||||||
break;
|
break;
|
||||||
case 'removeCustomJS':
|
case 'removeData':
|
||||||
delete localStorage['customjs'];
|
delete localStorage['customjs'];
|
||||||
break;
|
break;
|
||||||
|
case 'goTo':
|
||||||
|
window.location = request.link;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
sendResponse({src: '', config: {}});
|
sendResponse({src: '', config: {}});
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@
|
||||||
|
|
||||||
<div class="pure-g controls">
|
<div class="pure-g controls">
|
||||||
<div class="pure-u-2-5 controls__save">
|
<div class="pure-u-2-5 controls__save">
|
||||||
<input type="submit" id="save" class="pure-button" name="save" value="save">
|
<input type="submit" id="save" class="pure-button pure-button-primary" name="save" value="save">
|
||||||
<a id="draft-remove" class="controls__remove-draft red-text is-hidden" href="#">remove draft</a>
|
<a id="draft-remove" class="controls__remove-draft red-text is-hidden" href="#">remove draft</a>
|
||||||
</div>
|
</div>
|
||||||
</div><!-- .controls -->
|
</div><!-- .controls -->
|
||||||
|
|
Reference in a new issue