1
0
Fork 0

Host switch

This commit is contained in:
Dan Hromada 2014-05-12 15:20:54 +02:00
parent 592e324f6e
commit e7ecedccec
3 changed files with 151 additions and 94 deletions

View file

@ -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);

View file

@ -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: {}});
} }

View file

@ -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 -->