diff --git a/.gitignore b/.gitignore
index 41bb909..1e06d3a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
.msc
+web-ext-artifacts/
diff --git a/background.js b/background.js
index 31878cc..e872700 100644
--- a/background.js
+++ b/background.js
@@ -1,72 +1,73 @@
-let tabs = {};
-function createTab(id){
- return tabs[id] = {
- top: "",
- scriptsIndex: {},
- scripts: []
- };
-}
-
-chrome.browserAction.setBadgeBackgroundColor({color:"#303030"});
-chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
- let rTabID = request.tabID;
- let action = request.action;
- let value = request.value;
-
- if(sender.tab){ // Messages from tabs
- let tabID = sender.tab.id;
- if(!tabs[tabID]) createTab(tabID)
- let tab = tabs[tabID];
-
- switch(action){
- case "add-files": {
- value.forEach(info => {
- if(!tab.scriptsIndex[info.id]){
- tab.scriptsIndex[info.id] = info;
- tab.scripts.push(info);
- if(info.enabled) tab.badge++;
-
- let file = new File(info.id);
- file.onChange = function(newInfo){
- for(let index in newInfo){
- info[index] = newInfo[index];
- }
- }
- }
- });
-
- if(tab.scripts.length>0)
- chrome.browserAction.setBadgeText({
- tabId: tabID,
- text: String(tab.scripts.length)
- });
- break;
- }
- case "set-url": {
- tab = createTab(tabID);
- tab.top = value;
- break;
- }
- }
- } else { // Messages from anywhere else
- let tab;
- if(rTabID){
- tab = tabs[rTabID];
- if(!tab) return;
- }
-
- switch(action){
- case "get-files": {
- sendResponse(tab.scripts);
- break;
- }
- case "get-url": {
- sendResponse(tab.top);
- break;
- }
- }
- }
-});
-chrome.tabs.onRemoved.addListener((tabID, removeInfo) => {
- delete tabs[tabID];
-});
\ No newline at end of file
+let tabs = {};
+function createTab(id){
+ return tabs[id] = {
+ top: "",
+ scriptsIndex: {},
+ scripts: []
+ };
+}
+
+chrome.browserAction.setBadgeBackgroundColor({color:"#303030"});
+chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
+ let rTabID = request.tabID;
+ let action = request.action;
+ let value = request.value;
+
+ if(sender.tab){ // Messages from tabs
+ let tabID = sender.tab.id;
+ if(!tabs[tabID]) createTab(tabID)
+ let tab = tabs[tabID];
+
+ switch(action){
+ case "add-files": {
+ value.forEach(info => {
+ if(!tab.scriptsIndex[info.id]){
+ tab.scriptsIndex[info.id] = info;
+ tab.scripts.push(info);
+ if(info.enabled) tab.badge++;
+
+ let file = new File(info.id);
+ file.onChange = function(newInfo){
+ for(let index in newInfo){
+ info[index] = newInfo[index];
+ }
+ }
+ }
+ });
+
+ if(tab.scripts.length>0){
+ chrome.browserAction.setBadgeText({
+ tabId: tabID,
+ text: String(tab.scripts.length)
+ });
+ }
+ break;
+ }
+ case "set-url": {
+ tab = createTab(tabID);
+ tab.top = value;
+ break;
+ }
+ }
+ } else { // Messages from anywhere else
+ let tab;
+ if(rTabID){
+ tab = tabs[rTabID];
+ if(!tab) return;
+ }
+
+ switch(action){
+ case "get-files": {
+ sendResponse(tab.scripts);
+ break;
+ }
+ case "get-url": {
+ sendResponse(tab.top);
+ break;
+ }
+ }
+ }
+});
+chrome.tabs.onRemoved.addListener((tabID, removeInfo) => {
+ delete tabs[tabID];
+});
diff --git a/content.js b/content.js
index 883116c..0497d37 100644
--- a/content.js
+++ b/content.js
@@ -1,46 +1,46 @@
-let myHead = document.createElement("custom-web");
-document.documentElement.appendChild(myHead);
-
-chrome.runtime.sendMessage({
- action: "set-url",
- value: window.location.href
-});
-
-File.loadAll().then(files => {
- let activeFiles = [];
- for(let i = 0; i < files.length; i++){
- let info = files[i].info;
-
- if(info.links && info.links.length > 0) {
- let found = false;
- for(let l = 0; l < info.links.length && !found; l++) {
- let regexp = new RegExp(info.links[l]);
- found = window.location.href.match(regexp);
- }
- if(!found) continue;
- }
- activeFiles.push(info);
- if(!info.enabled) continue;
- if(info.type == "JS") {
- let jsContainer = document.createElement("script");
- jsContainer.textContent = info.content;
- myHead.appendChild(jsContainer);
- } else {
- let cssContainer = document.createElement("style");
- cssContainer.textContent = info.content;
- myHead.appendChild(cssContainer);
- }
- }
- let isTop = (window == window.top);
-
- if(isTop){ // Only allow top to set URL
- chrome.runtime.sendMessage({
- action: "set-url",
- value: window.location.href
- });
- }
- chrome.runtime.sendMessage({
- action: "add-files",
- value: activeFiles
- });
-});
+let myHead = document.createElement("custom-web");
+document.documentElement.appendChild(myHead);
+
+chrome.runtime.sendMessage({
+ action: "set-url",
+ value: window.location.href
+});
+
+File.loadAll().then(files => {
+ let activeFiles = [];
+ for(let i = 0; i < files.length; i++){
+ let info = files[i].info;
+
+ if(info.links && info.links.length > 0) {
+ let found = false;
+ for(let l = 0; l < info.links.length && !found; l++) {
+ let regexp = new RegExp(info.links[l]);
+ found = window.location.href.match(regexp);
+ }
+ if(!found) continue;
+ }
+ activeFiles.push(info);
+ if(!info.enabled) continue;
+ if(info.type == "JS") {
+ let jsContainer = document.createElement("script");
+ jsContainer.textContent = info.content;
+ myHead.appendChild(jsContainer);
+ } else {
+ let cssContainer = document.createElement("style");
+ cssContainer.textContent = info.content;
+ myHead.appendChild(cssContainer);
+ }
+ }
+ let isTop = (window == window.top);
+
+ if(isTop){ // Only allow top to set URL
+ chrome.runtime.sendMessage({
+ action: "set-url",
+ value: window.location.href
+ });
+ }
+ chrome.runtime.sendMessage({
+ action: "add-files",
+ value: activeFiles
+ });
+});
diff --git a/css/common.css b/css/common.css
index ce0f366..0c0a645 100644
--- a/css/common.css
+++ b/css/common.css
@@ -1,67 +1,67 @@
-*{box-sizing:border-box;}
-
-:root{
- --top: #212121;
- --background: #303030;
- --light: #424242;
- --lighter: #606060;
- --lightest: #848484;
-}
-html{
- height:100vh;
- font-family: "Segoe UI", Tahoma, sans-serif;
-}
-body{
- min-height:100%;
- margin: 0;
- background-color: var(--background);
-}
-
-.check{
- font-size:20px;
-
- display: inline-flex;
- width:2em;
- height:1em;
- margin-right: 10px;
-}
-.check input{
- display:none;
-}
-.check input + span{
- position:relative;
- display:inline-flex;
- width:100%;
- height:100%;
- background: #000;
- border-radius:1000px;
- cursor:pointer;
- transition: background 100ms ease-in-out;
-}
-.check input:checked + span{
- background:#0a3;
-}
-.check input + span::before{
- content:"";
- display:inline-block;
- width:1em; height:1em;
- margin-left:1px;
- border:0.15em solid transparent;
- background-clip: padding-box;
- box-sizing:border-box;
- border-radius:100%;
- background-color:white;
- transition: all 100ms ease-in-out;
-}
-.check input:checked + span::before{
- transform: translateX(100%);
- margin-left:-1px;
-}
-.check.no-transition input + span,
-.check.no-transition input + span::before{
- transition:none;
-}
-/* Small Check */
-.check.small{
- font-size:17px;
-}
\ No newline at end of file
+*{box-sizing:border-box;}
+
+:root{
+ --top: #212121;
+ --background: #303030;
+ --light: #424242;
+ --lighter: #606060;
+ --lightest: #848484;
+}
+html{
+ height:100vh;
+ font-family: "Segoe UI", Tahoma, sans-serif;
+}
+body{
+ min-height:100%;
+ margin: 0;
+ background-color: var(--background);
+}
+
+.check{
+ font-size:20px;
+
+ display: inline-flex;
+ width:2em;
+ height:1em;
+ margin-right: 10px;
+}
+.check input{
+ display:none;
+}
+.check input + span{
+ position:relative;
+ display:inline-flex;
+ width:100%;
+ height:100%;
+ background: #000;
+ border-radius:1000px;
+ cursor:pointer;
+ transition: background 100ms ease-in-out;
+}
+.check input:checked + span{
+ background:#0a3;
+}
+.check input + span::before{
+ content:"";
+ display:inline-block;
+ width:1em; height:1em;
+ margin-left:1px;
+ border:0.15em solid transparent;
+ background-clip: padding-box;
+ box-sizing:border-box;
+ border-radius:100%;
+ background-color:white;
+ transition: all 100ms ease-in-out;
+}
+.check input:checked + span::before{
+ transform: translateX(100%);
+ margin-left:-1px;
+}
+.check.no-transition input + span,
+.check.no-transition input + span::before{
+ transition:none;
+}
+/* Small Check */
+.check.small{
+ font-size:17px;
+}
diff --git a/css/editor.css b/css/editor.css
index bcfcd1a..0df9d88 100644
--- a/css/editor.css
+++ b/css/editor.css
@@ -1,233 +1,233 @@
-/* reset */
-input {
- padding: 0;
- background-color: transparent;
- outline: none;
- border: none;
-}
-#editor {
- margin: 0;
-}
-* { box-sizing: border-box; }
-
-/* custom styles */
-body {
- display: flex;
- flex-direction: column;
-}
-
-/* header */
-header {
- display: flex;
- align-items: center;
- justify-content: flex-end;
-
- height: 50px;
- flex-shrink: 0;
- padding: 0 20px;
- box-sizing: border-box;
-
- background-color: var(--top);
-}
-
-header .check {
- margin-right: 10px;
-}
-
-header input {
- width: 50%;
- height: 40px;
- padding: 0 15px;
- margin-right: auto;
- border-radius: 40px;
- background-color: var(--top);
-
- font-family: "Segoe UI", Tahoma, sans-serif;
- font-size: 30px;
- color: white;
- cursor:pointer;
- margin-right: auto;
-
- transition: padding 100ms ease-in-out;
-}
-header input:hover,
-header input:focus {
- background-color: var(--light);
-}
-header input:focus{
- cursor:auto;
-}
-
-header > span {
- width: 40px;
- height: 40px;
- padding: 5px;
- margin-left: 5px;
- border-radius: 40px;
- cursor: pointer;
-}
-header > span#download-btn {
- padding: 7px;
-}
-header > span:last-child {
- margin-right: -5px;
-}
-header > span:hover {
- background-color: var(--light);
-}
-
-header > span svg {
- width: 100%;
- height: 100%;
- fill: white;
-}
-
-#save-btn {
- pointer-events: none;
-}
-#save-btn.edited {
- pointer-events: all;
-}
-
-#save-btn svg {
- opacity: 0.25;
- transition: opacity 100ms ease-in-out;
-}
-#save-btn.edited svg {
- opacity: 1;
-}
-
-/* editor */
-main {
- flex-grow: 1;
- display: flex;
- flex-direction: column;
-}
-
-#editor {
- flex-grow: 1;
-}
-
-/* links popup */
-#links-popup {
- display: none; /* flex */
- flex-direction: column;
-
- width: 100%;
- max-width: 600px;
- height: 500px;
- border-radius: 20px;
- overflow: hidden;
-
- position: absolute;
- margin: auto;
- top: 0; bottom: 0;
- right: 0; left: 0;
- z-index: 10;
-
- background-color: var(--light);
- box-shadow: 0 0 25px rgba(0, 0, 0, 0.5);
-}
-#links-popup header {
- background: none;
- background-color: var(--background);
-}
-#links-popup header h1 {
- margin-right: auto;
-
- font-family: "Segoe UI", Tahoma, sans-serif;
- font-weight: normal;
- font-size: 24px;
- color: white;
-}
-
-#links-popup header > span {
- width: 35px;
- height: 35px;
-}
-
-#links-popup main {
- align-items: center;
-}
-
-#links-popup main #links-wrapper {
- width: 100%;
- height: 100%;
- padding: 20px;
- overflow: auto;
-}
-
-#links-popup main #links-wrapper .link-entry {
- position: relative;
- width: 100%;
- flex-shrink: 0;
- margin-bottom: 6px;
- border-radius: 40px;
- overflow: hidden;
-}
-
-#links-popup main #links-wrapper .link-entry input {
- display: block;
- height: 40px;
- width: 100%;
- border-radius: 40px;
- padding: 10px 15px;
- padding-right: 40px;
-
- font-family: "Segoe UI", Tahoma, sans-serif;
- font-weight: normal;
- font-size: 16px;
- color: rgb(235, 227, 227);
- opacity: 1;
-
- cursor: pointer;
-}
-#links-popup main #links-wrapper .link-entry:hover,
-#links-popup main #links-wrapper .link-entry input:focus {
- background-color: var(--lighter);
- opacity: 1;
-}
-#links-popup main #links-wrapper .link-entry input:focus {
- cursor:auto;
-}
-
-#links-popup main #links-wrapper .link-entry svg {
- position: absolute;
- top: 0; right: 0px;
-
- height: 40px;
- width: 40px;
- padding: 10px;
- border-radius: 100%;
- flex-shrink: 0;
-
- fill: white;
- opacity: 0;
- cursor: pointer
-}
-#links-popup main #links-wrapper .link-entry:hover svg,
-#links-popup main #links-wrapper .link-entry input:focus + svg {
- opacity: 0.5;
-}
-#links-popup main #links-wrapper .link-entry svg:hover {
- opacity: 1;
-}
-
-
-/* better monokai */
-
-#editor.ace-monokai {
- background-color: var(--background);
-}
-
-#editor.ace-monokai .ace_gutter {
- background-color: var(--light);
-}
-
-#editor.ace-monokai .ace_selection {
- background-color: var(--lighter);
-}
-
-#editor.ace-monokai .ace_marker-layer .ace_active-line {
- background-color: rgba(0, 0, 0, 0.2);
-}
+/* reset */
+input {
+ padding: 0;
+ background-color: transparent;
+ outline: none;
+ border: none;
+}
+#editor {
+ margin: 0;
+}
+* { box-sizing: border-box; }
+
+/* custom styles */
+body {
+ display: flex;
+ flex-direction: column;
+}
+
+/* header */
+header {
+ display: flex;
+ align-items: center;
+ justify-content: flex-end;
+
+ height: 50px;
+ flex-shrink: 0;
+ padding: 0 20px;
+ box-sizing: border-box;
+
+ background-color: var(--top);
+}
+
+header .check {
+ margin-right: 10px;
+}
+
+header input {
+ width: 50%;
+ height: 40px;
+ padding: 0 15px;
+ margin-right: auto;
+ border-radius: 40px;
+ background-color: var(--top);
+
+ font-family: "Segoe UI", Tahoma, sans-serif;
+ font-size: 30px;
+ color: white;
+ cursor:pointer;
+ margin-right: auto;
+
+ transition: padding 100ms ease-in-out;
+}
+header input:hover,
+header input:focus {
+ background-color: var(--light);
+}
+header input:focus{
+ cursor:auto;
+}
+
+header > span {
+ width: 40px;
+ height: 40px;
+ padding: 5px;
+ margin-left: 5px;
+ border-radius: 40px;
+ cursor: pointer;
+}
+header > span#download-btn {
+ padding: 7px;
+}
+header > span:last-child {
+ margin-right: -5px;
+}
+header > span:hover {
+ background-color: var(--light);
+}
+
+header > span svg {
+ width: 100%;
+ height: 100%;
+ fill: white;
+}
+
+#save-btn {
+ pointer-events: none;
+}
+#save-btn.edited {
+ pointer-events: all;
+}
+
+#save-btn svg {
+ opacity: 0.25;
+ transition: opacity 100ms ease-in-out;
+}
+#save-btn.edited svg {
+ opacity: 1;
+}
+
+/* editor */
+main {
+ flex-grow: 1;
+ display: flex;
+ flex-direction: column;
+}
+
+#editor {
+ flex-grow: 1;
+}
+
+/* links popup */
+#links-popup {
+ display: none; /* flex */
+ flex-direction: column;
+
+ width: 100%;
+ max-width: 600px;
+ height: 500px;
+ border-radius: 20px;
+ overflow: hidden;
+
+ position: absolute;
+ margin: auto;
+ top: 0; bottom: 0;
+ right: 0; left: 0;
+ z-index: 10;
+
+ background-color: var(--light);
+ box-shadow: 0 0 25px rgba(0, 0, 0, 0.5);
+}
+#links-popup header {
+ background: none;
+ background-color: var(--background);
+}
+#links-popup header h1 {
+ margin-right: auto;
+
+ font-family: "Segoe UI", Tahoma, sans-serif;
+ font-weight: normal;
+ font-size: 24px;
+ color: white;
+}
+
+#links-popup header > span {
+ width: 35px;
+ height: 35px;
+}
+
+#links-popup main {
+ align-items: center;
+}
+
+#links-popup main #links-wrapper {
+ width: 100%;
+ height: 100%;
+ padding: 20px;
+ overflow: auto;
+}
+
+#links-popup main #links-wrapper .link-entry {
+ position: relative;
+ width: 100%;
+ flex-shrink: 0;
+ margin-bottom: 6px;
+ border-radius: 40px;
+ overflow: hidden;
+}
+
+#links-popup main #links-wrapper .link-entry input {
+ display: block;
+ height: 40px;
+ width: 100%;
+ border-radius: 40px;
+ padding: 10px 15px;
+ padding-right: 40px;
+
+ font-family: "Segoe UI", Tahoma, sans-serif;
+ font-weight: normal;
+ font-size: 16px;
+ color: rgb(235, 227, 227);
+ opacity: 1;
+
+ cursor: pointer;
+}
+#links-popup main #links-wrapper .link-entry:hover,
+#links-popup main #links-wrapper .link-entry input:focus {
+ background-color: var(--lighter);
+ opacity: 1;
+}
+#links-popup main #links-wrapper .link-entry input:focus {
+ cursor:auto;
+}
+
+#links-popup main #links-wrapper .link-entry svg {
+ position: absolute;
+ top: 0; right: 0px;
+
+ height: 40px;
+ width: 40px;
+ padding: 10px;
+ border-radius: 100%;
+ flex-shrink: 0;
+
+ fill: white;
+ opacity: 0;
+ cursor: pointer
+}
+#links-popup main #links-wrapper .link-entry:hover svg,
+#links-popup main #links-wrapper .link-entry input:focus + svg {
+ opacity: 0.5;
+}
+#links-popup main #links-wrapper .link-entry svg:hover {
+ opacity: 1;
+}
+
+
+/* better monokai */
+
+#editor.ace-monokai {
+ background-color: var(--background);
+}
+
+#editor.ace-monokai .ace_gutter {
+ background-color: var(--light);
+}
+
+#editor.ace-monokai .ace_selection {
+ background-color: var(--lighter);
+}
+
+#editor.ace-monokai .ace_marker-layer .ace_active-line {
+ background-color: rgba(0, 0, 0, 0.2);
+}
diff --git a/css/index.css b/css/index.css
index 89fbc83..bfce17b 100644
--- a/css/index.css
+++ b/css/index.css
@@ -1,152 +1,152 @@
-svg{
- max-width:100%;
- max-height:100%;
-}
-
-body.drag-over{
- background-color: var(--light);
-}
-
-header{
- width:100%;
- height:50px;
- display: flex;
- align-items:center;
- padding:0px 20px;
- background-color: var(--top);
- color:white;
- fill:white;
- font-size:30px;
-}
-header img{
- width:36px;
- margin-right:10px;
-}
-header img + span{
- margin-right:auto;
-}
-
-header #new-file {
- display: flex;
- justify-content: flex-end;
- width: 40px;
- height: 40px;
- border-radius: 40px;
- overflow: hidden;
- align-items: center;
-
- transition: width 100ms ease-in-out;
-}
-header #new-file:hover {
- width: 175px;
- background-color: var(--light);
-}
-
-header #new-file span.btn {
- display:flex;
- align-items:center;
- justify-content:center;
- flex-grow: 1;
- flex-shrink: 1;
- min-width: 30px;
- height: 100%;
- opacity:0.5;
-
- text-align: center;
- font-size: 14px;
- cursor: pointer;
- user-select: none;
-}
-header #new-file span.btn:hover {
- opacity:1;
- text-shadow: 0 0 0 rgba(255, 255, 255, 0.5);
-}
-
-header #new-file .btn-svg {
- flex-shrink: 0;
- width: 40px;
- height: 40px;
- padding: 5px;
-}
-
-header #new-file .btn-svg svg {
- display: block;
- width: 100%;
- height: 100%;
- fill: white;
-}
-
-#files{
- padding:10px 20px;
-}
-.file{
- position:relative;
- color:white;
- height:45px;
- padding:10px 15px;
- display:grid;
- grid-template-columns: 60px auto 50px 125px;
- align-items:center;
- font-size:16px;
- border-radius:45px;
- cursor:pointer;
-}
-.file:hover{
- background: var(--lighter);
-}
-.file .file-type{
- justify-self: center;
-}
-.file .file-name,
-.file .file-type{
- pointer-events:none;
-}
-.file .file-icons{
- display:flex;
- pointer-events:none;
-}
-.file .file-icons .file-icon{
- display:flex;
- align-items:center;
- border-radius:20px;
- padding:2px 0px;
- transition: all 100ms ease-in-out;
- cursor:pointer;
- pointer-events:all;
-}
-.file .file-icons .file-icon svg{
- width: 20px;
- height: 20px;
- fill: white;
- opacity:0.7;
-}
-.file .file-icons .file-icon.icon-confirm svg,
-.file .file-icons .file-icon svg:hover{
- opacity:1;
-}
-.file .file-icons .file-icon.icon-confirm{
- background:#C00;
- padding:2px 5px;
-}
-.file .file-icons .file-icon::before{
- content:"DELETE";
- font-size: 12px;
- width: 0px;
- overflow:hidden;
- text-align:center;
- transition: width 100ms ease-in-out;
-}
-.file .file-icons .file-icon.icon-confirm::before{
- width:50px;
-}
-.file .file-icons .file-edit{
- margin-left:auto;
- margin-right:5px;
-}
-.file-type[data-type="JS"]{
- color: #ffde24
-}
-.file-type[data-type="CSS"]{
- color: #15a0dc
-}
-
+svg{
+ max-width:100%;
+ max-height:100%;
+}
+
+body.drag-over{
+ background-color: var(--light);
+}
+
+header{
+ width:100%;
+ height:50px;
+ display: flex;
+ align-items:center;
+ padding:0px 20px;
+ background-color: var(--top);
+ color:white;
+ fill:white;
+ font-size:30px;
+}
+header img{
+ width:36px;
+ margin-right:10px;
+}
+header img + span{
+ margin-right:auto;
+}
+
+header #new-file {
+ display: flex;
+ justify-content: flex-end;
+ width: 40px;
+ height: 40px;
+ border-radius: 40px;
+ overflow: hidden;
+ align-items: center;
+
+ transition: width 100ms ease-in-out;
+}
+header #new-file:hover {
+ width: 175px;
+ background-color: var(--light);
+}
+
+header #new-file span.btn {
+ display:flex;
+ align-items:center;
+ justify-content:center;
+ flex-grow: 1;
+ flex-shrink: 1;
+ min-width: 30px;
+ height: 100%;
+ opacity:0.5;
+
+ text-align: center;
+ font-size: 14px;
+ cursor: pointer;
+ user-select: none;
+}
+header #new-file span.btn:hover {
+ opacity:1;
+ text-shadow: 0 0 0 rgba(255, 255, 255, 0.5);
+}
+
+header #new-file .btn-svg {
+ flex-shrink: 0;
+ width: 40px;
+ height: 40px;
+ padding: 5px;
+}
+
+header #new-file .btn-svg svg {
+ display: block;
+ width: 100%;
+ height: 100%;
+ fill: white;
+}
+
+#files{
+ padding:10px 20px;
+}
+.file{
+ position:relative;
+ color:white;
+ height:45px;
+ padding:10px 15px;
+ display:grid;
+ grid-template-columns: 60px auto 50px 125px;
+ align-items:center;
+ font-size:16px;
+ border-radius:45px;
+ cursor:pointer;
+}
+.file:hover{
+ background: var(--lighter);
+}
+.file .file-type{
+ justify-self: center;
+}
+.file .file-name,
+.file .file-type{
+ pointer-events:none;
+}
+.file .file-icons{
+ display:flex;
+ pointer-events:none;
+}
+.file .file-icons .file-icon{
+ display:flex;
+ align-items:center;
+ border-radius:20px;
+ padding:2px 0px;
+ transition: all 100ms ease-in-out;
+ cursor:pointer;
+ pointer-events:all;
+}
+.file .file-icons .file-icon svg{
+ width: 20px;
+ height: 20px;
+ fill: white;
+ opacity:0.7;
+}
+.file .file-icons .file-icon.icon-confirm svg,
+.file .file-icons .file-icon svg:hover{
+ opacity:1;
+}
+.file .file-icons .file-icon.icon-confirm{
+ background:#C00;
+ padding:2px 5px;
+}
+.file .file-icons .file-icon::before{
+ content:"DELETE";
+ font-size: 12px;
+ width: 0px;
+ overflow:hidden;
+ text-align:center;
+ transition: width 100ms ease-in-out;
+}
+.file .file-icons .file-icon.icon-confirm::before{
+ width:50px;
+}
+.file .file-icons .file-edit{
+ margin-left:auto;
+ margin-right:5px;
+}
+.file-type[data-type="JS"]{
+ color: #ffde24
+}
+.file-type[data-type="CSS"]{
+ color: #15a0dc
+}
+
diff --git a/css/popup.css b/css/popup.css
index 4a3f099..ca4e83a 100644
--- a/css/popup.css
+++ b/css/popup.css
@@ -1,89 +1,89 @@
-html{
- height:auto;
-}
-body{
- width:200px;
- color:white;
- padding:3px 0px;
- font-size:12px;
-}
-img{
- height:22px;
- width:22px;
- justify-self:center;
-}
-.title{
- font-size:16px;
-}
-.line{
- display:grid;
- align-items:center;
- grid-template-columns: 34px auto 25px;
- column-gap: 10px;
- height:30px;
- padding:0px 10px;
-}
-.line .check{
- flex-shrink:0;
-}
-.line > .line-item{
- white-space: nowrap;
- max-width: 100%;
- overflow: hidden;
- text-overflow: ellipsis;
- pointer-events:none;
-}
-.line > .line-item + .line-item{
- opacity:0.5;
- justify-self: center;
-}
-
-.btn{
- cursor:pointer;
-}
-.btn:hover{
- opacity:1;
- background: var(--lighter);
-}
-
-#files:empty{
- display:none;
-}
-
-section:not(:first-child){
- margin-top:3px;
- padding-top:3px;
- border-top:1px solid var(--light);
-}
-section h2{
- margin: 0;
- font-size: 10px;
- font-weight:400;
- padding:0px 10px;
- color: var(--lighter)
-}
-section h2 span{
- max-width: 100%;
- display: inline-block;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- pointer-events:none;
-}
-
-#add-new .line {
- grid-template-columns: 50% 50%;
- align-items: stretch;
- column-gap:0;
- height:20px;
-}
-#add-new .line .btn{
- display:flex;
- align-items:center;
- justify-content:center;
- opacity:0.7;
-}
-#add-new .line .btn:hover{
- opacity:1;
- background:none;
-}
\ No newline at end of file
+html{
+ height:auto;
+}
+body{
+ width:200px;
+ color:white;
+ padding:3px 0px;
+ font-size:12px;
+}
+img{
+ height:22px;
+ width:22px;
+ justify-self:center;
+}
+.title{
+ font-size:16px;
+}
+.line{
+ display:grid;
+ align-items:center;
+ grid-template-columns: 34px auto 25px;
+ column-gap: 10px;
+ height:30px;
+ padding:0px 10px;
+}
+.line .check{
+ flex-shrink:0;
+}
+.line > .line-item{
+ white-space: nowrap;
+ max-width: 100%;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ pointer-events:none;
+}
+.line > .line-item + .line-item{
+ opacity:0.5;
+ justify-self: center;
+}
+
+.btn{
+ cursor:pointer;
+}
+.btn:hover{
+ opacity:1;
+ background: var(--lighter);
+}
+
+#files:empty{
+ display:none;
+}
+
+section:not(:first-child){
+ margin-top:3px;
+ padding-top:3px;
+ border-top:1px solid var(--light);
+}
+section h2{
+ margin: 0;
+ font-size: 10px;
+ font-weight:400;
+ padding:0px 10px;
+ color: var(--lighter)
+}
+section h2 span{
+ max-width: 100%;
+ display: inline-block;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ pointer-events:none;
+}
+
+#add-new .line {
+ grid-template-columns: 50% 50%;
+ align-items: stretch;
+ column-gap:0;
+ height:20px;
+}
+#add-new .line .btn{
+ display:flex;
+ align-items:center;
+ justify-content:center;
+ opacity:0.7;
+}
+#add-new .line .btn:hover{
+ opacity:1;
+ background:none;
+}
diff --git a/editor.html b/editor.html
index ea84545..1a12619 100644
--- a/editor.html
+++ b/editor.html
@@ -1,56 +1,56 @@
-
-
-
-
- Script Editor
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Script Editor
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/index.html b/index.html
index e16392e..b160446 100644
--- a/index.html
+++ b/index.html
@@ -1,41 +1,41 @@
-
-
-
-
- Custom Web
-
-
-
-
-
-
-
-
- Custom Web
-
-
-
-
-
-
-
-
-
-
- CSS
- JS
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Custom Web
+
+
+
+
+
+
+
+
+ Custom Web
+
+
+
+
+
+
+
+
+
+
+ CSS
+ JS
+
+
+
+
+
+
+
+
+
+
+
diff --git a/js/editor.js b/js/editor.js
index 7705fea..43af2cd 100644
--- a/js/editor.js
+++ b/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 = `
-
-
- `;
-
- 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 = `
+
+
+ `;
+
+ 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);
diff --git a/js/file.js b/js/file.js
index 52316eb..89f6880 100644
--- a/js/file.js
+++ b/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);
+ })
+ });
+ });
+};
diff --git a/js/index.js b/js/index.js
index 51fabe6..ddb827f 100644
--- a/js/index.js
+++ b/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 = `
-
- ${info.name}
- ${info.type}
-
- `;
-
- 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 {
- 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 = `
+
+ ${info.name}
+ ${info.type}
+
+ `;
+
+ 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 {
+ 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(); });
diff --git a/js/popup.js b/js/popup.js
index 3a7b113..dc9e1c0 100644
--- a/js/popup.js
+++ b/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 = `
-
-
- `;
- 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();
- });
- }
- });
-});
\ No newline at end of file
+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 = `
+
+
+ `;
+ 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();
+ });
+ }
+ });
+});
diff --git a/js/storage.js b/js/storage.js
index dd1dba5..77b57d0 100644
--- a/js/storage.js
+++ b/js/storage.js
@@ -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); }
+ }
+});
+
diff --git a/js/webdav.js b/js/webdav.js
index b1f357c..c643d68 100644
--- a/js/webdav.js
+++ b/js/webdav.js
@@ -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");
diff --git a/popup.html b/popup.html
index a3364b6..10ffc46 100644
--- a/popup.html
+++ b/popup.html
@@ -1,24 +1,24 @@
-
-
-
-
-
-
- Custom Web Popup
-
-
-
-
Manage Files
-
-
-
- Add Script
- Add Style
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+ Custom Web Popup
+
+
+
+
Manage Files
+
+
+
+ Add Script
+ Add Style
+
+
+
+
+
+
+
+
diff --git a/settings.html b/settings.html
index 5c75f1c..28f8c67 100644
--- a/settings.html
+++ b/settings.html
@@ -1,6 +1,6 @@
-
+
Custom Web - Settings