Fix the horrible whitespacing
This commit is contained in:
parent
d5518a164e
commit
a9dd23a52c
17 changed files with 1311 additions and 1309 deletions
338
js/editor.js
338
js/editor.js
|
|
@ -1,169 +1,169 @@
|
|||
let fileId = window.location.hash.substr(1);
|
||||
let file = {};
|
||||
|
||||
let enableInput = document.getElementById("enable-input");
|
||||
let nameInput = document.getElementById("name-input");
|
||||
let linksBtn = document.getElementById("links-btn");
|
||||
let saveBtn = document.getElementById("save-btn");
|
||||
let editor = ace.edit("editor");
|
||||
editor.setTheme("ace/theme/monokai");
|
||||
|
||||
File.load(fileId).then((f) => {
|
||||
let info = (file = f).info;
|
||||
enableInput.parentNode.classList.add("no-transition");
|
||||
enableInput.checked = info.enabled;
|
||||
setTimeout(()=>{enableInput.parentNode.classList.remove("no-transition")}, 0);
|
||||
nameInput.value = info.name;
|
||||
editor.setValue(info.content||"", -1);
|
||||
|
||||
if(info.type == "JS") {
|
||||
editor.session.setMode("ace/mode/javascript");
|
||||
} else {
|
||||
editor.session.setMode("ace/mode/css");
|
||||
}
|
||||
|
||||
if(info.links) {
|
||||
info.links.forEach((link) => {
|
||||
createLinkEntry(link);
|
||||
});
|
||||
createLinkEntry();
|
||||
}
|
||||
|
||||
f.onChange = function(info){
|
||||
enableInput.checked = info.enabled;
|
||||
nameInput.value = info.name;
|
||||
}
|
||||
|
||||
enableInput.addEventListener("input", editorSetEdited);
|
||||
nameInput.addEventListener("input", editorSetEdited);
|
||||
editor.session.on("change", editorSetEdited);
|
||||
});
|
||||
|
||||
function editorSetEdited() {
|
||||
saveBtn.classList.add("edited");
|
||||
}
|
||||
|
||||
/* export */
|
||||
let downloadLink = document.createElement("a");
|
||||
downloadLink.style.display = "none";
|
||||
document.body.appendChild(downloadLink);
|
||||
|
||||
let downloadBtn = document.getElementById("download-btn");
|
||||
downloadBtn.addEventListener("click", () => {
|
||||
save();
|
||||
let info = file.info;
|
||||
delete info.id;
|
||||
downloadLink.href = "data:text/json;charset=utf-8," +
|
||||
encodeURIComponent(JSON.stringify(info));
|
||||
downloadLink.download = info.name + ".json";
|
||||
downloadLink.click();
|
||||
});
|
||||
|
||||
|
||||
/* links */
|
||||
let popupActive = false;
|
||||
let popup = document.getElementById("links-popup");
|
||||
let linksWrapper = document.getElementById("links-wrapper");
|
||||
|
||||
linksBtn.addEventListener("click", (e) => {
|
||||
e.stopPropagation();
|
||||
|
||||
if(popupActive) {
|
||||
popup.style.display = "none";
|
||||
popupActive = false;
|
||||
} else {
|
||||
popup.style.display = "flex";
|
||||
popupActive = true;
|
||||
}
|
||||
});
|
||||
|
||||
function linksClose() {
|
||||
if(popupActive) {
|
||||
popup.style.display = "none";
|
||||
popupActive = false;
|
||||
save();
|
||||
}
|
||||
}
|
||||
document.getElementById("close-links-btn").
|
||||
addEventListener("click", linksClose);
|
||||
document.addEventListener("mousedown", linksClose);
|
||||
window.addEventListener("keydown", (e) => {
|
||||
if(e.key === "Escape") { linksClose(); }
|
||||
});
|
||||
|
||||
popup.addEventListener("mousedown", (e) => {
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
function createLinkEntry(link = "") {
|
||||
let empty = link == "";
|
||||
|
||||
let entry = document.createElement("div");
|
||||
entry.className = "link-entry";
|
||||
entry.innerHTML = `
|
||||
<input type="text" value="${link}" placeholder="Add a target website"/>
|
||||
<svg viewBox="0 0 24 24" title="Delete entry">
|
||||
<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
let entryInput = entry.querySelector("input");
|
||||
entryInput.addEventListener("input", () => {
|
||||
if(empty) {
|
||||
entrySvg.style.display = "";
|
||||
empty = false;
|
||||
createLinkEntry();
|
||||
}
|
||||
editorSetEdited();
|
||||
});
|
||||
entryInput.addEventListener("blur", () => {
|
||||
if(entryInput.value == "" && !empty) {
|
||||
entry.remove();
|
||||
}
|
||||
});
|
||||
|
||||
let entrySvg = entry.querySelector("svg");
|
||||
if(empty) { entrySvg.style.display = "none"; }
|
||||
entrySvg.addEventListener("click", () => {
|
||||
if(!empty) {
|
||||
entry.remove();
|
||||
editorSetEdited();
|
||||
}
|
||||
});
|
||||
|
||||
linksWrapper.appendChild(entry);
|
||||
}
|
||||
|
||||
/* save */
|
||||
enableInput.addEventListener("change", save);
|
||||
|
||||
function save() {
|
||||
let info = file.info;
|
||||
info.enabled = enableInput.checked;
|
||||
info.name = nameInput.value;
|
||||
info.content = editor.getValue();
|
||||
|
||||
let links = [];
|
||||
let inputs = linksWrapper.querySelectorAll("input");
|
||||
if(inputs) {
|
||||
inputs.forEach((input) => {
|
||||
if(input.value != "") {
|
||||
links.push(input.value);
|
||||
}
|
||||
});
|
||||
}
|
||||
info.links = links;
|
||||
|
||||
file.touch();
|
||||
file.save();
|
||||
WebDAV.putFile(file.info);
|
||||
saveBtn.classList.remove("edited");
|
||||
}
|
||||
saveBtn.addEventListener("click", save);
|
||||
window.addEventListener("keydown", (e) => {
|
||||
if(e.ctrlKey && e.key=="s") {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
save();
|
||||
}
|
||||
}, true);
|
||||
let fileId = window.location.hash.substr(1);
|
||||
let file = {};
|
||||
|
||||
let enableInput = document.getElementById("enable-input");
|
||||
let nameInput = document.getElementById("name-input");
|
||||
let linksBtn = document.getElementById("links-btn");
|
||||
let saveBtn = document.getElementById("save-btn");
|
||||
let editor = ace.edit("editor");
|
||||
editor.setTheme("ace/theme/monokai");
|
||||
|
||||
File.load(fileId).then((f) => {
|
||||
let info = (file = f).info;
|
||||
enableInput.parentNode.classList.add("no-transition");
|
||||
enableInput.checked = info.enabled;
|
||||
setTimeout(()=>{enableInput.parentNode.classList.remove("no-transition")}, 0);
|
||||
nameInput.value = info.name;
|
||||
editor.setValue(info.content||"", -1);
|
||||
|
||||
if(info.type == "JS") {
|
||||
editor.session.setMode("ace/mode/javascript");
|
||||
} else {
|
||||
editor.session.setMode("ace/mode/css");
|
||||
}
|
||||
|
||||
if(info.links) {
|
||||
info.links.forEach((link) => {
|
||||
createLinkEntry(link);
|
||||
});
|
||||
createLinkEntry();
|
||||
}
|
||||
|
||||
f.onChange = function(info){
|
||||
enableInput.checked = info.enabled;
|
||||
nameInput.value = info.name;
|
||||
}
|
||||
|
||||
enableInput.addEventListener("input", editorSetEdited);
|
||||
nameInput.addEventListener("input", editorSetEdited);
|
||||
editor.session.on("change", editorSetEdited);
|
||||
});
|
||||
|
||||
function editorSetEdited() {
|
||||
saveBtn.classList.add("edited");
|
||||
}
|
||||
|
||||
/* export */
|
||||
let downloadLink = document.createElement("a");
|
||||
downloadLink.style.display = "none";
|
||||
document.body.appendChild(downloadLink);
|
||||
|
||||
let downloadBtn = document.getElementById("download-btn");
|
||||
downloadBtn.addEventListener("click", () => {
|
||||
save();
|
||||
let info = file.info;
|
||||
delete info.id;
|
||||
downloadLink.href = "data:text/json;charset=utf-8," +
|
||||
encodeURIComponent(JSON.stringify(info));
|
||||
downloadLink.download = info.name + ".json";
|
||||
downloadLink.click();
|
||||
});
|
||||
|
||||
|
||||
/* links */
|
||||
let popupActive = false;
|
||||
let popup = document.getElementById("links-popup");
|
||||
let linksWrapper = document.getElementById("links-wrapper");
|
||||
|
||||
linksBtn.addEventListener("click", (e) => {
|
||||
e.stopPropagation();
|
||||
|
||||
if(popupActive) {
|
||||
popup.style.display = "none";
|
||||
popupActive = false;
|
||||
} else {
|
||||
popup.style.display = "flex";
|
||||
popupActive = true;
|
||||
}
|
||||
});
|
||||
|
||||
function linksClose() {
|
||||
if(popupActive) {
|
||||
popup.style.display = "none";
|
||||
popupActive = false;
|
||||
save();
|
||||
}
|
||||
}
|
||||
document.getElementById("close-links-btn").
|
||||
addEventListener("click", linksClose);
|
||||
document.addEventListener("mousedown", linksClose);
|
||||
window.addEventListener("keydown", (e) => {
|
||||
if(e.key === "Escape") { linksClose(); }
|
||||
});
|
||||
|
||||
popup.addEventListener("mousedown", (e) => {
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
function createLinkEntry(link = "") {
|
||||
let empty = link == "";
|
||||
|
||||
let entry = document.createElement("div");
|
||||
entry.className = "link-entry";
|
||||
entry.innerHTML = `
|
||||
<input type="text" value="${link}" placeholder="Add a target website"/>
|
||||
<svg viewBox="0 0 24 24" title="Delete entry">
|
||||
<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
let entryInput = entry.querySelector("input");
|
||||
entryInput.addEventListener("input", () => {
|
||||
if(empty) {
|
||||
entrySvg.style.display = "";
|
||||
empty = false;
|
||||
createLinkEntry();
|
||||
}
|
||||
editorSetEdited();
|
||||
});
|
||||
entryInput.addEventListener("blur", () => {
|
||||
if(entryInput.value == "" && !empty) {
|
||||
entry.remove();
|
||||
}
|
||||
});
|
||||
|
||||
let entrySvg = entry.querySelector("svg");
|
||||
if(empty) { entrySvg.style.display = "none"; }
|
||||
entrySvg.addEventListener("click", () => {
|
||||
if(!empty) {
|
||||
entry.remove();
|
||||
editorSetEdited();
|
||||
}
|
||||
});
|
||||
|
||||
linksWrapper.appendChild(entry);
|
||||
}
|
||||
|
||||
/* save */
|
||||
enableInput.addEventListener("change", save);
|
||||
|
||||
function save() {
|
||||
let info = file.info;
|
||||
info.enabled = enableInput.checked;
|
||||
info.name = nameInput.value;
|
||||
info.content = editor.getValue();
|
||||
|
||||
let links = [];
|
||||
let inputs = linksWrapper.querySelectorAll("input");
|
||||
if(inputs) {
|
||||
inputs.forEach((input) => {
|
||||
if(input.value != "") {
|
||||
links.push(input.value);
|
||||
}
|
||||
});
|
||||
}
|
||||
info.links = links;
|
||||
|
||||
file.touch();
|
||||
file.save();
|
||||
WebDAV.putFile(file.info);
|
||||
saveBtn.classList.remove("edited");
|
||||
}
|
||||
saveBtn.addEventListener("click", save);
|
||||
window.addEventListener("keydown", (e) => {
|
||||
if(e.ctrlKey && e.key=="s") {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
save();
|
||||
}
|
||||
}, true);
|
||||
|
|
|
|||
198
js/file.js
198
js/file.js
|
|
@ -1,99 +1,99 @@
|
|||
function File(id){
|
||||
let _this = this;
|
||||
if(!id) id = File.uuid();
|
||||
let info = this.info = {id, enabled:true};
|
||||
|
||||
this.changeInfo = function(i){
|
||||
for(let _i in i){
|
||||
info[_i] = i[_i];
|
||||
}
|
||||
};
|
||||
this.touch = function(){
|
||||
info.lastModified = ((new Date()).getTime() / 1000)|0;
|
||||
}
|
||||
|
||||
this.save = function(){
|
||||
return new Promise(function(succ, err){
|
||||
Storage.save({[File.PREFIX+info.id]:info}).then(_ => {
|
||||
File.saveIndex(info.id, info.enabled).then(succ);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
this.onChange = function(info){}; //Placeholder function
|
||||
Storage.onChange(File.PREFIX+id, newInfo => {
|
||||
_this.changeInfo(newInfo);
|
||||
_this.onChange(newInfo);
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
File.PREFIX = "FILE-";
|
||||
File.saveIndex = function(id, enabled){
|
||||
return new Promise((succ, err) => {
|
||||
File.loadIndex().then((index) => {
|
||||
index[id] = enabled;
|
||||
Storage.save({"INDEX":index}).then(succ);
|
||||
});
|
||||
});
|
||||
};
|
||||
File.loadIndex = function(){
|
||||
return new Promise((succ, err) => {
|
||||
Storage.load(["INDEX"]).then((result) => {
|
||||
let index = result["INDEX"] || {};
|
||||
succ(index);
|
||||
});
|
||||
});
|
||||
};
|
||||
File.uuid = function(){
|
||||
return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
|
||||
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
|
||||
)
|
||||
};
|
||||
File.remove = function(id){
|
||||
return new Promise((succ, err) => {
|
||||
File.loadIndex().then((index) => {
|
||||
delete index[id];
|
||||
Storage.save({"INDEX":index}).then(_ => {
|
||||
Storage.remove([File.PREFIX+id]).then(succ);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
File.load = function(id){
|
||||
return new Promise((succ, err) => {
|
||||
let innerID = File.PREFIX+id;
|
||||
Storage.load([innerID]).then(result => {
|
||||
if(!result[innerID]) err();
|
||||
let file = new File(id);
|
||||
file.changeInfo(result[innerID]);
|
||||
succ(file);
|
||||
});
|
||||
});
|
||||
};
|
||||
File.loadAll = function(){
|
||||
return new Promise((succ, err) => {
|
||||
let files = [];
|
||||
File.loadIndex().then((index) => {
|
||||
for(let id in index){
|
||||
files.push(File.load(id));
|
||||
}
|
||||
Promise.all(files).then((files) => {
|
||||
succ(files);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
File.loadEnabled = function(){
|
||||
return new Promise((succ, err) => {
|
||||
let files = [];
|
||||
File.loadIndex().then((index) => {
|
||||
for(let id in index){
|
||||
if(index[id]) files.push(File.load(id));
|
||||
}
|
||||
Promise.all(files).then((files) => {
|
||||
succ(files);
|
||||
})
|
||||
});
|
||||
});
|
||||
};
|
||||
function File(id){
|
||||
let _this = this;
|
||||
if(!id) id = File.uuid();
|
||||
let info = this.info = {id, enabled:true};
|
||||
|
||||
this.changeInfo = function(i){
|
||||
for(let _i in i){
|
||||
info[_i] = i[_i];
|
||||
}
|
||||
};
|
||||
this.touch = function(){
|
||||
info.lastModified = ((new Date()).getTime() / 1000)|0;
|
||||
}
|
||||
|
||||
this.save = function(){
|
||||
return new Promise(function(succ, err){
|
||||
Storage.save({[File.PREFIX+info.id]:info}).then(_ => {
|
||||
File.saveIndex(info.id, info.enabled).then(succ);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
this.onChange = function(info){}; //Placeholder function
|
||||
Storage.onChange(File.PREFIX+id, newInfo => {
|
||||
_this.changeInfo(newInfo);
|
||||
_this.onChange(newInfo);
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
File.PREFIX = "FILE-";
|
||||
File.saveIndex = function(id, enabled){
|
||||
return new Promise((succ, err) => {
|
||||
File.loadIndex().then((index) => {
|
||||
index[id] = enabled;
|
||||
Storage.save({"INDEX":index}).then(succ);
|
||||
});
|
||||
});
|
||||
};
|
||||
File.loadIndex = function(){
|
||||
return new Promise((succ, err) => {
|
||||
Storage.load(["INDEX"]).then((result) => {
|
||||
let index = result["INDEX"] || {};
|
||||
succ(index);
|
||||
});
|
||||
});
|
||||
};
|
||||
File.uuid = function(){
|
||||
return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
|
||||
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
|
||||
)
|
||||
};
|
||||
File.remove = function(id){
|
||||
return new Promise((succ, err) => {
|
||||
File.loadIndex().then((index) => {
|
||||
delete index[id];
|
||||
Storage.save({"INDEX":index}).then(_ => {
|
||||
Storage.remove([File.PREFIX+id]).then(succ);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
File.load = function(id){
|
||||
return new Promise((succ, err) => {
|
||||
let innerID = File.PREFIX+id;
|
||||
Storage.load([innerID]).then(result => {
|
||||
if(!result[innerID]) err();
|
||||
let file = new File(id);
|
||||
file.changeInfo(result[innerID]);
|
||||
succ(file);
|
||||
});
|
||||
});
|
||||
};
|
||||
File.loadAll = function(){
|
||||
return new Promise((succ, err) => {
|
||||
let files = [];
|
||||
File.loadIndex().then((index) => {
|
||||
for(let id in index){
|
||||
files.push(File.load(id));
|
||||
}
|
||||
Promise.all(files).then((files) => {
|
||||
succ(files);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
File.loadEnabled = function(){
|
||||
return new Promise((succ, err) => {
|
||||
let files = [];
|
||||
File.loadIndex().then((index) => {
|
||||
for(let id in index){
|
||||
if(index[id]) files.push(File.load(id));
|
||||
}
|
||||
Promise.all(files).then((files) => {
|
||||
succ(files);
|
||||
})
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
|
|||
298
js/index.js
298
js/index.js
|
|
@ -1,149 +1,149 @@
|
|||
function createFileEntry(fileObject, element){
|
||||
let info = fileObject.info;
|
||||
let file = document.createElement("div");
|
||||
file.className = "file";
|
||||
file.innerHTML = `
|
||||
<label class="check" title="Enable or disable file"><input type="checkbox" ${info.enabled?"checked='true'":""}><span></span></label>
|
||||
<span class="file-name">${info.name}</span>
|
||||
<span class="file-type" data-type="${info.type}">${info.type}</span>
|
||||
<div class="file-icons">
|
||||
<span class="file-icon file-edit" title="Edit file">
|
||||
<svg viewBox="0 0 48 48">
|
||||
<path d="M6 34.5v7.5h7.5l22.13-22.13-7.5-7.5-22.13 22.13zm35.41-20.41c.78-.78.78-2.05 0-2.83l-4.67-4.67c-.78-.78-2.05-.78-2.83 0l-3.66 3.66 7.5 7.5 3.66-3.66z"/>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="file-icon file-delete" title="Delete file">
|
||||
<svg viewBox="0 0 48 48">
|
||||
<path d="M12 38c0 2.21 1.79 4 4 4h16c2.21 0 4-1.79 4-4v-24h-24v24zm26-30h-7l-2-2h-10l-2 2h-7v4h28v-4z"/>
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
let fileName = file.querySelector(".file-name");
|
||||
let fileType = file.querySelector(".file-type");
|
||||
let fileEnable = file.querySelector("input");
|
||||
fileEnable.addEventListener("change", function(){
|
||||
info.enabled = this.checked;
|
||||
fileObject.save();
|
||||
});
|
||||
let fileEdit = file.querySelector(".file-icon.file-edit");
|
||||
fileEdit.addEventListener("click", edit);
|
||||
let fileDelete = file.querySelector(".file-icon.file-delete");
|
||||
fileDelete.addEventListener("click", function(){
|
||||
if(fileDelete.classList.contains("icon-confirm")){
|
||||
File.remove(info.id).then(function(){
|
||||
file.remove();
|
||||
});
|
||||
}else{
|
||||
fileDelete.classList.add("icon-confirm");
|
||||
setTimeout(function(){
|
||||
fileDelete.classList.remove("icon-confirm");
|
||||
}, 1000);
|
||||
}
|
||||
});
|
||||
file.addEventListener("click", e => {
|
||||
if(e.target.className=="file") edit();
|
||||
});
|
||||
element.appendChild(file);
|
||||
|
||||
fileObject.onChange = function(info){
|
||||
fileEnable.checked = info.enabled;
|
||||
fileName.textContent = info.name;
|
||||
}
|
||||
|
||||
function edit(){
|
||||
chrome.tabs.create({url: chrome.runtime.getURL("editor.html#"+info.id)});
|
||||
}
|
||||
}
|
||||
|
||||
let filesElement = document.getElementById("files");
|
||||
File.loadAll().then(function(files){
|
||||
files = files.sort((a, b) => {
|
||||
if(a.info.name < b.info.name) return -1;
|
||||
if(a.info.name > b.info.name) return 1;
|
||||
return 0;
|
||||
});
|
||||
for(let i=0;i<files.length;i++){
|
||||
createFileEntry(files[i], filesElement);
|
||||
}
|
||||
});
|
||||
|
||||
let newFileJS = document.getElementById("new-js");
|
||||
newFileJS.addEventListener("click", () => {
|
||||
let f = new File();
|
||||
f.changeInfo({type: "JS", name: "New Script"});
|
||||
f.save().then(() => {
|
||||
createFileEntry(f, filesElement);
|
||||
});
|
||||
});
|
||||
|
||||
let newFileCSS = document.getElementById("new-css");
|
||||
newFileCSS.addEventListener("click", () => {
|
||||
let f = new File();
|
||||
f.changeInfo({type: "CSS", name: "New Stylesheet"});
|
||||
f.save().then(() => {
|
||||
createFileEntry(f, filesElement);
|
||||
});
|
||||
});
|
||||
|
||||
/* file input */
|
||||
function newFromFile(inFile) {
|
||||
let info = {};
|
||||
|
||||
if(inFile.type == "text/javascript") {
|
||||
info.type = "JS";
|
||||
info.name = inFile.name.match(/(.*)\..*$/);
|
||||
} else if(inFile.type == "text/css") {
|
||||
info.type = "CSS";
|
||||
info.name = inFile.name.match(/(.*)\..*$/);
|
||||
} else if(inFile.type == "application/json") {
|
||||
} else {
|
||||
alert("Unsupported file type");
|
||||
return;
|
||||
}
|
||||
|
||||
let reader = new FileReader();
|
||||
reader.addEventListener("load", () => {
|
||||
if(inFile.type == "application/json") {
|
||||
try {
|
||||
info = JSON.parse(reader.result);
|
||||
} catch(e) { alert("The uploaded json file is not valid"); }
|
||||
} else {
|
||||
info.content = reader.result;
|
||||
}
|
||||
|
||||
let f = new File();
|
||||
f.changeInfo(info);
|
||||
f.save().then(() => {
|
||||
createFileEntry(f, filesElement);
|
||||
});
|
||||
});
|
||||
reader.readAsText(inFile);
|
||||
}
|
||||
|
||||
document.body.addEventListener("dragover", (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
document.body.classList.add("drag-over");
|
||||
});
|
||||
document.body.addEventListener("dragleave", (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
document.body.classList.remove("drag-over");
|
||||
});
|
||||
document.body.addEventListener("drop", (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
document.body.classList.remove("drag-over");
|
||||
newFromFile(e.dataTransfer.files[0]);
|
||||
});
|
||||
|
||||
let inputFile = document.createElement("input");
|
||||
inputFile.type = "file";
|
||||
inputFile.addEventListener("change", () => {
|
||||
newFromFile(inputFile.files[0]);
|
||||
});
|
||||
|
||||
let newFileUp = document.getElementById("new-up");
|
||||
newFileUp.addEventListener("click", () => { inputFile.click(); });
|
||||
function createFileEntry(fileObject, element){
|
||||
let info = fileObject.info;
|
||||
let file = document.createElement("div");
|
||||
file.className = "file";
|
||||
file.innerHTML = `
|
||||
<label class="check" title="Enable or disable file"><input type="checkbox" ${info.enabled?"checked='true'":""}><span></span></label>
|
||||
<span class="file-name">${info.name}</span>
|
||||
<span class="file-type" data-type="${info.type}">${info.type}</span>
|
||||
<div class="file-icons">
|
||||
<span class="file-icon file-edit" title="Edit file">
|
||||
<svg viewBox="0 0 48 48">
|
||||
<path d="M6 34.5v7.5h7.5l22.13-22.13-7.5-7.5-22.13 22.13zm35.41-20.41c.78-.78.78-2.05 0-2.83l-4.67-4.67c-.78-.78-2.05-.78-2.83 0l-3.66 3.66 7.5 7.5 3.66-3.66z"/>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="file-icon file-delete" title="Delete file">
|
||||
<svg viewBox="0 0 48 48">
|
||||
<path d="M12 38c0 2.21 1.79 4 4 4h16c2.21 0 4-1.79 4-4v-24h-24v24zm26-30h-7l-2-2h-10l-2 2h-7v4h28v-4z"/>
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
let fileName = file.querySelector(".file-name");
|
||||
let fileType = file.querySelector(".file-type");
|
||||
let fileEnable = file.querySelector("input");
|
||||
fileEnable.addEventListener("change", function(){
|
||||
info.enabled = this.checked;
|
||||
fileObject.save();
|
||||
});
|
||||
let fileEdit = file.querySelector(".file-icon.file-edit");
|
||||
fileEdit.addEventListener("click", edit);
|
||||
let fileDelete = file.querySelector(".file-icon.file-delete");
|
||||
fileDelete.addEventListener("click", function(){
|
||||
if(fileDelete.classList.contains("icon-confirm")){
|
||||
File.remove(info.id).then(function(){
|
||||
file.remove();
|
||||
});
|
||||
}else{
|
||||
fileDelete.classList.add("icon-confirm");
|
||||
setTimeout(function(){
|
||||
fileDelete.classList.remove("icon-confirm");
|
||||
}, 1000);
|
||||
}
|
||||
});
|
||||
file.addEventListener("click", e => {
|
||||
if(e.target.className=="file") edit();
|
||||
});
|
||||
element.appendChild(file);
|
||||
|
||||
fileObject.onChange = function(info){
|
||||
fileEnable.checked = info.enabled;
|
||||
fileName.textContent = info.name;
|
||||
}
|
||||
|
||||
function edit(){
|
||||
chrome.tabs.create({url: chrome.runtime.getURL("editor.html#"+info.id)});
|
||||
}
|
||||
}
|
||||
|
||||
let filesElement = document.getElementById("files");
|
||||
File.loadAll().then(function(files){
|
||||
files = files.sort((a, b) => {
|
||||
if(a.info.name < b.info.name) return -1;
|
||||
if(a.info.name > b.info.name) return 1;
|
||||
return 0;
|
||||
});
|
||||
for(let i=0;i<files.length;i++){
|
||||
createFileEntry(files[i], filesElement);
|
||||
}
|
||||
});
|
||||
|
||||
let newFileJS = document.getElementById("new-js");
|
||||
newFileJS.addEventListener("click", () => {
|
||||
let f = new File();
|
||||
f.changeInfo({type: "JS", name: "New Script"});
|
||||
f.save().then(() => {
|
||||
createFileEntry(f, filesElement);
|
||||
});
|
||||
});
|
||||
|
||||
let newFileCSS = document.getElementById("new-css");
|
||||
newFileCSS.addEventListener("click", () => {
|
||||
let f = new File();
|
||||
f.changeInfo({type: "CSS", name: "New Stylesheet"});
|
||||
f.save().then(() => {
|
||||
createFileEntry(f, filesElement);
|
||||
});
|
||||
});
|
||||
|
||||
/* file input */
|
||||
function newFromFile(inFile) {
|
||||
let info = {};
|
||||
|
||||
if(inFile.type == "text/javascript") {
|
||||
info.type = "JS";
|
||||
info.name = inFile.name.match(/(.*)\..*$/);
|
||||
} else if(inFile.type == "text/css") {
|
||||
info.type = "CSS";
|
||||
info.name = inFile.name.match(/(.*)\..*$/);
|
||||
} else if(inFile.type == "application/json") {
|
||||
} else {
|
||||
alert("Unsupported file type");
|
||||
return;
|
||||
}
|
||||
|
||||
let reader = new FileReader();
|
||||
reader.addEventListener("load", () => {
|
||||
if(inFile.type == "application/json") {
|
||||
try {
|
||||
info = JSON.parse(reader.result);
|
||||
} catch(e) { alert("The uploaded json file is not valid"); }
|
||||
} else {
|
||||
info.content = reader.result;
|
||||
}
|
||||
|
||||
let f = new File();
|
||||
f.changeInfo(info);
|
||||
f.save().then(() => {
|
||||
createFileEntry(f, filesElement);
|
||||
});
|
||||
});
|
||||
reader.readAsText(inFile);
|
||||
}
|
||||
|
||||
document.body.addEventListener("dragover", (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
document.body.classList.add("drag-over");
|
||||
});
|
||||
document.body.addEventListener("dragleave", (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
document.body.classList.remove("drag-over");
|
||||
});
|
||||
document.body.addEventListener("drop", (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
document.body.classList.remove("drag-over");
|
||||
newFromFile(e.dataTransfer.files[0]);
|
||||
});
|
||||
|
||||
let inputFile = document.createElement("input");
|
||||
inputFile.type = "file";
|
||||
inputFile.addEventListener("change", () => {
|
||||
newFromFile(inputFile.files[0]);
|
||||
});
|
||||
|
||||
let newFileUp = document.getElementById("new-up");
|
||||
newFileUp.addEventListener("click", () => { inputFile.click(); });
|
||||
|
|
|
|||
162
js/popup.js
162
js/popup.js
|
|
@ -1,81 +1,81 @@
|
|||
let addNew = document.getElementById("add-new");
|
||||
let section = document.getElementById("files");
|
||||
let manage = document.getElementById("manage");
|
||||
manage.addEventListener("click", e => {
|
||||
chrome.tabs.create({ url: chrome.runtime.getURL("index.html") });
|
||||
window.close();
|
||||
});
|
||||
chrome.tabs.query({active: true, currentWindow: true}, tabs => {
|
||||
let tabID = tabs[0].id;
|
||||
|
||||
// Query file list
|
||||
chrome.runtime.sendMessage({tabID, action: "get-files"}, files => {
|
||||
if(!files || !files.length) return;
|
||||
files.forEach(info => {
|
||||
let file = new File(info.id);
|
||||
file.changeInfo(info);
|
||||
info = file.info;
|
||||
|
||||
let span = document.createElement("span");
|
||||
span.className = "line btn";
|
||||
span.addEventListener("click", e => {
|
||||
if(e.target.classList.contains("btn")){
|
||||
chrome.tabs.create({ url: chrome.runtime.getURL("editor.html#"+info.id)});
|
||||
window.close();
|
||||
}
|
||||
});
|
||||
|
||||
let enable = document.createElement("label");
|
||||
enable.className = "check small";
|
||||
enable.innerHTML = `
|
||||
<input id="enable-input" type="checkbox">
|
||||
<span><span></span></span>
|
||||
`;
|
||||
let input = enable.children[0];
|
||||
input.checked = info.enabled;
|
||||
input.addEventListener("change", e => {
|
||||
file.info.enabled = input.checked;
|
||||
file.save();
|
||||
});
|
||||
span.appendChild(enable);
|
||||
|
||||
let name = document.createElement("span");
|
||||
name.className = "line-item";
|
||||
name.textContent = info.name;
|
||||
span.appendChild(name);
|
||||
|
||||
let type = document.createElement("span");
|
||||
type.className = "line-item";
|
||||
type.textContent = info.type;
|
||||
span.appendChild(type);
|
||||
|
||||
file.onChange = function(info){
|
||||
input.checked = info.enabled;
|
||||
name.textContent = info.name;
|
||||
}
|
||||
|
||||
section.appendChild(span);
|
||||
});
|
||||
});
|
||||
|
||||
// Query URL
|
||||
addNew.style.display = "none";
|
||||
chrome.runtime.sendMessage({tabID, action: "get-url"}, url => {
|
||||
if(!url) return;
|
||||
addNew.style.display = "";
|
||||
|
||||
let addJS = document.getElementById("add-js");
|
||||
let addCSS = document.getElementById("add-css");
|
||||
addJS.addEventListener("click", e =>{add("JS")});
|
||||
addCSS.addEventListener("click", e =>{add("CSS")});
|
||||
|
||||
function add(type){
|
||||
let f = new File();
|
||||
f.changeInfo({type, name: "New "+(type=="CSS"?"Stylesheet":"Script"), links:[url]});
|
||||
f.save().then(_ => {
|
||||
chrome.tabs.create({ url: chrome.runtime.getURL("editor.html#"+f.info.id)});
|
||||
window.close();
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
let addNew = document.getElementById("add-new");
|
||||
let section = document.getElementById("files");
|
||||
let manage = document.getElementById("manage");
|
||||
manage.addEventListener("click", e => {
|
||||
chrome.tabs.create({ url: chrome.runtime.getURL("index.html") });
|
||||
window.close();
|
||||
});
|
||||
chrome.tabs.query({active: true, currentWindow: true}, tabs => {
|
||||
let tabID = tabs[0].id;
|
||||
|
||||
// Query file list
|
||||
chrome.runtime.sendMessage({tabID, action: "get-files"}, files => {
|
||||
if(!files || !files.length) return;
|
||||
files.forEach(info => {
|
||||
let file = new File(info.id);
|
||||
file.changeInfo(info);
|
||||
info = file.info;
|
||||
|
||||
let span = document.createElement("span");
|
||||
span.className = "line btn";
|
||||
span.addEventListener("click", e => {
|
||||
if(e.target.classList.contains("btn")){
|
||||
chrome.tabs.create({ url: chrome.runtime.getURL("editor.html#"+info.id)});
|
||||
window.close();
|
||||
}
|
||||
});
|
||||
|
||||
let enable = document.createElement("label");
|
||||
enable.className = "check small";
|
||||
enable.innerHTML = `
|
||||
<input id="enable-input" type="checkbox">
|
||||
<span><span></span></span>
|
||||
`;
|
||||
let input = enable.children[0];
|
||||
input.checked = info.enabled;
|
||||
input.addEventListener("change", e => {
|
||||
file.info.enabled = input.checked;
|
||||
file.save();
|
||||
});
|
||||
span.appendChild(enable);
|
||||
|
||||
let name = document.createElement("span");
|
||||
name.className = "line-item";
|
||||
name.textContent = info.name;
|
||||
span.appendChild(name);
|
||||
|
||||
let type = document.createElement("span");
|
||||
type.className = "line-item";
|
||||
type.textContent = info.type;
|
||||
span.appendChild(type);
|
||||
|
||||
file.onChange = function(info){
|
||||
input.checked = info.enabled;
|
||||
name.textContent = info.name;
|
||||
}
|
||||
|
||||
section.appendChild(span);
|
||||
});
|
||||
});
|
||||
|
||||
// Query URL
|
||||
addNew.style.display = "none";
|
||||
chrome.runtime.sendMessage({tabID, action: "get-url"}, url => {
|
||||
if(!url) return;
|
||||
addNew.style.display = "";
|
||||
|
||||
let addJS = document.getElementById("add-js");
|
||||
let addCSS = document.getElementById("add-css");
|
||||
addJS.addEventListener("click", e =>{add("JS")});
|
||||
addCSS.addEventListener("click", e =>{add("CSS")});
|
||||
|
||||
function add(type){
|
||||
let f = new File();
|
||||
f.changeInfo({type, name: "New "+(type=="CSS"?"Stylesheet":"Script"), links:[url]});
|
||||
f.save().then(_ => {
|
||||
chrome.tabs.create({ url: chrome.runtime.getURL("editor.html#"+f.info.id)});
|
||||
window.close();
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,29 +1,29 @@
|
|||
let Storage = {};
|
||||
|
||||
Storage.save = browser.storage.local.set;
|
||||
Storage.load = browser.storage.local.get;
|
||||
Storage.remove = browser.storage.local.remove;
|
||||
|
||||
Storage.saveSync = browser.storage.sync.set;
|
||||
Storage.loadSync = browser.storage.sync.get;
|
||||
Storage.removeSync = browser.storage.sync.remove;
|
||||
|
||||
Storage.callbacks = {};
|
||||
Storage.onChange = function(key, fn){
|
||||
if(!Storage.callbacks[key]) Storage.callbacks[key] = [];
|
||||
Storage.callbacks[key].push(fn);
|
||||
}
|
||||
Storage.emit = function(key, newValue){
|
||||
if(!Storage.callbacks[key]) return;
|
||||
Storage.callbacks[key].forEach(x => {
|
||||
x(newValue);
|
||||
});
|
||||
}
|
||||
chrome.storage.onChanged.addListener(function(objects, area){
|
||||
if(area!="local") return;
|
||||
for(let id in objects){
|
||||
let newValue = objects[id].newValue;
|
||||
if(newValue) { Storage.emit(id, newValue); }
|
||||
}
|
||||
});
|
||||
|
||||
let Storage = {};
|
||||
|
||||
Storage.save = browser.storage.local.set;
|
||||
Storage.load = browser.storage.local.get;
|
||||
Storage.remove = browser.storage.local.remove;
|
||||
|
||||
Storage.saveSync = browser.storage.sync.set;
|
||||
Storage.loadSync = browser.storage.sync.get;
|
||||
Storage.removeSync = browser.storage.sync.remove;
|
||||
|
||||
Storage.callbacks = {};
|
||||
Storage.onChange = function(key, fn){
|
||||
if(!Storage.callbacks[key]) Storage.callbacks[key] = [];
|
||||
Storage.callbacks[key].push(fn);
|
||||
}
|
||||
Storage.emit = function(key, newValue){
|
||||
if(!Storage.callbacks[key]) return;
|
||||
Storage.callbacks[key].forEach(x => {
|
||||
x(newValue);
|
||||
});
|
||||
}
|
||||
chrome.storage.onChanged.addListener(function(objects, area){
|
||||
if(area!="local") return;
|
||||
for(let id in objects){
|
||||
let newValue = objects[id].newValue;
|
||||
if(newValue) { Storage.emit(id, newValue); }
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ WebDAV.propfind = async (path, opts) => {
|
|||
let res = await WebDAV.req(path, "PROPFIND", opts);
|
||||
let xmlText = await res.text();
|
||||
let parser = new DOMParser();
|
||||
let xmlDoc = parser.parseFromString(xmlText, "text/xml");
|
||||
let xmlDoc = parser.parseFromString(xmlText, "text/xml");
|
||||
|
||||
let responses = xmlDoc.getElementsByTagName("D:response");
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue