├── .gitignore
├── README.md
├── background.js
├── favicon.png
├── icon.png
├── icon@2x.png
├── icon@3x.png
├── index.html
├── manifest.json
├── package-lock.json
├── package.json
├── postcss.config.js
├── static
├── css
│ ├── style.css
│ └── tailwind.css
├── img
│ └── default-yellow.webp
└── js
│ ├── alpine.min.js
│ ├── bookmarks.js
│ ├── jquery-3.5.0.min.js
│ ├── mark.min.js
│ ├── modal.js
│ ├── semantic.min.js
│ ├── settings.js
│ ├── sortable.min.js
│ └── tasks.js
└── tailwind.config.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # mission-control
2 | Mission Control - New Tab Chrome Extension
3 |
4 | Visit Website: https://mission-control.app/
5 |
6 | Install on Chrome: https://chrome.google.com/webstore/detail/mission-control-bookmarks/moefgmdpmpkpfiflljmcjgjlmjnjaall?hl=en-US
7 |
--------------------------------------------------------------------------------
/background.js:
--------------------------------------------------------------------------------
1 | // background.js
2 | (function () {
3 | "use strict";
4 |
5 | chrome.runtime.onInstalled.addListener(function () {
6 | chrome.contextMenus.create({
7 | id: "AddpagetoBookmarks",
8 | title: "Add this Page to Mission Control",
9 | contexts: ["page"],
10 | });
11 | chrome.contextMenus.create({
12 | id: "AddLinktoBookmarks",
13 | title: "Add this link to Mission Control",
14 | contexts: ["link"],
15 | });
16 | chrome.contextMenus.create({
17 | id: "AddtoTasks",
18 | title: "Add as Task in Mission Control",
19 | contexts: ["selection"],
20 | });
21 | });
22 |
23 | chrome.action.onClicked.addListener(handleBrowserActionClicked);
24 |
25 | function handleBrowserActionClicked(tab) {
26 | const opts = {
27 | url: chrome.runtime.getURL("index.html"),
28 | };
29 | chrome.tabs.create(opts, handleCallback);
30 | }
31 |
32 | // Open on New Tab
33 | // So give users a chance to use other New Tab
34 |
35 | // chrome.tabs.onCreated.addListener(function (tab) {
36 | // // Only redirect if this is a blank new tab (not opened by clicking a link).
37 |
38 | // setTimeout(() => {
39 | // console.log(tab);
40 | // if ((tab.pendingUrl || tab.url) === "chrome://newtab/") {
41 | // // Show your website. This might highlight the omnibox,
42 | // console.log("this");
43 | // // but it's not guaranteed.
44 | // chrome.tabs.update(
45 | // tab.id,
46 | // {
47 | // url: chrome.runtime.getURL("index.html"),
48 | // },
49 | // handleCallback
50 | // );
51 | // console.log("here");
52 | // }
53 | // }, 100);
54 | // });
55 |
56 | // function handleCallback(window) {
57 | // console.log("done");
58 | // }
59 |
60 | chrome.alarms.create({ delayInMinutes: 0.1 });
61 | console.log("alarn");
62 |
63 | chrome.alarms.onAlarm.addListener(() => {
64 | console.log("alarm run");
65 | if (chrome.notifications) {
66 | console.log("yup run");
67 | //show();
68 | }
69 | });
70 |
71 | // function show() {
72 | // var opt = {
73 | // iconUrl:
74 | // "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA" +
75 | // "AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO" +
76 | // "9TXL0Y4OHwAAAABJRU5ErkJggg==",
77 | // type: "basic",
78 | // title: "Primary Title",
79 | // message: "Primary message to display",
80 | // priority: 1,
81 | // };
82 | // chrome.notifications.create(
83 | // "1",
84 | // {
85 | // iconUrl:
86 | // "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA" +
87 | // "AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO" +
88 | // "9TXL0Y4OHwAAAABJRU5ErkJggg==",
89 | // title: "This should be a notification",
90 | // type: "basic",
91 | // message: "Notification body",
92 | // isClickable: true,
93 | // priority: 2,
94 | // },
95 | // function (id) {
96 | // console.log("Last error:", chrome.runtime.lastError);
97 | // }
98 | // );
99 | // }
100 |
101 | // items: [
102 | // { title: "Item1", message: "This is item 1." },
103 | // { title: "Item2", message: "This is item 2." },
104 | // { title: "Item3", message: "This is item 3." },
105 | // ],
106 |
107 | // chrome.contextMenus.create({
108 | // title: "Add this Website to Mission Control",
109 | // id: "mc-add",
110 | // contexts: ["all"],
111 | // });
112 |
113 | // chrome.contextMenus.onClicked.addListener(async (info, tab) => {
114 | // console.log(info);
115 | // console.log(tab);
116 | // const { menuItemId } = info;
117 | // if (menuItemId === "mc-add") {
118 | // console.log("yup");
119 | // await addToAWMT(info);
120 | // }
121 | // });
122 |
123 | // chrome.browserAction.onClicked.addListener(async (tab) => {
124 | // const { url } = tab;
125 | // addToAWMT({ webpage: url });
126 | // });
127 |
128 | // async function addToAWMT(info) {
129 | // const { srcUrl, selectionText, webpage } = info;
130 | // console.log("goko");
131 | // chrome.tabs.getSelected(null, (tab) => {
132 | // const source = tab.url;
133 |
134 | // if (srcUrl) {
135 | // console.log({ type: "Image", url: srcUrl, source });
136 | // }
137 |
138 | // if (selectionText) {
139 | // console.log({ content: selectionText, source });
140 | // }
141 |
142 | // if (webpage) {
143 | // console.log({ type: "WebPage", url: webpage, source });
144 | // }
145 | // });
146 | // }
147 |
148 | // // var xhr = new XMLHttpRequest();
149 | // // xhr.open("GET", "https://yahoo.com/", true);
150 | // // xhr.onreadystatechange = function () {
151 | // // if (xhr.readyState == 4) {
152 | // // // JSON.parse does not evaluate the attacker's scripts.
153 | // // var title = /
(.*?)<\/title>/m.exec(xhr.responseText)[1];
154 | // // console.log(title);
155 | // // }
156 | // // };
157 | // // xhr.send();
158 |
159 | // // chrome.runtime.onMessage.addListener(
160 | // // function(request, sender, sendResponse) {
161 | // // if (request.contentScriptQuery == "queryPrice") {
162 | // // var url = "https://another-site.com/price-query?itemId=" +
163 | // // encodeURIComponent(request.itemId);
164 | // // fetch(url)
165 | // // .then(response => response.text())
166 | // // .then(text => parsePrice(text))
167 | // // .then(price => sendResponse(price))
168 | // // .catch(error => ...)
169 | // // return true; // Will respond asynchronously.
170 | // // }
171 | // // });
172 | })();
173 |
--------------------------------------------------------------------------------
/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/surjithctly/mission-control/ed84904a7788ac4b7fc1daca244d941d9adc02c2/favicon.png
--------------------------------------------------------------------------------
/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/surjithctly/mission-control/ed84904a7788ac4b7fc1daca244d941d9adc02c2/icon.png
--------------------------------------------------------------------------------
/icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/surjithctly/mission-control/ed84904a7788ac4b7fc1daca244d941d9adc02c2/icon@2x.png
--------------------------------------------------------------------------------
/icon@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/surjithctly/mission-control/ed84904a7788ac4b7fc1daca244d941d9adc02c2/icon@3x.png
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | New Tab by Mission Control
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
19 |
20 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
53 |
55 |
56 |
57 |
58 |
59 |
62 |
63 |
66 |
67 |
68 |
69 |
70 |
72 |
75 |
76 |
77 |
79 |
81 |
82 |
83 |
84 | Starred
85 |
86 |
89 |
90 |
93 |
95 |
96 |
97 | Show All
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
108 |
109 |
110 |
111 |
144 |
145 |
147 |
148 |
149 |
151 |
152 |
153 |
Add New
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
364 |
365 |
366 |
367 |
368 |
369 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
430 |
431 |
432 |
433 |
434 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
470 |
471 |
472 |
473 |
474 |
476 |
477 |
478 |
479 |
480 |
482 |
484 |
486 |
487 |
488 |
(Esc)
489 |
490 |
491 |
492 |
493 |
494 |
495 |
Add New
496 |
497 |
499 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
593 |
594 |
595 |
596 |
698 |
699 |
700 |
701 |
702 |
708 |
709 |
710 |
711 |
712 |
713 |
715 |
716 |
717 |
738 |
739 |
740 |
741 |
742 |
743 |
744 |
745 |
746 |
747 |
748 |
749 |
750 |
--------------------------------------------------------------------------------
/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Mission Control - Bookmarks & Tasks",
3 | "author": "Surjith S M",
4 | "version": "1.0.0",
5 | "description": "Turn your New Tab into a Mission Control. Focus on your important tasks and organize your bookmarks.",
6 | "permissions": ["storage", "topSites", "notifications", "alarms", "contextMenus", "unlimitedStorage", "clipboardRead"],
7 | "manifest_version": 3,
8 | "short_name": "Mission Control",
9 | "host_permissions": [
10 | "",
11 | "*://*/*"
12 | ],
13 | "background": {
14 | "service_worker": "background.js"
15 | },
16 | "chrome_url_overrides": {
17 | "newtab": "index.html"
18 | },
19 | "icons": {
20 | "128": "icon.png"
21 | },
22 | "action": {
23 | "default_icon": "icon.png",
24 | "default_title": "Open Mission Control"
25 | }
26 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mission-control",
3 | "version": "1.0.0",
4 | "description": "Chrome Extension",
5 | "main": "background.js",
6 | "scripts": {
7 | "dev": "postcss ./static/css/tailwind.css -o ./static/css/style.css -w",
8 | "build": "cross-env NODE_ENV=production postcss ./static/css/tailwind.css -o ./static/css/style.css"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "git+https://github.com/surjithctly/mission-control.git"
13 | },
14 | "keywords": [
15 | "chrome",
16 | "extension"
17 | ],
18 | "author": "Surjith S M",
19 | "license": "ISC",
20 | "bugs": {
21 | "url": "https://github.com/surjithctly/mission-control/issues"
22 | },
23 | "homepage": "https://github.com/surjithctly/mission-control#readme",
24 | "devDependencies": {
25 | "@tailwindcss/jit": "^0.1.17",
26 | "autoprefixer": "^10.2.5",
27 | "cross-env": "^7.0.3",
28 | "cssnano": "^4.1.11",
29 | "postcss": "^8.3.0",
30 | "postcss-cli": "^8.3.1",
31 | "tailwindcss": "^2.0.4",
32 | "vite": "^2.1.4"
33 | },
34 | "dependencies": {}
35 | }
36 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | "@tailwindcss/jit": {},
4 | autoprefixer: {},
5 | [process.env.NODE_ENV === "production" ? "cssnano" : ""]: {},
6 | },
7 | };
8 |
--------------------------------------------------------------------------------
/static/css/tailwind.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | /* h1.ui.center.header {
6 | margin-top: 3em;
7 | }
8 |
9 | .completed label {
10 | opacity: 0.5;
11 | text-decoration: line-through;
12 | } */
13 |
14 | /*-----Tailwind Overrides-----*/
15 | /* .bg-gray-100 {
16 | --bg-opacity: 1;
17 | background-color: #f7fafc;
18 | background-color: rgba(247, 250, 252, var(--bg-opacity));
19 | } */
20 | /*------------*/
21 |
22 | .spinner {
23 | animation: rotate 2s linear infinite;
24 | }
25 |
26 | .spinner .path {
27 | stroke-linecap: round;
28 | animation: dash 1.5s ease-in-out infinite;
29 | }
30 |
31 | @keyframes rotate {
32 | 100% {
33 | transform: rotate(360deg);
34 | }
35 | }
36 |
37 | @keyframes dash {
38 | 0% {
39 | stroke-dasharray: 1, 150;
40 | stroke-dashoffset: 0;
41 | }
42 |
43 | 50% {
44 | stroke-dasharray: 90, 150;
45 | stroke-dashoffset: -35;
46 | }
47 |
48 | 100% {
49 | stroke-dasharray: 90, 150;
50 | stroke-dashoffset: -124;
51 | }
52 | }
53 |
54 | .check-icon {
55 | display: none;
56 | }
57 |
58 | .completed .check-icon {
59 | display: block;
60 | }
61 |
62 | .completed .task__title {
63 | text-decoration: line-through;
64 | opacity: 0.3;
65 | }
66 |
67 | .completed .checkbox {
68 | background-color: #e5e7e8;
69 | border: 0;
70 | }
71 |
72 | .scrolling-touch {
73 | -webkit-overflow-scrolling: touch !important;
74 | }
75 |
76 | .scrollbar-none {
77 | scrollbar-width: none;
78 | }
79 |
80 | .scrollbar-none::-webkit-scrollbar {
81 | display: none !important;
82 | }
83 |
84 | .scrollbar-w-2::-webkit-scrollbar {
85 | width: 0.5rem !important;
86 | height: 0.5rem !important;
87 | }
88 |
89 | .scrollbar-track-gray-lighter::-webkit-scrollbar-track {
90 | background-color: #fff !important;
91 | }
92 |
93 | .scrollbar-thumb-gray::-webkit-scrollbar-thumb {
94 | --bg-opacity: 0.5 !important;
95 | background-color: #fff !important;
96 | /* background-color: rgba(203, 213, 224, var(--bg-opacity)) !important*/
97 | }
98 |
99 | .scrollbar-thumb-rounded::-webkit-scrollbar-thumb {
100 | border-radius: 0.25rem !important;
101 | }
102 |
103 | .h-1\/3 {
104 | height: 33.333333%;
105 | }
106 |
107 | .h-1\/2 {
108 | height: 50%;
109 | }
110 |
111 | .h-25 {
112 | height: 25rem;
113 | }
114 |
115 | .pt-05 {
116 | padding-top: 0.1rem;
117 | }
118 |
119 | .remove {
120 | display: none;
121 | }
122 |
123 | .item:hover .remove {
124 | display: block;
125 | }
126 |
127 | .card__is__dragging,
128 | .site__is__dragging {
129 | background-color: #edf2f7;
130 | }
131 |
132 | .card__is__dragging *,
133 | .site__is__dragging * {
134 | opacity: 0;
135 | }
136 |
137 | /*
138 | .js__bookmark_card::-webkit-scrollbar {
139 | opacity: 0;
140 | display: none;
141 | } */
142 |
143 | /* .js__bookmark_card:hover::-webkit-scrollbar {
144 | opacity: 1;
145 | display: initial;
146 | } */
147 |
148 | .disabled\:opacity-75:disabled {
149 | opacity: 0.75 !important;
150 | }
151 |
152 | .overflow__block.scrollbar-thumb-gray:hover::-webkit-scrollbar-thumb {
153 | --bg-opacity: 0.5 !important;
154 | background-color: #cbd5e0 !important;
155 | background-color: rgba(203, 213, 224, var(--bg-opacity)) !important;
156 | }
157 |
158 | .draggable-svg {
159 | top: 9px;
160 | left: -12px;
161 | }
162 |
163 | .draggable-tasks {
164 | top: 12px;
165 | left: 7px;
166 | opacity: 0;
167 | }
168 |
169 | .js__tasks_card .item:hover .draggable-tasks {
170 | opacity: 1;
171 | }
172 |
173 | .disable__hover item:hover {
174 | pointer-events: none;
175 | background: rgba(255, 255, 255, 0);
176 | }
177 |
178 | .grabbable {
179 | cursor: move;
180 | /* fallback if grab cursor is unsupported */
181 | cursor: grab;
182 | cursor: -moz-grab;
183 | cursor: -webkit-grab;
184 | }
185 |
186 | /* (Optional) Apply a "closed-hand" cursor during drag operation. */
187 | .grabbable:active {
188 | cursor: grabbing;
189 | cursor: -moz-grabbing;
190 | cursor: -webkit-grabbing;
191 | }
192 |
193 | .js__bookmark_card:after,
194 | .js__tasks_card:after {
195 | content: "";
196 | width: 100%;
197 | height: 70px;
198 | position: absolute;
199 | left: 0;
200 | bottom: 0;
201 | background: linear-gradient(transparent 0, white 95%);
202 | opacity: 1;
203 | pointer-events: none;
204 | transition: all ease 0.2s;
205 | }
206 |
207 | .js__bookmark_card:hover:after,
208 | .js__tasks_card:hover:after {
209 | opacity: 0;
210 | }
211 |
212 | .card__actions {
213 | opacity: 0;
214 | transition: all ease 0.2s;
215 | }
216 |
217 | .js__bookmark_card:hover .card__actions {
218 | opacity: 1;
219 | }
220 |
221 | .js__tasks_card:hover .card__actions {
222 | opacity: 1;
223 | }
224 |
225 | /* Taks : Show Hide completed */
226 |
227 | .hide_completed .completed {
228 | display: none;
229 | }
230 |
231 | /* Toggle */
232 | .toggle__active {
233 | background: white;
234 | border-radius: 9999px;
235 | color: #7f9cf5;
236 | }
237 |
238 | /* SETTINGS */
239 | .settings__is_open > a > span {
240 | display: none;
241 | }
242 |
243 | .settings__go-back {
244 | display: none;
245 | }
246 |
247 | .settings__is_open .settings__go-back {
248 | display: initial;
249 | }
250 |
251 | .max-h-25 {
252 | max-height: 25rem;
253 | }
254 |
--------------------------------------------------------------------------------
/static/img/default-yellow.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/surjithctly/mission-control/ed84904a7788ac4b7fc1daca244d941d9adc02c2/static/img/default-yellow.webp
--------------------------------------------------------------------------------
/static/js/alpine.min.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Minified by jsDelivr using Terser v3.14.1.
3 | * Original file: /gh/alpinejs/alpine@2.3.3/dist/alpine.js
4 | *
5 | * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
6 | */
7 | !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).Alpine=t()}(this,function(){"use strict";function e(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function t(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,i)}return n}function n(n){for(var i=1;i{const t=u(e.name),n=t.match(a),i=t.match(/:([a-zA-Z\-:]+)/),r=t.match(/\.[^.\]]+(?=[^\]]*$)/g)||[];return{type:n?n[1]:null,value:i?i[1]:null,modifiers:r.map(e=>e.replace(".","")),expression:e.value}}).filter(e=>!t||e.type===t)}function u(e){return e.startsWith("@")?e.replace("@","x-on:"):e.startsWith(":")?e.replace(":","x-bind:"):e}function d(e,t,n=!1){if(n)return t();const i=c(e,"transition"),r=c(e,"show")[0];if(r&&r.modifiers.includes("transition")){let n=r.modifiers;if(n.includes("out")&&!n.includes("in"))return t();const i=n.includes("in")&&n.includes("out");(function(e,t,n){const i={duration:m(t,"duration",150),origin:m(t,"origin","center"),first:{opacity:0,scale:m(t,"scale",95)},second:{opacity:1,scale:100}};p(e,t,n,()=>{},i)})(e,n=i?n.filter((e,t)=>t0?function(e,t,n){const i=(t.find(e=>"enter"===e.value)||{expression:""}).expression.split(" ").filter(e=>""!==e),r=(t.find(e=>"enter-start"===e.value)||{expression:""}).expression.split(" ").filter(e=>""!==e),s=(t.find(e=>"enter-end"===e.value)||{expression:""}).expression.split(" ").filter(e=>""!==e);h(e,i,r,s,n,()=>{})}(e,i,t):t()}function f(e,t,n=!1){if(n)return t();const i=c(e,"transition"),r=c(e,"show")[0];if(r&&r.modifiers.includes("transition")){let n=r.modifiers;if(n.includes("in")&&!n.includes("out"))return t();const i=n.includes("in")&&n.includes("out");(function(e,t,n,i){const r={duration:n?m(t,"duration",150):m(t,"duration",150)/2,origin:m(t,"origin","center"),first:{opacity:1,scale:100},second:{opacity:0,scale:m(t,"scale",95)}};p(e,t,()=>{},i,r)})(e,n=i?n.filter((e,t)=>t>n.indexOf("out")):n,i,t)}else i.length>0?function(e,t,n){const i=(t.find(e=>"leave"===e.value)||{expression:""}).expression.split(" ").filter(e=>""!==e),r=(t.find(e=>"leave-start"===e.value)||{expression:""}).expression.split(" ").filter(e=>""!==e),s=(t.find(e=>"leave-end"===e.value)||{expression:""}).expression.split(" ").filter(e=>""!==e);h(e,i,r,s,()=>{},n)}(e,i,t):t()}function m(e,t,n){if(-1===e.indexOf(t))return n;const i=e[e.indexOf(t)+1];if(!i)return n;if("scale"===t&&!b(i))return n;if("duration"===t){let e=i.match(/([0-9]+)ms/);if(e)return e[1]}return"origin"===t&&["top","right","left","center","bottom"].includes(e[e.indexOf(t)+2])?[i,e[e.indexOf(t)+2]].join(" "):i}function p(e,t,n,i,r){const s=e.style.opacity,o=e.style.transform,a=e.style.transformOrigin,l=!t.includes("opacity")&&!t.includes("scale"),c=l||t.includes("opacity"),u=l||t.includes("scale"),d={start(){c&&(e.style.opacity=r.first.opacity),u&&(e.style.transform=`scale(${r.first.scale/100})`)},during(){u&&(e.style.transformOrigin=r.origin),e.style.transitionProperty=[c?"opacity":"",u?"transform":""].join(" ").trim(),e.style.transitionDuration=`${r.duration/1e3}s`,e.style.transitionTimingFunction="cubic-bezier(0.4, 0.0, 0.2, 1)"},show(){n()},end(){c&&(e.style.opacity=r.second.opacity),u&&(e.style.transform=`scale(${r.second.scale/100})`)},hide(){i()},cleanup(){c&&(e.style.opacity=s),u&&(e.style.transform=o),u&&(e.style.transformOrigin=a),e.style.transitionProperty=null,e.style.transitionDuration=null,e.style.transitionTimingFunction=null}};v(e,d)}function h(e,t,n,i,r,s){const o=e.__x_original_classes||[],a={start(){e.classList.add(...n)},during(){e.classList.add(...t)},show(){r()},end(){e.classList.remove(...n.filter(e=>!o.includes(e))),e.classList.add(...i)},hide(){s()},cleanup(){e.classList.remove(...t.filter(e=>!o.includes(e))),e.classList.remove(...i.filter(e=>!o.includes(e)))}};v(e,a)}function v(e,t){t.start(),t.during(),requestAnimationFrame(()=>{let n=1e3*Number(getComputedStyle(e).transitionDuration.replace(/,.*/,"").replace("s",""));t.show(),requestAnimationFrame(()=>{t.end(),setTimeout(()=>{t.hide(),e.isConnected&&t.cleanup()},n)})})}function b(e){return!isNaN(e)}function y(e,t,i,r,s){"template"!==t.tagName.toLowerCase()&&console.warn("Alpine: [x-for] directive should only be added to tags.");let o=function(e){let t=/,([^,\}\]]*)(?:,([^,\}\]]*))?$/,n=e.match(/([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/);if(!n)return;let i={};i.items=n[2].trim();let r=n[1].trim().replace(/^\(|\)$/g,""),s=r.match(t);s?(i.item=r.replace(t,"").trim(),i.index=s[1].trim(),s[2]&&(i.collection=s[2].trim())):i.item=r;return i}(i),a=function(e,t,n,i){let r=c(t,"if")[0];if(r&&!e.evaluateReturnExpression(t,r.expression))return[];return e.evaluateReturnExpression(t,n.items,i)}(e,t,o,s),l=t;a.forEach((i,u)=>{let f=function(e,t,i,r,s){let o=s?n({},s):{};o[e.item]=t,e.index&&(o[e.index]=i);e.collection&&(o[e.collection]=r);return o}(o,i,u,a,s()),m=function(e,t,n,i){let r=c(t,"bind").filter(e=>"key"===e.value)[0];return r?e.evaluateReturnExpression(t,r.expression,()=>i):n}(e,t,u,f),p=l.nextElementSibling;p&&void 0!==p.__x_for_key?((p=function(e,t){if(e.__x_for_key===t)return e;let n=e;for(;n;){if(n.__x_for_key===t)return n.parentElement.insertBefore(n,e);n=!(!n.nextElementSibling||void 0===n.nextElementSibling.__x_for_key)&&n.nextElementSibling}}(p,m))||(p=g(t,l)),delete p.__x_for_key,p.__x_for=f,e.updateElements(p,()=>p.__x_for)):(d(p=g(t,l),()=>{},r),p.__x_for=f,e.initializeElements(p,()=>p.__x_for)),(l=p).__x_for_key=m}),function(e){var t=!(!e.nextElementSibling||void 0===e.nextElementSibling.__x_for_key)&&e.nextElementSibling;for(;t;){let e=t,n=t.nextElementSibling;f(t,()=>{e.remove()}),t=!(!n||void 0===n.__x_for_key)&&n}}(l)}function g(e,t){let n=document.importNode(e.content,!0);return 1!==n.childElementCount&&console.warn("Alpine: tag with [x-for] encountered with multiple element roots. Make sure only has a single child node."),t.parentElement.insertBefore(n,t.nextElementSibling),t.nextElementSibling}function x(e,t,n,r,s,o){var a=e.evaluateReturnExpression(t,r,s);if("value"===n)if(void 0===a&&r.match(/\./).length&&(a=""),"radio"===t.type)void 0===t.attributes.value&&"bind"===o?t.value=a:"bind"!==o&&(t.checked=t.value==a);else if("checkbox"===t.type){if(Array.isArray(a)){let e=!1;a.forEach(n=>{n==t.value&&(e=!0)}),t.checked=e}else t.checked=!!a;"string"==typeof a&&(t.value=a)}else if("SELECT"===t.tagName)!function(e,t){const n=[].concat(t).map(e=>e+"");Array.from(e.options).forEach(e=>{e.selected=n.includes(e.value||e.text)})}(t,a);else if("text"===t.type){const e=t.selectionStart,n=t.selectionEnd,i=t.selectionDirection;t.value=a,t===document.activeElement&&null!==e&&t.setSelectionRange(e,n,i)}else t.value=a;else if("class"===n)if(Array.isArray(a)){const e=t.__x_original_classes||[];t.setAttribute("class",i(e.concat(a)).join(" "))}else if("object"==typeof a){Object.keys(a).sort((e,t)=>a[e]-a[t]).forEach(e=>{a[e]?e.split(" ").forEach(e=>t.classList.add(e)):e.split(" ").forEach(e=>t.classList.remove(e))})}else{const e=t.__x_original_classes||[],n=a.split(" ");t.setAttribute("class",i(e.concat(n)).join(" "))}else!function(e){return["disabled","checked","required","readonly","hidden","open","selected","autofocus","itemscope","multiple","novalidate","allowfullscreen","allowpaymentrequest","formnovalidate","autoplay","controls","loop","muted","playsinline","default","ismap","reversed","async","defer","nomodule"].includes(e)}(n)?t.setAttribute(n,a):a?t.setAttribute(n,""):t.removeAttribute(n)}function w(e,t,n,i,r,o={}){if(i.includes("away")){let s=a=>{t.contains(a.target)||t.offsetWidth<1&&t.offsetHeight<1||(_(e,r,a,o),i.includes("once")&&document.removeEventListener(n,s))};document.addEventListener(n,s)}else{let a=i.includes("window")?window:i.includes("document")?document:t,l=s=>{if(a!==window&&a!==document||document.body.contains(t)){if(!(function(e){return["keydown","keyup"].includes(e)}(n)&&function(e,t){let n=t.filter(e=>!["window","document","prevent","stop"].includes(e));if(n.includes("debounce")){let e=n.indexOf("debounce");n.splice(e,b((n[e+1]||"invalid-wait").split("ms")[0])?2:1)}if(0===n.length)return!1;if(1===n.length&&n[0]===E(e.key))return!1;const i=["ctrl","shift","alt","meta","cmd","super"].filter(e=>n.includes(e));if(n=n.filter(e=>!i.includes(e)),i.length>0){const t=i.filter(t=>("cmd"!==t&&"super"!==t||(t="meta"),e[`${t}Key`]));if(t.length===i.length&&n[0]===E(e.key))return!1}return!0}(s,i)||(i.includes("prevent")&&s.preventDefault(),i.includes("stop")&&s.stopPropagation(),i.includes("self")&&s.target!==t))){!1===_(e,r,s,o)?s.preventDefault():i.includes("once")&&a.removeEventListener(n,l)}}else a.removeEventListener(n,l)};if(i.includes("debounce")){let e=i[i.indexOf("debounce")+1]||"invalid-wait",t=b(e.split("ms")[0])?Number(e.split("ms")[0]):250;l=s(l,t)}a.addEventListener(n,l)}}function _(e,t,i,r){return e.evaluateCommandExpression(i.target,t,()=>n({},r(),{$event:i}))}function E(e){switch(e){case"/":return"slash";case" ":case"Spacebar":return"space";default:return e&&e.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[_\s]/,"-").toLowerCase()}}function O(e,t,n){return"radio"===e.type&&(e.hasAttribute("name")||e.setAttribute("name",n)),(n,i)=>{if(n instanceof CustomEvent&&n.detail)return n.detail;if("checkbox"===e.type)return Array.isArray(i)?n.target.checked?i.concat([n.target.value]):i.filter(e=>e!==n.target.value):n.target.checked;if("select"===e.tagName.toLowerCase()&&e.multiple)return t.includes("number")?Array.from(n.target.selectedOptions).map(e=>{const t=e.value||e.text,n=t?parseFloat(t):null;return isNaN(n)?t:n}):Array.from(n.target.selectedOptions).map(e=>e.value||e.text);{const e=n.target.value,i=e?parseFloat(e):null;return t.includes("number")?isNaN(i)?e:i:t.includes("trim")?e.trim():e}}}const{isArray:k}=Array,{getPrototypeOf:A,create:S,defineProperty:$,defineProperties:P,isExtensible:D,getOwnPropertyDescriptor:C,getOwnPropertyNames:j,getOwnPropertySymbols:T,preventExtensions:N,hasOwnProperty:L}=Object,{push:R,concat:z,map:F}=Array.prototype;function M(e){return void 0===e}function I(e){return"function"==typeof e}const U=new WeakMap;function q(e,t){U.set(e,t)}const B=e=>U.get(e)||e;function W(e,t){return e.valueIsObservable(t)?e.getProxy(t):t}function K(e,t,n){z.call(j(n),T(n)).forEach(i=>{let r=C(n,i);r.configurable||(r=te(e,r,W)),$(t,i,r)}),N(t)}class G{constructor(e,t){this.originalTarget=t,this.membrane=e}get(e,t){const{originalTarget:n,membrane:i}=this,r=n[t],{valueObserved:s}=i;return s(n,t),i.getProxy(r)}set(e,t,n){const{originalTarget:i,membrane:{valueMutated:r}}=this;return i[t]!==n?(i[t]=n,r(i,t)):"length"===t&&k(i)&&r(i,t),!0}deleteProperty(e,t){const{originalTarget:n,membrane:{valueMutated:i}}=this;return delete n[t],i(n,t),!0}apply(e,t,n){}construct(e,t,n){}has(e,t){const{originalTarget:n,membrane:{valueObserved:i}}=this;return i(n,t),t in n}ownKeys(e){const{originalTarget:t}=this;return z.call(j(t),T(t))}isExtensible(e){const t=D(e);if(!t)return t;const{originalTarget:n,membrane:i}=this,r=D(n);return r||K(i,e,n),r}setPrototypeOf(e,t){}getPrototypeOf(e){const{originalTarget:t}=this;return A(t)}getOwnPropertyDescriptor(e,t){const{originalTarget:n,membrane:i}=this,{valueObserved:r}=this.membrane;r(n,t);let s=C(n,t);if(M(s))return s;const o=C(e,t);return M(o)?((s=te(i,s,W)).configurable||$(e,t,s),s):o}preventExtensions(e){const{originalTarget:t,membrane:n}=this;return K(n,e,t),N(t),!0}defineProperty(e,t,n){const{originalTarget:i,membrane:r}=this,{valueMutated:s}=r,{configurable:o}=n;if(L.call(n,"writable")&&!L.call(n,"value")){const e=C(i,t);n.value=e.value}return $(i,t,function(e){return L.call(e,"value")&&(e.value=B(e.value)),e}(n)),!1===o&&$(e,t,te(r,n,W)),s(i,t),!0}}function H(e,t){return e.valueIsObservable(t)?e.getReadOnlyProxy(t):t}class Z{constructor(e,t){this.originalTarget=t,this.membrane=e}get(e,t){const{membrane:n,originalTarget:i}=this,r=i[t],{valueObserved:s}=n;return s(i,t),n.getReadOnlyProxy(r)}set(e,t,n){return!1}deleteProperty(e,t){return!1}apply(e,t,n){}construct(e,t,n){}has(e,t){const{originalTarget:n,membrane:{valueObserved:i}}=this;return i(n,t),t in n}ownKeys(e){const{originalTarget:t}=this;return z.call(j(t),T(t))}setPrototypeOf(e,t){}getOwnPropertyDescriptor(e,t){const{originalTarget:n,membrane:i}=this,{valueObserved:r}=i;r(n,t);let s=C(n,t);if(M(s))return s;const o=C(e,t);return M(o)?(s=te(i,s,H),L.call(s,"set")&&(s.set=void 0),s.configurable||$(e,t,s),s):o}preventExtensions(e){return!1}defineProperty(e,t,n){return!1}}function J(e){let t=void 0;return k(e)?t=[]:"object"==typeof e&&(t={}),t}const Q=Object.prototype;function V(e){if(null===e)return!1;if("object"!=typeof e)return!1;if(k(e))return!0;const t=A(e);return t===Q||null===t||null===A(t)}const X=(e,t)=>{},Y=(e,t)=>{},ee=e=>e;function te(e,t,n){const{set:i,get:r}=t;return L.call(t,"value")?t.value=n(e,t.value):(M(r)||(t.get=function(){return n(e,r.call(B(this)))}),M(i)||(t.set=function(t){i.call(B(this),e.unwrapProxy(t))})),t}class ne{constructor(e){if(this.valueDistortion=ee,this.valueMutated=Y,this.valueObserved=X,this.valueIsObservable=V,this.objectGraph=new WeakMap,!M(e)){const{valueDistortion:t,valueMutated:n,valueObserved:i,valueIsObservable:r}=e;this.valueDistortion=I(t)?t:ee,this.valueMutated=I(n)?n:Y,this.valueObserved=I(i)?i:X,this.valueIsObservable=I(r)?r:V}}getProxy(e){const t=B(e),n=this.valueDistortion(t);if(this.valueIsObservable(n)){const i=this.getReactiveState(t,n);return i.readOnly===e?e:i.reactive}return n}getReadOnlyProxy(e){e=B(e);const t=this.valueDistortion(e);return this.valueIsObservable(t)?this.getReactiveState(e,t).readOnly:t}unwrapProxy(e){return B(e)}getReactiveState(e,t){const{objectGraph:n}=this;let i=n.get(t);if(i)return i;const r=this;return i={get reactive(){const n=new G(r,t),i=new Proxy(J(t),n);return q(i,e),$(this,"reactive",{value:i}),i},get readOnly(){const n=new Z(r,t),i=new Proxy(J(t),n);return q(i,e),$(this,"readOnly",{value:i}),i}},n.set(t,i),i}}class ie{constructor(e,t=null){this.$el=e;const n=this.$el.getAttribute("x-data"),i=""===n?"{}":n,r=this.$el.getAttribute("x-init");this.unobservedData=t||o(i,{});let{membrane:s,data:a}=this.wrapDataInObservable(this.unobservedData);var l;this.$data=a,this.membrane=s,this.unobservedData.$el=this.$el,this.unobservedData.$refs=this.getRefsProxy(),this.nextTickStack=[],this.unobservedData.$nextTick=(e=>{this.nextTickStack.push(e)}),this.watchers={},this.unobservedData.$watch=((e,t)=>{this.watchers[e]||(this.watchers[e]=[]),this.watchers[e].push(t)}),this.showDirectiveStack=[],this.showDirectiveLastElement,r&&!t&&(this.pauseReactivity=!0,l=this.evaluateReturnExpression(this.$el,r),this.pauseReactivity=!1),this.initializeElements(this.$el),this.listenForNewElementsToInitialize(),"function"==typeof l&&l.call(this.$data)}getUnobservedData(){return function(e,t){let n=e.unwrapProxy(t),i={};return Object.keys(n).forEach(e=>{["$el","$refs","$nextTick","$watch"].includes(e)||(i[e]=n[e])}),i}(this.membrane,this.$data)}wrapDataInObservable(e){var t=this;let n=s(function(){t.updateElements(t.$el)},0);return function(e,t){let n=new ne({valueMutated(e,n){t(e,n)}});return{data:n.getProxy(e),membrane:n}}(e,(e,i)=>{t.watchers[i]?t.watchers[i].forEach(t=>t(e[i])):Object.keys(t.watchers).filter(e=>e.includes(".")).forEach(n=>{let r=n.split(".");i===r[r.length-1]&&r.reduce((r,s)=>(Object.is(e,r)&&t.watchers[n].forEach(t=>t(e[i])),r[s]),t.getUnobservedData())}),t.pauseReactivity||n()})}walkAndSkipNestedComponents(e,t,n=(()=>{})){!function e(t,n){if(!1===n(t))return;let i=t.firstElementChild;for(;i;)e(i,n),i=i.nextElementSibling}(e,e=>e.hasAttribute("x-data")&&!e.isSameNode(this.$el)?(e.__x||n(e),!1):t(e))}initializeElements(e,t=(()=>{})){this.walkAndSkipNestedComponents(e,e=>void 0===e.__x_for_key&&(void 0===e.__x_inserted_me&&void this.initializeElement(e,t)),e=>{e.__x=new ie(e)}),this.executeAndClearRemainingShowDirectiveStack(),this.executeAndClearNextTickStack(e)}initializeElement(e,t){e.hasAttribute("class")&&c(e).length>0&&(e.__x_original_classes=e.getAttribute("class").split(" ")),this.registerListeners(e,t),this.resolveBoundAttributes(e,!0,t)}updateElements(e,t=(()=>{})){this.walkAndSkipNestedComponents(e,e=>{if(void 0!==e.__x_for_key&&!e.isSameNode(this.$el))return!1;this.updateElement(e,t)},e=>{e.__x=new ie(e)}),this.executeAndClearRemainingShowDirectiveStack(),this.executeAndClearNextTickStack(e)}executeAndClearNextTickStack(e){if(e===this.$el)for(;this.nextTickStack.length>0;)this.nextTickStack.shift()()}executeAndClearRemainingShowDirectiveStack(){this.showDirectiveStack.reverse().map(e=>new Promise(t=>{e(e=>{t(e)})})).reduce((e,t)=>e.then(()=>t.then(e=>e())),Promise.resolve(()=>{})),this.showDirectiveStack=[],this.showDirectiveLastElement=void 0}updateElement(e,t){this.resolveBoundAttributes(e,!1,t)}registerListeners(e,t){c(e).forEach(({type:i,value:r,modifiers:s,expression:o})=>{switch(i){case"on":w(this,e,r,s,o,t);break;case"model":!function(e,t,i,r,s){var o="select"===t.tagName.toLowerCase()||["checkbox","radio"].includes(t.type)||i.includes("lazy")?"change":"input";w(e,t,o,i,`${r} = rightSideOfExpression($event, ${r})`,()=>n({},s(),{rightSideOfExpression:O(t,i,r)}))}(this,e,s,o,t)}})}resolveBoundAttributes(e,t=!1,n){let i=c(e);if(void 0!==e.type&&"radio"===e.type){const e=i.findIndex(e=>"model"===e.type);e>-1&&i.push(i.splice(e,1)[0])}i.forEach(({type:r,value:s,modifiers:o,expression:a})=>{switch(r){case"model":x(this,e,"value",a,n,r);break;case"bind":if("template"===e.tagName.toLowerCase()&&"key"===s)return;x(this,e,s,a,n,r);break;case"text":var l=this.evaluateReturnExpression(e,a,n);!function(e,t,n){void 0===t&&n.match(/\./).length&&(t=""),e.innerText=t}(e,l,a);break;case"html":!function(e,t,n,i){t.innerHTML=e.evaluateReturnExpression(t,n,i)}(this,e,a,n);break;case"show":l=this.evaluateReturnExpression(e,a,n);!function(e,t,n,i,r=!1){const s=()=>{t.style.display="none"},o=()=>{1===t.style.length&&"none"===t.style.display?t.removeAttribute("style"):t.style.removeProperty("display")};if(!0===r)return void(n?o():s());const a=e=>{n?(""!==t.style.display&&d(t,()=>{o()}),e(()=>{})):"none"!==t.style.display?f(t,()=>{e(()=>{s()})}):e(()=>{})};i.includes("immediate")?a(e=>e()):(e.showDirectiveLastElement&&!e.showDirectiveLastElement.contains(t)&&e.executeAndClearRemainingShowDirectiveStack(),e.showDirectiveStack.push(a),e.showDirectiveLastElement=t)}(this,e,l,o,t);break;case"if":if(i.filter(e=>"for"===e.type).length>0)return;l=this.evaluateReturnExpression(e,a,n);!function(e,t,n,i,r){"template"!==t.nodeName.toLowerCase()&&console.warn("Alpine: [x-if] directive should only be added to tags. See https://github.com/alpinejs/alpine#x-if");const s=t.nextElementSibling&&!0===t.nextElementSibling.__x_inserted_me;if(n&&!s){const n=document.importNode(t.content,!0);t.parentElement.insertBefore(n,t.nextElementSibling),d(t.nextElementSibling,()=>{},i),e.initializeElements(t.nextElementSibling,r),t.nextElementSibling.__x_inserted_me=!0}else!n&&s&&f(t.nextElementSibling,()=>{t.nextElementSibling.remove()},i)}(this,e,l,t,n);break;case"for":y(this,e,a,t,n);break;case"cloak":e.removeAttribute("x-cloak")}})}evaluateReturnExpression(e,t,i=(()=>{})){return o(t,this.$data,n({},i(),{$dispatch:this.getDispatchFunction(e)}))}evaluateCommandExpression(e,t,i=(()=>{})){return function(e,t,n={}){if(Object.keys(t).includes(e)){let i=new Function(["dataContext",...Object.keys(n)],`with(dataContext) { return ${e} }`)(t,...Object.values(n));if("function"==typeof i)return i.call(t,n.$event)}return new Function(["dataContext",...Object.keys(n)],`with(dataContext) { ${e} }`)(t,...Object.values(n))}(t,this.$data,n({},i(),{$dispatch:this.getDispatchFunction(e)}))}getDispatchFunction(e){return(t,n={})=>{e.dispatchEvent(new CustomEvent(t,{detail:n,bubbles:!0}))}}listenForNewElementsToInitialize(){const e=this.$el;new MutationObserver(e=>{for(let t=0;t{this.$data[e]!==n[e]&&(this.$data[e]=n[e])})}e[t].addedNodes.length>0&&e[t].addedNodes.forEach(e=>{1!==e.nodeType||e.__x_inserted_me||(e.matches("[x-data]")?e.__x=new ie(e):this.initializeElements(e))})}}}).observe(e,{childList:!0,attributes:!0,subtree:!0})}getRefsProxy(){var e=this;return new Proxy({},{get(t,n){return"$isAlpineProxy"===n||(e.walkAndSkipNestedComponents(e.$el,e=>{e.hasAttribute("x-ref")&&e.getAttribute("x-ref")===n&&(i=e)}),i);var i}})}}const re={version:"2.3.3",start:async function(){r()||await new Promise(e=>{"loading"==document.readyState?document.addEventListener("DOMContentLoaded",e):e()}),this.discoverComponents(e=>{this.initializeComponent(e)}),document.addEventListener("turbolinks:load",()=>{this.discoverUninitializedComponents(e=>{this.initializeComponent(e)})}),this.listenForNewUninitializedComponentsAtRunTime(e=>{this.initializeComponent(e)})},discoverComponents:function(e){document.querySelectorAll("[x-data]").forEach(t=>{e(t)})},discoverUninitializedComponents:function(e,t=null){const n=(t||document).querySelectorAll("[x-data]");Array.from(n).filter(e=>void 0===e.__x).forEach(t=>{e(t)})},listenForNewUninitializedComponentsAtRunTime:function(e){const t=document.querySelector("body");new MutationObserver(e=>{for(let t=0;t0&&e[t].addedNodes.forEach(e=>{1===e.nodeType&&(e.parentElement&&e.parentElement.closest("[x-data]")||this.discoverUninitializedComponents(e=>{this.initializeComponent(e)},e.parentElement))})}).observe(t,{childList:!0,attributes:!0,subtree:!0})},initializeComponent:function(e){e.__x||(e.__x=new ie(e))},clone:function(e,t){t.__x||(t.__x=new ie(t,e.getUnobservedData()))}};return r()||(window.Alpine=re,window.deferLoadingAlpine?window.deferLoadingAlpine(function(){window.Alpine.start()}):window.Alpine.start()),re});
8 |
--------------------------------------------------------------------------------
/static/js/bookmarks.js:
--------------------------------------------------------------------------------
1 | (function () {
2 | "use strict";
3 |
4 | /*
5 | * -----------------------------------------------------------------------------------
6 | * // Utils Functions
7 | * // random hex string generator
8 | * // Used to provide unique ID to Cards & Sites
9 | * -----------------------------------------------------------------------------------
10 | */
11 |
12 | var randHex = function (len) {
13 | var maxlen = 8,
14 | min = Math.pow(16, Math.min(len, maxlen) - 1),
15 | max = Math.pow(16, Math.min(len, maxlen)) - 1,
16 | n = Math.floor(Math.random() * (max - min + 1)) + min,
17 | r = n.toString(16);
18 | while (r.length < len) {
19 | r = r + randHex(len - maxlen);
20 | }
21 | return r;
22 | };
23 |
24 | /*
25 | * -----------------------------------------------------------------------------------
26 | * // Check if a String Valid URL
27 | * // Used to fetch Title from Link
28 | * -----------------------------------------------------------------------------------
29 | */
30 |
31 | function validURL(str) {
32 | var pattern = new RegExp(
33 | "^(https?:\\/\\/)?" + // protocol
34 | "((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|" + // domain name
35 | "((\\d{1,3}\\.){3}\\d{1,3}))" + // OR ip (v4) address
36 | "(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*" + // port and path
37 | "(\\?[;&a-z\\d%_.~+=-]*)?" + // query string
38 | "(\\#[-a-z\\d_]*)?$",
39 | "i"
40 | ); // fragment locator
41 | return !!pattern.test(str);
42 | }
43 |
44 | /*
45 | * -----------------------------------------------------------------------------------
46 | * // Bookmark INPUT Function
47 | * // Functions to fetch Title
48 | * -----------------------------------------------------------------------------------
49 | */
50 |
51 | $("#bookmark_url").on("keyup change paste input", function (e) {
52 | if (this.value != "") {
53 | var url_result = validURL(this.value);
54 | if (url_result) {
55 | $("#bookmark_title").attr({
56 | disabled: true,
57 | placeholder: "Fetching Title... Please wait",
58 | });
59 | // Function declared as async so await can be used
60 | async function fetchContent() {
61 | // Instead of using fetch().then, use await
62 | let text = await $("#bookmark_url").val();
63 |
64 | // Inside the async function text is the request body
65 | getTitlefromURL(text);
66 |
67 | // Resolve this async function with the text
68 | return text;
69 | }
70 |
71 | // Use the async function
72 | var promise = fetchContent();
73 | }
74 | } else {
75 | // Do Nothing
76 | }
77 | });
78 |
79 | /*
80 | * -----------------------------------------------------------------------------------
81 | * // Fetch from URL
82 | * // This requries manifest Persmission for
83 | * // content_security_policy also need to satisfy
84 | * -----------------------------------------------------------------------------------
85 | */
86 |
87 | function getTitlefromURL(url_result) {
88 | var xhr = new XMLHttpRequest();
89 | xhr.open("GET", url_result, true);
90 | xhr.onreadystatechange = function () {
91 | $("#bookmark_title").attr({
92 | disabled: false,
93 | placeholder: "Enter Title",
94 | });
95 | if (xhr.readyState == 4 && xhr.responseText) {
96 | if (xhr.responseText.indexOf("") != -1) {
97 | // console.log(xhr.responseText);
98 | var title = /(.*?)<\/title>/m.exec(xhr.responseText)[1];
99 | console.log(title);
100 | addTitletoDom(title);
101 | } else {
102 | console.log(xhr.statusText);
103 | console.log("Title not found");
104 | }
105 | }
106 | };
107 | xhr.onerror = function (e) {
108 | console.log("xhr Fetch Error");
109 | //console.log(xhr.statusText);
110 | };
111 | xhr.send(null);
112 | }
113 |
114 | /*
115 | * -----------------------------------------------------------------------------------
116 | * // Add Fetched Title to DOM
117 | * // It will be blank if error or can't find title
118 | * -----------------------------------------------------------------------------------
119 | */
120 |
121 | function addTitletoDom(title) {
122 | if ($("#bookmark_title").val() === "" && $("#bookmark_url").val() !== "") {
123 | $("#bookmark_title").val(title);
124 | // console.log(this.value);
125 | }
126 | }
127 |
128 | /*
129 | * -----------------------------------------------------------------------------------
130 | * // CARD TEMPLATE
131 | * // USed in many Places to GENERATE CARD UI DOM
132 | * -----------------------------------------------------------------------------------
133 | */
134 |
135 | const newCardTemplate = ({ card_title, card_id, websites, starred }) => `
136 |
137 |
193 |
194 |
195 | `;
196 |
197 | /*
198 | * -----------------------------------------------------------------------------------
199 | * // WEBSITE LIST TEMPLATE
200 | * // To use inside card Template.
201 | * -----------------------------------------------------------------------------------
202 | */
203 |
204 | const bookmarklist = ({
205 | bookmarks_id,
206 | bookmarks_title,
207 | bookmarks_url,
208 | bookmarks_desc,
209 | }) => `
210 |
211 |
239 |
240 |
241 | `;
242 |
243 | /*
244 | * -----------------------------------------------------------------------------------
245 | * // SET UNSAVED TO TRUE
246 | * // To Sync with Github
247 | * -----------------------------------------------------------------------------------
248 | */
249 |
250 | function setUnsavedChanges() {
251 | console.log("inside setUnsavedChanges");
252 | chrome.storage.local.get("settings", function (storage) {
253 | // console.log("hey", storage);
254 | const settings = storage.settings;
255 | // console.log("hooy", settings);
256 | // console.log(settings);
257 | for (let key in settings) {
258 | // console.log("kye" + key);
259 | if (settings.hasOwnProperty(key)) {
260 | settings[key].unsaved_changes = true;
261 | }
262 | }
263 |
264 | chrome.storage.local.set({ settings }, function () {
265 | // do nothing
266 | console.log("done");
267 | });
268 | });
269 | }
270 |
271 | /*
272 | * -----------------------------------------------------------------------------------
273 | * // ON Page Load Setup
274 | * // It will Generate Cards on page load
275 | * -----------------------------------------------------------------------------------
276 | */
277 |
278 | var carddb = "sites";
279 |
280 | var cardarray = new Array();
281 |
282 | chrome.storage.local.get(carddb, function (storage) {
283 | if (carddb in storage) {
284 | cardarray = storage[carddb];
285 | } else {
286 | // user is first time or database not found
287 | storage = {};
288 | storage[carddb] = [];
289 |
290 | chrome.topSites.get((arr) => {
291 | var newCat = {
292 | label: "Top Sites",
293 | starred: false,
294 | id: 1,
295 | cid: randHex(24),
296 | date: new Date().getTime(),
297 | websites: {},
298 | };
299 | storage[carddb].push(newCat);
300 |
301 | var topbook = storage[carddb];
302 |
303 | var newwebsites = new Array();
304 | for (var i = 0; i < arr.length; i++) {
305 | var newItem = {
306 | title: arr[i].title,
307 | id: randHex(24),
308 | date: new Date().getTime(),
309 | url: arr[i].url,
310 | desc: "",
311 | };
312 | newwebsites.push(newItem);
313 | }
314 |
315 | for (let key in topbook) {
316 | if (topbook.hasOwnProperty(key)) {
317 | if (1 === topbook[key].id) {
318 | topbook[key].websites = newwebsites;
319 | break;
320 | }
321 | }
322 | }
323 |
324 | const missionItems = [
325 | {
326 | date: new Date().getTime(),
327 | desc: "",
328 | id: randHex(24),
329 | title: "Follow on Twitter",
330 | url: "https://twitter.com/surjithctly/",
331 | },
332 |
333 | {
334 | date: new Date().getTime(),
335 | desc: "",
336 | id: randHex(24),
337 | title: "Submit an Issue or Feebback",
338 | url: "https://github.com/surjithctly/mission-control/issues",
339 | },
340 | {
341 | date: new Date().getTime(),
342 | desc: "",
343 | id: randHex(24),
344 | title: "Review on Chrome Store",
345 | url: "https://chrome.google.com/webstore/category/extensions",
346 | },
347 |
348 | {
349 | date: new Date().getTime(),
350 | desc: "",
351 | id: randHex(24),
352 | title: "Github Repo",
353 | url: "https://github.com/surjithctly/mission-control",
354 | },
355 | {
356 | date: new Date().getTime(),
357 | desc: "",
358 | id: randHex(24),
359 | title: "View on Chrome Store",
360 | url: "https://chrome.google.com/webstore/category/extensions",
361 | },
362 | {
363 | date: new Date().getTime(),
364 | desc: "",
365 | id: randHex(24),
366 | title: "Mission Control",
367 | url: "https://mission-control.vercel.app/",
368 | },
369 | ];
370 |
371 | const promotedItems = [
372 | {
373 | date: new Date().getTime(),
374 | desc: "",
375 | id: randHex(24),
376 | title: "Promote your Website here",
377 | url:
378 | "https://twitter.com/messages/compose?recipient_id=79699534&text=Hey%2C%20I%20would%20like%20to%20add%20my%20website%20as%20a%20Promoted%20Websites%20in%20Mission%20Control",
379 | },
380 | {
381 | date: new Date().getTime(),
382 | desc: "",
383 | id: randHex(24),
384 | title: "TailwindCSS Web & UI Components",
385 | url: "https://web3templates.com/components/?ref=mission_control",
386 | },
387 | {
388 | date: new Date().getTime(),
389 | desc: "",
390 | id: randHex(24),
391 | title: "Web3Templates - Free Website & Landing Page Templates",
392 | url: "https://web3templates.com/?ref=mission_control",
393 | },
394 | {
395 | date: new Date().getTime(),
396 | desc: "",
397 | id: randHex(24),
398 | title: "Web3Forms - Contact forms without server",
399 | url: "https://web3forms.com/?ref=mission_control",
400 | },
401 | ];
402 |
403 | const missionCat = {
404 | cid: randHex(24),
405 | date: new Date().getTime(),
406 | id: 1,
407 | label: "Mission Control",
408 | starred: false,
409 | websites: missionItems,
410 | };
411 |
412 | const favCat = {
413 | cid: randHex(24),
414 | date: new Date().getTime(),
415 | id: 0,
416 | promoted: true,
417 | label: "Promoted Websites",
418 | starred: false,
419 | websites: promotedItems,
420 | };
421 |
422 | storage[carddb].push(missionCat);
423 | storage[carddb].push(favCat);
424 |
425 | chrome.storage.local.set(
426 | storage,
427 | function () {
428 | for (var i = 0; i < topbook.length; i++) {
429 | addSiteCards(topbook[i]);
430 | }
431 | setUnsavedChanges();
432 | }.bind(this)
433 | );
434 | });
435 | }
436 |
437 | //displaying the existing items (if user is not new user)
438 | for (var i = 0; i < cardarray.length; i++) {
439 | addSiteCards(cardarray[i]);
440 | //addDatalistToSearch(cardarray[i]);
441 | }
442 | });
443 |
444 | /*
445 | * -----------------------------------------------------------------------------------
446 | * // Function to Add Cards to DOM
447 | * // It will fetch the Card Template from above
448 | * -----------------------------------------------------------------------------------
449 | */
450 |
451 | function addSiteCards(cardarray) {
452 | var websitelist = addSiteLists(cardarray.websites);
453 |
454 | $("#bookmark_cards").append(
455 | [
456 | {
457 | card_title: cardarray.label,
458 | card_id: cardarray.cid,
459 | starred: cardarray.starred,
460 | websites: websitelist,
461 | },
462 | ]
463 | .map(newCardTemplate)
464 | .join("")
465 | );
466 | }
467 | // const cardlabelearray = Array();
468 | // function addDatalistToSearch(cardarray) {
469 | // // cardlabelearray.push(cardarray.label);
470 | // // console.log(cardlabelearray);
471 | // $("#card_categories").append(
472 | // `${cardarray.label} `
473 | // );
474 |
475 | // cardAutocomplete();
476 | // }
477 |
478 | // $("#card_categories").on("click", "a", function (e) {
479 | // e.preventDefault();
480 | // console.log($(this).text());
481 | // });
482 |
483 | // function cardAutocomplete() {
484 | // let $search = $("#bookmark_search_input");
485 | // let $context = $("#card_categories");
486 | // $search.on("input", function () {
487 | // let term = $(this).val();
488 | // $context.find("li").show().unmark();
489 |
490 | // if (term) {
491 | // $context.removeClass("hidden");
492 | // $context.mark(term, {
493 | // done: function () {
494 | // $context.find("li").not(":has(mark)").hide();
495 | // },
496 | // });
497 | // }
498 | // });
499 | // $search.focus(function () {
500 | // $context.removeClass("hidden");
501 | // });
502 |
503 | // $search.blur(function () {
504 | // setTimeout(() => {
505 | // $context.addClass("hidden");
506 | // }, 200);
507 | // });
508 | // }
509 |
510 | function addSiteLists(websites) {
511 | var websitelist = "";
512 | // console.log("websites");
513 | for (var i = 0; i < websites.length; i++) {
514 | //addSiteCards(cardarray[i]);
515 | websitelist =
516 | [
517 | {
518 | bookmarks_id: websites[i].id,
519 | bookmarks_title: websites[i].title,
520 | bookmarks_url: websites[i].url,
521 | bookmarks_desc: websites[i].desc,
522 | },
523 | ]
524 | .map(bookmarklist)
525 | .join("") + websitelist;
526 | }
527 | return websitelist;
528 | }
529 |
530 | $("#bookmark_cards").on("mouseenter", ".js--bookmarks__title", function (e) {
531 | $("span.title", this).addClass("hidden");
532 | $("span.link", this).removeClass("hidden");
533 | });
534 | $("#bookmark_cards").on("mouseleave", ".js--bookmarks__title", function (e) {
535 | $("span.link", this).addClass("hidden");
536 | $("span.title", this).removeClass("hidden");
537 | });
538 |
539 | // ---
540 | // Remove Bookmark Items
541 | // ---
542 |
543 | $("#bookmark_cards").on("click", ".remove", function () {
544 | var chosenID = $(this).closest(".item").data("id");
545 | var catID = $(this).closest(".js__bookmark_card").data("card");
546 | removeItem(chosenID, catID);
547 | $(this).closest(".item").remove();
548 | console.log(chosenID, catID);
549 | });
550 |
551 | function removeItem(chosenID, catID) {
552 | console.log("removeitem");
553 | chrome.storage.local.get([carddb], function (storage) {
554 | var siteList = storage[carddb];
555 | console.log(siteList);
556 |
557 | for (let key in siteList) {
558 | if (siteList.hasOwnProperty(key)) {
559 | if (catID === siteList[key].cid) {
560 | if (siteList[key].websites) {
561 | console.log("sites found in this cat");
562 | // var result = siteList.websites.filter(i=>!i.errorMsg)
563 |
564 | // console.log(result)
565 |
566 | var NewsiteList = $.grep(siteList[key].websites, function (e) {
567 | // console.log(e.id);
568 | return e.id != chosenID;
569 | });
570 | siteList[key].websites = NewsiteList;
571 | //console.log(NewsiteList);
572 | }
573 | break;
574 | }
575 | }
576 | }
577 |
578 | // console.log(siteList);
579 |
580 | chrome.storage.local.set({ [carddb]: siteList }, function () {
581 | console.log(siteList);
582 | setUnsavedChanges();
583 | });
584 | });
585 | }
586 |
587 | // Adding Website to a Category Card
588 | // Inside Popup
589 |
590 | $("#addBookmarkform").on("submit", function (e) {
591 | e.preventDefault();
592 | var title = $("#bookmark_title").val();
593 | var getURL = $("#bookmark_url").val();
594 | var desc = $("#bookmark_desc").val();
595 | var catID = $("#category_id").val();
596 | if (getURL != "" && title != "") {
597 | e.preventDefault();
598 |
599 | var newItem = {
600 | date: new Date().getTime(),
601 | id: randHex(24),
602 | title: title.trim(),
603 | url: getURL,
604 | desc: desc,
605 | };
606 | // addBookmarkItem(newItem);
607 | chrome.storage.local.get([carddb], function (storage) {
608 | var siteList = storage[carddb];
609 | //bookmarks.push(newItem);
610 |
611 | for (let key in siteList) {
612 | if (siteList.hasOwnProperty(key)) {
613 | if (catID === siteList[key].cid) {
614 | if (siteList[key].websites) {
615 | console.log("sites found in this cat");
616 | siteList[key].websites.push(newItem);
617 | }
618 | break;
619 | }
620 | }
621 | }
622 |
623 | //reset value
624 | $("#addBookmarkform")[0].reset();
625 | toggleModal();
626 |
627 | $('.js__bookmark_card[data-card="' + catID + '"] .content').prepend(
628 | [
629 | {
630 | bookmarks_id: newItem.id,
631 | bookmarks_title: newItem.title,
632 | bookmarks_url: newItem.url,
633 | bookmarks_desc: newItem.desc,
634 | },
635 | ]
636 | .map(bookmarklist)
637 | .join("")
638 | );
639 |
640 | // $("#bookmarkMoreForm").addClass("hidden");
641 |
642 | chrome.storage.local.set({ [carddb]: siteList }, function () {
643 | // console.log(siteList);
644 | // console.log("running submit");
645 | setUnsavedChanges();
646 | });
647 | });
648 |
649 | // addItem(e);
650 | // console.log("You pressed enter!");
651 | } else {
652 | alert("Fill all details");
653 | }
654 | });
655 |
656 | $("#addNewBookmarkUI").click(function (e) {
657 | e.preventDefault();
658 |
659 | chrome.storage.local.get([carddb], function (storage) {
660 | var newCat = {
661 | label: "Untitled Group",
662 | starred: false,
663 | id: 1,
664 | cid: randHex(24),
665 | date: new Date().getTime(),
666 | websites: [],
667 | };
668 | storage[carddb].unshift(newCat);
669 | console.log("adding New Category");
670 | console.log(storage);
671 | $("#addNewBookmarkUI").after(
672 | [
673 | {
674 | card_title: newCat.label,
675 | card_id: newCat.cid,
676 | websites: newCat.websites,
677 | },
678 | ]
679 | .map(newCardTemplate)
680 | .join("")
681 | );
682 |
683 | chrome.storage.local.set(
684 | storage,
685 | function () {
686 | console.log("cat added to db");
687 | setUnsavedChanges();
688 | }.bind(this)
689 | );
690 |
691 | var $recentcard = $("#bookmark_cards").find(
692 | '.js__bookmark_card[data-card="' + newCat.cid + '"]'
693 | );
694 | $recentcard.find(".js__card_title_text").addClass("hidden");
695 | $recentcard
696 | .find(".js__card_title_input")
697 | .removeClass("hidden")
698 | .focus()
699 | .select();
700 | });
701 | });
702 |
703 | async function getClipboardContents() {
704 | try {
705 | console.log("Getting Clipboard Data");
706 | const clipboardData = await navigator.clipboard.readText();
707 | console.log(clipboardData);
708 | if (validURL(clipboardData)) {
709 | console.log("Clipboard Data is Calid URL");
710 | $("#bookmark_url").val(clipboardData);
711 | // disable Title field while fetching from URL
712 | $("#bookmark_title").attr({
713 | disabled: true,
714 | placeholder: "Fetching Title... Please wait",
715 | });
716 | getTitlefromURL(clipboardData);
717 | $("#bookmark_title").focus();
718 | }
719 | } catch (err) {
720 | console.error("Failed to read clipboard contents: ", err);
721 | }
722 | }
723 |
724 | function toggleModal() {
725 | const body = document.querySelector("body");
726 | const modal = document.querySelector(".modal");
727 | modal.classList.toggle("opacity-0");
728 | modal.classList.toggle("pointer-events-none");
729 | body.classList.toggle("modal-active");
730 | $("#addBookmarkform").toggleClass("hidden");
731 | $("#dynamicModalTitle").text("Add Website");
732 | console.log("Toggle Modal");
733 | if (body.classList.contains("modal-active")) getClipboardContents();
734 | }
735 |
736 | // Card Dropdown
737 |
738 | $(document).on("click", ".js__add_bookmark", function (e) {
739 | e.preventDefault();
740 | var catID = $(this).closest(".js__bookmark_card").data("card");
741 | $("#addBookmarkform #category_id").val(catID);
742 | toggleModal();
743 | });
744 |
745 | $("#bookmark_cards").on("click", ".js__card_settings", function (e) {
746 | e.preventDefault();
747 | e.stopPropagation();
748 | $(".js__card_menu").not($(this).next(".js__card_menu")).addClass("hidden");
749 | $(this).next(".js__card_menu").toggleClass("hidden");
750 | });
751 |
752 | $(document).on("click", function (e) {
753 | $(".js__card_menu").addClass("hidden");
754 | });
755 |
756 | $("#bookmark_cards").on("click", ".js__delete_card", function (e) {
757 | var $this = $(this).closest(".js__bookmark_card");
758 | var cardid = $($this).data("card");
759 | var totalsites = $(".item", $this).length;
760 | if (
761 | confirm(
762 | "Are you sure you want to delete this card?\nIt contains " +
763 | totalsites +
764 | " websites.\nThere's no UNDO!"
765 | )
766 | ) {
767 | removeCards(cardid);
768 | } else {
769 | }
770 | });
771 |
772 | // Remove Card & its Contents
773 |
774 | function removeCards(cardid) {
775 | console.log("removeitem");
776 | chrome.storage.local.get([carddb], function (storage) {
777 | var siteList = storage[carddb];
778 | console.log(siteList);
779 | var siteList = $.grep(siteList, function (e) {
780 | // console.log(e.id);
781 | return e.cid != cardid;
782 | });
783 | console.log(siteList);
784 | // tasksList = storage[dbName];
785 | // tasksList.splice(itemIndex, 1);
786 | // console.log("new list", tasksList);
787 |
788 | chrome.storage.local.set({ [carddb]: siteList }, function () {
789 | console.log(siteList);
790 | $('.js__bookmark_card[data-card="' + cardid + '"]').remove();
791 | setUnsavedChanges();
792 | });
793 | });
794 | }
795 |
796 | // RENAME CARD LABEL
797 |
798 | $("#bookmark_cards").on("click", ".js__rename_card", function (e) {
799 | var $closestcard = $(this).closest(".js__bookmark_card");
800 | $closestcard.find(".js__card_title_text").addClass("hidden");
801 | $closestcard.find(".js__card_title_input").removeClass("hidden").focus();
802 | });
803 |
804 | $("#bookmark_cards").on("click", ".js__card_title_text", function (e) {
805 | var $closestcard = $(this).closest(".js__bookmark_card");
806 | $closestcard.find(".js__card_title_text").addClass("hidden");
807 | $closestcard.find(".js__card_title_input").removeClass("hidden").focus();
808 | });
809 |
810 | $("#bookmark_cards").on("keypress", ".js__card_title_input", function (e) {
811 | var cardtitle = $(this).val();
812 | var curcardval = $(this).next(".js__card_title_text").text();
813 | var catid = $(this).closest(".js__bookmark_card").data("card");
814 | if (e.which == 13 && cardtitle !== "") {
815 | e.preventDefault();
816 | if (curcardval !== cardtitle) {
817 | changeCardTitle(cardtitle, catid);
818 | console.log(cardtitle);
819 | }
820 | $(this).addClass("hidden");
821 | $(this)
822 | .next(".js__card_title_text")
823 | .text(cardtitle)
824 | .removeClass("hidden");
825 | }
826 | });
827 |
828 | $("#bookmark_cards").on("blur", ".js__card_title_input", function (e) {
829 | var cardtitle = $(this).val();
830 | var curcardval = $(this).next(".js__card_title_text").text();
831 | var catid = $(this).closest(".js__bookmark_card").data("card");
832 | if (curcardval !== cardtitle) {
833 | changeCardTitle(cardtitle, catid);
834 | console.log(cardtitle);
835 | }
836 | $(this).addClass("hidden");
837 | $(this).next(".js__card_title_text").text(cardtitle).removeClass("hidden");
838 | });
839 |
840 | // $("#bookmark_cards").on("blur", ".js__card_title_input", function (e) {
841 | // $(this).addClass("hidden");
842 | // $(this).next(".js__card_title_text").removeClass("hidden");
843 | // });
844 |
845 | function changeCardTitle(cardtitle, catid) {
846 | console.log("cardtitle: " + cardtitle);
847 |
848 | chrome.storage.local.get([carddb], function (storage) {
849 | var siteList = storage[carddb];
850 |
851 | for (let key in siteList) {
852 | if (siteList.hasOwnProperty(key)) {
853 | if (catid === siteList[key].cid) {
854 | if (cardtitle === siteList[key].label) {
855 | // do nothing
856 | } else {
857 | siteList[key].label = cardtitle;
858 | }
859 | break;
860 | }
861 | }
862 | }
863 |
864 | chrome.storage.local.set({ [carddb]: siteList }, function () {
865 | console.log(siteList);
866 | setUnsavedChanges();
867 | });
868 | });
869 | }
870 |
871 | /*
872 | * -----------------------------------------------------------------------------------
873 | * // Star a Card
874 | * -----------------------------------------------------------------------------------
875 | */
876 |
877 | $("#bookmark_cards").on("click", ".js__star_card", function (e) {
878 | e.preventDefault();
879 | var $closestcard = $(this).closest(".js__bookmark_card");
880 | var starred = $closestcard.attr("data-star");
881 | var catid = $closestcard.data("card");
882 | starredCard(starred, catid);
883 | if (starred !== "false") {
884 | $(this).find("span").addClass("hidden");
885 | $(this).find(".hook_star").removeClass("hidden");
886 | $closestcard.removeClass("starred border-t-4 border-red-300");
887 | $closestcard.attr("data-star", false);
888 | } else if (starred !== "true") {
889 | $(this).find("span").addClass("hidden");
890 | $(this).find(".hook_unstar").removeClass("hidden");
891 | $closestcard.addClass("starred border-t-4 border-red-300");
892 | $closestcard.attr("data-star", true);
893 | }
894 | // return;
895 | // console.log(starred);
896 | });
897 |
898 | function starredCard(starred, catid) {
899 | console.log("starring ");
900 | console.log(starred);
901 | chrome.storage.local.get([carddb], function (storage) {
902 | var siteList = storage[carddb];
903 |
904 | for (let key in siteList) {
905 | if (siteList.hasOwnProperty(key)) {
906 | if (catid === siteList[key].cid) {
907 | if (siteList[key].starred === true) {
908 | siteList[key].starred = false;
909 | } else {
910 | siteList[key].starred = true;
911 | }
912 | break;
913 | }
914 | }
915 | }
916 |
917 | chrome.storage.local.set({ [carddb]: siteList }, function () {
918 | console.log(siteList);
919 | setUnsavedChanges();
920 | });
921 | });
922 | }
923 |
924 | // Search Bookmarks
925 |
926 | function searchWebsites() {
927 | var $input = $("input[name='search']"),
928 | $context = $("#bookmark_cards");
929 | $input.on("input", function () {
930 | var term = $(this).val();
931 | console.log($context);
932 | $context.find(".js__bookmark_card .item").show().unmark();
933 | $context.find(".js__bookmark_card").show().unmark();
934 | $context.find(".js__bookmark_card").removeClass("category-matched");
935 | if (term) {
936 | $context.mark(term, {
937 | done: function () {
938 | const promise1 = new Promise((resolve, reject) => {
939 | $context
940 | .find(".js__bookmark_card .header p")
941 | .find("mark")
942 | .closest(".js__bookmark_card")
943 | .addClass("category-matched");
944 | resolve();
945 | });
946 |
947 | promise1.then(() => {
948 | $context
949 | .find(".js__bookmark_card:not(.category-matched)")
950 | .find(".item")
951 | .not(":has(mark)")
952 | .hide();
953 | console.log("i;m workin");
954 | // expected output: "Success!"
955 | });
956 |
957 | $context.find(".js__bookmark_card").not(":has(mark)").hide();
958 |
959 | // $context.not(":has(mark)").hide();
960 | },
961 | });
962 | }
963 | });
964 | }
965 |
966 | searchWebsites();
967 |
968 | // SORT or RE-ORDER CARDS
969 |
970 | //const event1 = { newIndex: 1, oldIndex: 0 };
971 | //var originalArray;
972 |
973 | function sortSiteCards(newindex, oldindex) {
974 | chrome.storage.local.get([carddb], function (storage) {
975 | const originalArray = storage[carddb];
976 | const event1 = { newIndex: newindex, oldIndex: oldindex };
977 | console.log(originalArray);
978 | var newCardorder = reorderArray(event1, originalArray);
979 | chrome.storage.local.set({ [carddb]: newCardorder }, function () {
980 | console.log(newCardorder);
981 | setUnsavedChanges();
982 | });
983 | });
984 | }
985 |
986 | const reorderArray = (event, originalArray) => {
987 | const movedItem = originalArray.filter(
988 | (item, index) => index === event.oldIndex
989 | );
990 | const remainingItems = originalArray.filter(
991 | (item, index) => index !== event.oldIndex
992 | );
993 |
994 | const reorderedItems = [
995 | ...remainingItems.slice(0, event.newIndex),
996 | movedItem[0],
997 | ...remainingItems.slice(event.newIndex),
998 | ];
999 |
1000 | return reorderedItems;
1001 | };
1002 |
1003 | var el = document.getElementById("bookmark_cards");
1004 | var sortable = Sortable.create(el, {
1005 | draggable: ".js__bookmark_card",
1006 | filter: ".card__actions, .js__card_title_input",
1007 | preventOnFilter: false,
1008 | animation: 150,
1009 | ghostClass: "card__is__dragging",
1010 | forceFallback: true,
1011 | onEnd: function (/**Event*/ evt) {
1012 | console.log("oldIndex:" + (evt.oldIndex - 1));
1013 | console.log("newidex:" + (evt.newIndex - 1));
1014 | var newIndex = evt.newIndex - 1;
1015 | var oldIndex = evt.oldIndex - 1;
1016 | sortSiteCards(newIndex, oldIndex);
1017 | // same properties as onEnd
1018 | },
1019 | });
1020 |
1021 | // wait for some time to dynamically load content
1022 | setTimeout(() => {
1023 | //Select our child group and make sortable
1024 | var child = document.getElementsByClassName("js_content");
1025 | for (var i = 0; i < child.length; i++) {
1026 | // console.log(child[i]);
1027 | new Sortable(child[i], {
1028 | group: {
1029 | name: "shared",
1030 | pull: true,
1031 | },
1032 | ghostClass: "site__is__dragging",
1033 | animation: 150,
1034 | forceFallback: true,
1035 | fallbackClass: "clone_card",
1036 | onStart: function (evt) {
1037 | $(".js_content").addClass("disable__hover");
1038 | },
1039 | onEnd: function (evt) {
1040 | $(".js_content").removeClass("disable__hover");
1041 | console.log(evt);
1042 | console.log($(evt.to).closest(".js__bookmark_card").data("card"));
1043 | console.log("newidex:" + evt.oldIndex);
1044 | console.log("newidex:" + evt.newIndex);
1045 | },
1046 | });
1047 | }
1048 | }, 2000);
1049 |
1050 | // new Sortable(item, {
1051 | // group: "shared",
1052 | // animation: 150,
1053 | // });
1054 |
1055 | /*
1056 | * FILTER Bookmark Cards by Starred or Show All
1057 | */
1058 |
1059 | $("#filter__site_cards button").on("click", function () {
1060 | // do
1061 | if ($(this).is("#filter__by_starred")) {
1062 | $(".js__bookmark_card:not(.starred)").addClass("hidden");
1063 | $("#filter__site_cards button").removeClass("toggle__active");
1064 | $(this).addClass("toggle__active");
1065 | } else {
1066 | $(".js__bookmark_card").removeClass("hidden");
1067 | $("#filter__site_cards button").removeClass("toggle__active");
1068 | $(this).addClass("toggle__active");
1069 | }
1070 | });
1071 |
1072 | // Process Current Chrome Bookmarks as Folder
1073 | // Todo for later
1074 |
1075 | function process_bookmark(bookmarks, folder) {
1076 | console.log(bookmarks);
1077 | for (var i = 0; i < bookmarks.length; i++) {
1078 | var bookmark = bookmarks[i];
1079 | if (bookmark.url) {
1080 | console.log(
1081 | "bookmark: " +
1082 | folder +
1083 | " = " +
1084 | bookmark.title +
1085 | " ~ " +
1086 | bookmark.url
1087 | );
1088 | }
1089 |
1090 | if (bookmark.children) {
1091 | process_bookmark(bookmark.children, bookmark.title);
1092 | }
1093 | }
1094 | }
1095 |
1096 | // chrome.bookmarks.getTree(process_bookmark);
1097 |
1098 | // process bookmarke
1099 | })();
1100 |
--------------------------------------------------------------------------------
/static/js/mark.min.js:
--------------------------------------------------------------------------------
1 | /*!***************************************************
2 | * mark.js v9.0.0
3 | * https://markjs.io/
4 | * Copyright (c) 2014–2018, Julian Kühnel
5 | * Released under the MIT license https://git.io/vwTVl
6 | *****************************************************/
7 | !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("jquery")):"function"==typeof define&&define.amd?define(["jquery"],t):e.Mark=t(e.jQuery)}(this,function(e){"use strict";function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function r(e,t){for(var n=0;n1&&void 0!==arguments[1])||arguments[1],o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:5e3;n(this,e),this.ctx=t,this.iframes=r,this.exclude=o,this.iframesTimeout=i}return o(e,[{key:"getContexts",value:function(){var e=[];return(void 0!==this.ctx&&this.ctx?NodeList.prototype.isPrototypeOf(this.ctx)?Array.prototype.slice.call(this.ctx):Array.isArray(this.ctx)?this.ctx:"string"==typeof this.ctx?Array.prototype.slice.call(document.querySelectorAll(this.ctx)):[this.ctx]:[]).forEach(function(t){var n=e.filter(function(e){return e.contains(t)}).length>0;-1!==e.indexOf(t)||n||e.push(t)}),e}},{key:"getIframeContents",value:function(e,t){var n,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(){};try{var o=e.contentWindow;if(n=o.document,!o||!n)throw new Error("iframe inaccessible")}catch(e){r()}n&&t(n)}},{key:"isIframeBlank",value:function(e){var t="about:blank",n=e.getAttribute("src").trim();return e.contentWindow.location.href===t&&n!==t&&n}},{key:"observeIframeLoad",value:function(e,t,n){var r=this,o=!1,i=null,a=function a(){if(!o){o=!0,clearTimeout(i);try{r.isIframeBlank(e)||(e.removeEventListener("load",a),r.getIframeContents(e,t,n))}catch(e){n()}}};e.addEventListener("load",a),i=setTimeout(a,this.iframesTimeout)}},{key:"onIframeReady",value:function(e,t,n){try{"complete"===e.contentWindow.document.readyState?this.isIframeBlank(e)?this.observeIframeLoad(e,t,n):this.getIframeContents(e,t,n):this.observeIframeLoad(e,t,n)}catch(e){n()}}},{key:"waitForIframes",value:function(e,t){var n=this,r=0;this.forEachIframe(e,function(){return!0},function(e){r++,n.waitForIframes(e.querySelector("html"),function(){--r||t()})},function(e){e||t()})}},{key:"forEachIframe",value:function(t,n,r){var o=this,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:function(){},a=t.querySelectorAll("iframe"),s=a.length,c=0;a=Array.prototype.slice.call(a);var u=function(){--s<=0&&i(c)};s||u(),a.forEach(function(t){e.matches(t,o.exclude)?u():o.onIframeReady(t,function(e){n(t)&&(c++,r(e)),u()},u)})}},{key:"createIterator",value:function(e,t,n){return document.createNodeIterator(e,t,n,!1)}},{key:"createInstanceOnIframe",value:function(t){return new e(t.querySelector("html"),this.iframes)}},{key:"compareNodeIframe",value:function(e,t,n){if(e.compareDocumentPosition(n)&Node.DOCUMENT_POSITION_PRECEDING){if(null===t)return!0;if(t.compareDocumentPosition(n)&Node.DOCUMENT_POSITION_FOLLOWING)return!0}return!1}},{key:"getIteratorNode",value:function(e){var t=e.previousNode();return{prevNode:t,node:null===t?e.nextNode():e.nextNode()&&e.nextNode()}}},{key:"checkIframeFilter",value:function(e,t,n,r){var o=!1,i=!1;return r.forEach(function(e,t){e.val===n&&(o=t,i=e.handled)}),this.compareNodeIframe(e,t,n)?(!1!==o||i?!1===o||i||(r[o].handled=!0):r.push({val:n,handled:!0}),!0):(!1===o&&r.push({val:n,handled:!1}),!1)}},{key:"handleOpenIframes",value:function(e,t,n,r){var o=this;e.forEach(function(e){e.handled||o.getIframeContents(e.val,function(e){o.createInstanceOnIframe(e).forEachNode(t,n,r)})})}},{key:"iterateThroughNodes",value:function(e,t,n,r,o){for(var i,a,s,c=this,u=this.createIterator(t,e,r),l=[],h=[];s=void 0,s=c.getIteratorNode(u),a=s.prevNode,i=s.node;)this.iframes&&this.forEachIframe(t,function(e){return c.checkIframeFilter(i,a,e,l)},function(t){c.createInstanceOnIframe(t).forEachNode(e,function(e){return h.push(e)},r)}),h.push(i);h.forEach(function(e){n(e)}),this.iframes&&this.handleOpenIframes(l,e,n,r),o()}},{key:"forEachNode",value:function(e,t,n){var r=this,o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:function(){},i=this.getContexts(),a=i.length;a||o(),i.forEach(function(i){var s=function(){r.iterateThroughNodes(e,i,t,n,function(){--a<=0&&o()})};r.iframes?r.waitForIframes(i,s):s()})}}],[{key:"matches",value:function(e,t){var n="string"==typeof t?[t]:t,r=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.oMatchesSelector||e.webkitMatchesSelector;if(r){var o=!1;return n.every(function(t){return!r.call(e,t)||(o=!0,!1)}),o}return!1}}]),e}(),s=
10 | /* */
11 | function(){function e(t){n(this,e),this.opt=i({},{diacritics:!0,synonyms:{},accuracy:"partially",caseSensitive:!1,ignoreJoiners:!1,ignorePunctuation:[],wildcards:"disabled"},t)}return o(e,[{key:"create",value:function(e){return"disabled"!==this.opt.wildcards&&(e=this.setupWildcardsRegExp(e)),e=this.escapeStr(e),Object.keys(this.opt.synonyms).length&&(e=this.createSynonymsRegExp(e)),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),this.opt.diacritics&&(e=this.createDiacriticsRegExp(e)),e=this.createMergedBlanksRegExp(e),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.createJoinersRegExp(e)),"disabled"!==this.opt.wildcards&&(e=this.createWildcardsRegExp(e)),e=this.createAccuracyRegExp(e),new RegExp(e,"gm".concat(this.opt.caseSensitive?"":"i"))}},{key:"sortByLength",value:function(e){return e.sort(function(e,t){return e.length===t.length?e>t?1:-1:t.length-e.length})}},{key:"escapeStr",value:function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}},{key:"createSynonymsRegExp",value:function(e){var t=this,n=this.opt.synonyms,r=this.opt.caseSensitive?"":"i",o=this.opt.ignoreJoiners||this.opt.ignorePunctuation.length?"\0":"";for(var i in n)if(n.hasOwnProperty(i)){var a=Array.isArray(n[i])?n[i]:[n[i]];a.unshift(i),(a=this.sortByLength(a).map(function(e){return"disabled"!==t.opt.wildcards&&(e=t.setupWildcardsRegExp(e)),e=t.escapeStr(e)}).filter(function(e){return""!==e})).length>1&&(e=e.replace(new RegExp("(".concat(a.map(function(e){return t.escapeStr(e)}).join("|"),")"),"gm".concat(r)),o+"(".concat(a.map(function(e){return t.processSynonyms(e)}).join("|"),")")+o))}return e}},{key:"processSynonyms",value:function(e){return(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),e}},{key:"setupWildcardsRegExp",value:function(e){return(e=e.replace(/(?:\\)*\?/g,function(e){return"\\"===e.charAt(0)?"?":""})).replace(/(?:\\)*\*/g,function(e){return"\\"===e.charAt(0)?"*":""})}},{key:"createWildcardsRegExp",value:function(e){var t="withSpaces"===this.opt.wildcards;return e.replace(/\u0001/g,t?"[\\S\\s]?":"\\S?").replace(/\u0002/g,t?"[\\S\\s]*?":"\\S*")}},{key:"setupIgnoreJoinersRegExp",value:function(e){return e.replace(/[^(|)\\]/g,function(e,t,n){var r=n.charAt(t+1);return/[(|)\\]/.test(r)||""===r?e:e+"\0"})}},{key:"createJoinersRegExp",value:function(e){var t=[],n=this.opt.ignorePunctuation;return Array.isArray(n)&&n.length&&t.push(this.escapeStr(n.join(""))),this.opt.ignoreJoiners&&t.push("\\u00ad\\u200b\\u200c\\u200d"),t.length?e.split(/\u0000+/).join("[".concat(t.join(""),"]*")):e}},{key:"createDiacriticsRegExp",value:function(e){var t=this.opt.caseSensitive?"":"i",n=this.opt.caseSensitive?["aàáảãạăằắẳẵặâầấẩẫậäåāą","AÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ","cçćč","CÇĆČ","dđď","DĐĎ","eèéẻẽẹêềếểễệëěēę","EÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ","iìíỉĩịîïī","IÌÍỈĨỊÎÏĪ","lł","LŁ","nñňń","NÑŇŃ","oòóỏõọôồốổỗộơởỡớờợöøō","OÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ","rř","RŘ","sšśșş","SŠŚȘŞ","tťțţ","TŤȚŢ","uùúủũụưừứửữựûüůū","UÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ","yýỳỷỹỵÿ","YÝỲỶỸỴŸ","zžżź","ZŽŻŹ"]:["aàáảãạăằắẳẵặâầấẩẫậäåāąAÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ","cçćčCÇĆČ","dđďDĐĎ","eèéẻẽẹêềếểễệëěēęEÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ","iìíỉĩịîïīIÌÍỈĨỊÎÏĪ","lłLŁ","nñňńNÑŇŃ","oòóỏõọôồốổỗộơởỡớờợöøōOÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ","rřRŘ","sšśșşSŠŚȘŞ","tťțţTŤȚŢ","uùúủũụưừứửữựûüůūUÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ","yýỳỷỹỵÿYÝỲỶỸỴŸ","zžżźZŽŻŹ"],r=[];return e.split("").forEach(function(o){n.every(function(n){if(-1!==n.indexOf(o)){if(r.indexOf(n)>-1)return!1;e=e.replace(new RegExp("[".concat(n,"]"),"gm".concat(t)),"[".concat(n,"]")),r.push(n)}return!0})}),e}},{key:"createMergedBlanksRegExp",value:function(e){return e.replace(/[\s]+/gim,"[\\s]+")}},{key:"createAccuracyRegExp",value:function(e){var t=this,n=this.opt.accuracy,r="string"==typeof n?n:n.value,o="string"==typeof n?[]:n.limiters,i="";switch(o.forEach(function(e){i+="|".concat(t.escapeStr(e))}),r){case"partially":default:return"()(".concat(e,")");case"complementary":return i="\\s"+(i||this.escapeStr("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~¡¿")),"()([^".concat(i,"]*").concat(e,"[^").concat(i,"]*)");case"exactly":return"(^|\\s".concat(i,")(").concat(e,")(?=$|\\s").concat(i,")")}}}]),e}(),c=
12 | /* */
13 | function(){function e(t){n(this,e),this.ctx=t,this.ie=!1;var r=window.navigator.userAgent;(r.indexOf("MSIE")>-1||r.indexOf("Trident")>-1)&&(this.ie=!0)}return o(e,[{key:"log",value:function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"debug",r=this.opt.log;this.opt.debug&&"object"===t(r)&&"function"==typeof r[n]&&r[n]("mark.js: ".concat(e))}},{key:"getSeparatedKeywords",value:function(e){var t=this,n=[];return e.forEach(function(e){t.opt.separateWordSearch?e.split(" ").forEach(function(e){e.trim()&&-1===n.indexOf(e)&&n.push(e)}):e.trim()&&-1===n.indexOf(e)&&n.push(e)}),{keywords:n.sort(function(e,t){return t.length-e.length}),length:n.length}}},{key:"isNumeric",value:function(e){return Number(parseFloat(e))==e}},{key:"checkRanges",value:function(e){var t=this;if(!Array.isArray(e)||"[object Object]"!==Object.prototype.toString.call(e[0]))return this.log("markRanges() will only accept an array of objects"),this.opt.noMatch(e),[];var n=[],r=0;return e.sort(function(e,t){return e.start-t.start}).forEach(function(e){var o=t.callNoMatchOnInvalidRanges(e,r),i=o.start,a=o.end;o.valid&&(e.start=i,e.length=a-i,n.push(e),r=a)}),n}},{key:"callNoMatchOnInvalidRanges",value:function(e,t){var n,r,o=!1;return e&&void 0!==e.start?(r=(n=parseInt(e.start,10))+parseInt(e.length,10),this.isNumeric(e.start)&&this.isNumeric(e.length)&&r-t>0&&r-n>0?o=!0:(this.log("Ignoring invalid or overlapping range: "+"".concat(JSON.stringify(e))),this.opt.noMatch(e))):(this.log("Ignoring invalid range: ".concat(JSON.stringify(e))),this.opt.noMatch(e)),{start:n,end:r,valid:o}}},{key:"checkWhitespaceRanges",value:function(e,t,n){var r,o=!0,i=n.length,a=t-i,s=parseInt(e.start,10)-a;return(r=(s=s>i?i:s)+parseInt(e.length,10))>i&&(r=i,this.log("End range automatically set to the max value of ".concat(i))),s<0||r-s<0||s>i||r>i?(o=!1,this.log("Invalid range: ".concat(JSON.stringify(e))),this.opt.noMatch(e)):""===n.substring(s,r).replace(/\s+/g,"")&&(o=!1,this.log("Skipping whitespace only range: "+JSON.stringify(e)),this.opt.noMatch(e)),{start:s,end:r,valid:o}}},{key:"getTextNodes",value:function(e){var t=this,n="",r=[];this.iterator.forEachNode(NodeFilter.SHOW_TEXT,function(e){r.push({start:n.length,end:(n+=e.textContent).length,node:e})},function(e){return t.matchesExclude(e.parentNode)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT},function(){e({value:n,nodes:r})})}},{key:"matchesExclude",value:function(e){return a.matches(e,this.opt.exclude.concat(["script","style","title","head","html"]))}},{key:"wrapRangeInTextNode",value:function(e,t,n){var r=this.opt.element?this.opt.element:"mark",o=e.splitText(t),i=o.splitText(n-t),a=document.createElement(r);return a.setAttribute("data-markjs","true"),this.opt.className&&a.setAttribute("class",this.opt.className),a.textContent=o.textContent,o.parentNode.replaceChild(a,o),i}},{key:"wrapRangeInMappedTextNode",value:function(e,t,n,r,o){var i=this;e.nodes.every(function(a,s){var c=e.nodes[s+1];if(void 0===c||c.start>t){if(!r(a.node))return!1;var u=t-a.start,l=(n>a.end?a.end:n)-a.start,h=e.value.substr(0,a.start),f=e.value.substr(l+a.start);if(a.node=i.wrapRangeInTextNode(a.node,u,l),e.value=h+f,e.nodes.forEach(function(t,n){n>=s&&(e.nodes[n].start>0&&n!==s&&(e.nodes[n].start-=l),e.nodes[n].end-=l)}),n-=l,o(a.node.previousSibling,a.start),!(n>a.end))return!1;t=a.end}return!0})}},{key:"wrapGroups",value:function(e,t,n,r){return r((e=this.wrapRangeInTextNode(e,t,t+n)).previousSibling),e}},{key:"separateGroups",value:function(e,t,n,r,o){for(var i=t.length,a=1;a-1&&r(t[a],e)&&(e=this.wrapGroups(e,s,t[a].length,o))}return e}},{key:"wrapMatches",value:function(e,t,n,r,o){var i=this,a=0===t?0:t+1;this.getTextNodes(function(t){t.nodes.forEach(function(t){var o;for(t=t.node;null!==(o=e.exec(t.textContent))&&""!==o[a];){if(i.opt.separateGroups)t=i.separateGroups(t,o,a,n,r);else{if(!n(o[a],t))continue;var s=o.index;if(0!==a)for(var c=1;c= 1) {
16 | intervalType = "year";
17 | } else {
18 | interval = Math.floor(seconds / 2592000);
19 | if (interval >= 1) {
20 | intervalType = "month";
21 | } else {
22 | interval = Math.floor(seconds / 86400);
23 | if (interval >= 1) {
24 | intervalType = "day";
25 | } else {
26 | interval = Math.floor(seconds / 3600);
27 | if (interval >= 1) {
28 | intervalType = "hour";
29 | } else {
30 | interval = Math.floor(seconds / 60);
31 | if (interval >= 1) {
32 | intervalType = "minute";
33 | } else {
34 | interval = interval;
35 | if (interval < 5) {
36 | interval = "few";
37 | intervalType = "second";
38 | } else {
39 | interval = interval;
40 | intervalType = "second";
41 | }
42 | }
43 | }
44 | }
45 | }
46 | }
47 |
48 | if (interval > 1 || interval === 0 || interval === "few") {
49 | intervalType += "s";
50 | }
51 |
52 | return interval + " " + intervalType;
53 | };
54 |
55 | var dbName = "settings";
56 | var settings = new Array();
57 | chrome.storage.local.get(dbName, function (storage) {
58 | if (dbName in storage) {
59 | settings = storage[dbName];
60 | var preftab = settings[0].defaultTab;
61 | // $("#b_loader").hide();
62 |
63 | // Fill Default Settings Value from Storage
64 | if (settings[0].git_token) $("#g__token").val(settings[0].git_token);
65 | if (settings[0].git_public)
66 | $("#g__public").prop("checked", settings[0].git_public);
67 | if (settings[0].last_sync)
68 | $("#last_sync_info").text(
69 | "Last Synced " + timeSince(new Date(settings[0].last_sync)) + " ago"
70 | );
71 | if (settings[0].gist_id) {
72 | $("#g__id")
73 | .val(settings[0].gist_id)
74 | .closest(".hidden")
75 | .removeClass("hidden");
76 | $("#g__public").prop("disabled", true);
77 | }
78 | } else {
79 | storage = {};
80 | storage[dbName] = [
81 | {
82 | defaultTab: "tasks",
83 | git_public: true,
84 | },
85 | ];
86 | chrome.storage.local.set(
87 | storage,
88 | function () {
89 | // console.log("storage");
90 | // console.log(storage);
91 | // var preftab = settings.defaultTab;
92 | // console.log(preftab);
93 | // setDefaultView(preftab);
94 | }.bind(this)
95 | );
96 | // console.log("First Settings");
97 | settings = storage[dbName];
98 | preftab = settings[0].defaultTab;
99 | // console.log(preftab);
100 | // setDefaultView(preftab);
101 | // $("#b_loader").hide();
102 | }
103 | setDefaultView(preftab);
104 | });
105 |
106 | $("#g__token").on("keyup change paste input", function (e) {
107 | //console.log(this.value);
108 | if (this.value != "") {
109 | const new_token = this.value;
110 | chrome.storage.local.get(dbName, function (storage) {
111 | if (dbName in storage) {
112 | settings = storage[dbName];
113 | //console.log("keeeeee" + storage[dbName].git_token);
114 |
115 | for (let key in settings) {
116 | if (settings.hasOwnProperty(key)) {
117 | settings[key].git_token = new_token;
118 | }
119 | }
120 |
121 | chrome.storage.local.set(storage, function () {}.bind(this));
122 | }
123 | });
124 | }
125 | });
126 |
127 | $("#g__public").on("change", function () {
128 | var ischecked = $(this).is(":checked");
129 |
130 | chrome.storage.local.get(dbName, function (storage) {
131 | if (dbName in storage) {
132 | settings = storage[dbName];
133 | //console.log("keeeeee" + storage[dbName].git_token);
134 |
135 | for (let key in settings) {
136 | if (settings.hasOwnProperty(key)) {
137 | if (!ischecked) {
138 | settings[key].git_public = false;
139 | } else {
140 | settings[key].git_public = true;
141 | }
142 | }
143 | }
144 |
145 | chrome.storage.local.set(storage, function () {}.bind(this));
146 | }
147 | });
148 | });
149 |
150 | $("#g__syncData").on("click", function (e) {
151 | e.preventDefault();
152 | $("#last_sync_info").text("Syncing...");
153 | exportToGithub();
154 | });
155 |
156 | $("#delete__existing_gist").on("click", function (e) {
157 | e.preventDefault();
158 |
159 | if (
160 | confirm(
161 | "Are you sure you want to delete this GIST ID?\nIt will not delete from Github.\nWe will create a new GIST next time you sync."
162 | )
163 | ) {
164 | chrome.storage.local.get(dbName, function (storage) {
165 | if (dbName in storage) {
166 | settings = storage[dbName];
167 | //console.log("keeeeee" + storage[dbName].git_token);
168 |
169 | for (let key in settings) {
170 | if (settings.hasOwnProperty(key)) {
171 | settings[key].gist_id = "";
172 | }
173 | }
174 |
175 | chrome.storage.local.set(
176 | storage,
177 | function () {
178 | $("#g__id").val("");
179 |
180 | $("#g__public").prop("disabled", false);
181 | }.bind(this)
182 | );
183 | }
184 | });
185 | } else {
186 | }
187 | });
188 |
189 | function setDefaultView(preftab) {
190 | if (preftab == "tasks") {
191 | $("#tasks").addClass("active").removeClass("hidden");
192 | $("#bookmarks").addClass("hidden").removeClass("active");
193 | } else {
194 | $("#bookmarks").addClass("active").removeClass("hidden");
195 | $("#tasks").addClass("hidden").removeClass("active");
196 | }
197 | $('#defaultViewToggle span[data-pref="' + preftab + '"]').removeClass(
198 | "hidden"
199 | );
200 | }
201 |
202 | function changeDefaultView(preftab) {
203 | console.log("update");
204 | chrome.storage.local.get([dbName], function (storage) {
205 | var settings = storage[dbName];
206 |
207 | for (let key in settings) {
208 | if (settings.hasOwnProperty(key)) {
209 | if (preftab != settings[key].defaultTab) {
210 | settings[key].defaultTab = preftab;
211 | break;
212 | }
213 | }
214 | }
215 |
216 | chrome.storage.local.set({ [dbName]: settings }, function () {
217 | //console.log(settings);
218 | setDefaultView(preftab);
219 | });
220 | });
221 | }
222 |
223 | $("#defaultViewToggle").on("click", function (e) {
224 | e.preventDefault();
225 | $("span", this).toggleClass("hidden");
226 | var preftab = $("span:not(.hidden)", this).data("pref");
227 | //console.log(preftab);
228 | changeDefaultView(preftab);
229 | });
230 |
231 | /*
232 | *
233 | * Download Data as JSON
234 | *
235 | */
236 |
237 | $("#download__as_json").on("click", function (e) {
238 | chrome.storage.local.get(null, function (storage) {
239 | let e = document.createElement("a");
240 | e.setAttribute(
241 | "href",
242 | `data:application/json;charset=utf-8,${escape(JSON.stringify(storage))}`
243 | );
244 | e.setAttribute("download", `mission_backup_${Date.now()}.json`);
245 | e.click();
246 |
247 | // e.stopPropagation();
248 | });
249 | });
250 | /*
251 | *
252 | * Open Settings Page
253 | *
254 | */
255 |
256 | function showSettings() {
257 | if ($(this).hasClass("settings__is_open")) {
258 | $("#tasks.active, #bookmarks.active").removeClass("hidden");
259 | $(this).removeClass("settings__is_open");
260 | $("#settings").addClass("hidden");
261 | $("#defaultViewToggle").show();
262 | } else {
263 | $("#tasks, #bookmarks").addClass("hidden");
264 | $(this).addClass("settings__is_open");
265 | $("#settings").removeClass("hidden");
266 | $("#defaultViewToggle").hide();
267 | }
268 | }
269 |
270 | $("#showSettings").on("click", showSettings);
271 |
272 | /*
273 | *
274 | * Import from Github Backup
275 | *
276 | */
277 |
278 | $("#importBackupTrigger").on("click", function (e) {
279 | e.preventDefault();
280 | $("#importbackupBlock").toggleClass("hidden");
281 | $("#gist_block").addClass("hidden");
282 | });
283 |
284 | $("#g__importData").on("click", doubleCheckImport);
285 |
286 | function doubleCheckImport() {
287 | if (
288 | confirm(
289 | "Are you sure you want to import?\nThis will delete all existing content in your system.\nYou cannot UNDO this action."
290 | )
291 | ) {
292 | importToGithub();
293 | } else {
294 | // do nothing
295 | }
296 | }
297 |
298 | function importToGithub() {
299 | chrome.storage.local.get(null, function (storage) {
300 | settings = storage[dbName];
301 | const gittoken = settings[0].git_token;
302 | const gist_id = $("#ex-g__id").val();
303 |
304 | if (gist_id && gittoken) {
305 | var ajaxsettings = {
306 | async: true,
307 | crossDomain: true,
308 | url: "https://api.github.com/gists/" + gist_id,
309 | method: "GET",
310 | headers: {
311 | Authorization: "Bearer " + gittoken,
312 | Accept: "application/vnd.github.v3+json",
313 | },
314 | processData: false,
315 | };
316 |
317 | $.ajax(ajaxsettings).done(function (response) {
318 | const backupdata = JSON.parse(
319 | response.files["mission_control_ext_bkp.json"].content
320 | );
321 |
322 | if (backupdata) {
323 | //const sitedata = backupdata.sites;
324 | // const tododata = backupdata.todo_list;
325 |
326 | storage["sites"] = backupdata.sites;
327 | storage["todo_list"] = backupdata.todo_list;
328 |
329 | console.log(storage);
330 |
331 | // console.log(backupdata, sitedata, tododata);
332 | for (let key in settings) {
333 | if (settings.hasOwnProperty(key)) {
334 | settings[key].gist_id = gist_id;
335 | }
336 | }
337 |
338 | chrome.storage.local.set(
339 | storage,
340 | function () {
341 | alert("Github Data succesfully imported! ");
342 | location.reload();
343 | }.bind(this)
344 | );
345 | } else {
346 | alert("we couldn't find your backup data");
347 | }
348 | });
349 | } else {
350 | alert("Please fill Github Token & Gist ID");
351 | }
352 | });
353 | }
354 |
355 | /*
356 | *
357 | * Export To Github Gists
358 | *
359 | */
360 |
361 | setInterval(() => {
362 | chrome.storage.local.get(null, function (storage) {
363 | const settings = storage["settings"];
364 | const unsaved_changes = settings[0].unsaved_changes;
365 | console.log("Unsaved: " + unsaved_changes);
366 | if (unsaved_changes) {
367 | console.log("running sync");
368 | //
369 | //const promise = await exportToGithub();
370 |
371 | exportToGithub().then(() => {
372 | console.log("value");
373 | // Adding settimeout here as a HACK
374 | // Something is overwriting the time. So this delay will avoid that
375 | // TODO: Fix later
376 | setTimeout(() => {
377 | chrome.storage.local.get(null, function (newstorage) {
378 | console.log("newstorage", newstorage);
379 | const newsettings = newstorage["settings"];
380 | console.log("newsettings", newsettings);
381 | // expected output: "Success!"
382 | for (let key in newsettings) {
383 | if (newsettings.hasOwnProperty(key)) {
384 | newsettings[key].unsaved_changes = false;
385 | }
386 | }
387 | chrome.storage.local.set({ settings: newsettings }, function () {
388 | // do nothing
389 | //console.log("done");
390 | });
391 | });
392 | }, 5000);
393 | });
394 | }
395 | });
396 | }, 60000);
397 |
398 | function exportToGithub() {
399 | return new Promise((resolve) => {
400 | chrome.storage.local.get(null, function (storage) {
401 | if (dbName in storage) {
402 | settings = storage[dbName];
403 | const gittoken = settings[0].git_token;
404 | const gist_id = settings[0].gist_id;
405 | const git_public = settings[0].git_public;
406 | const sitesTasksArray = Object.keys(storage).reduce((object, key) => {
407 | if (key !== dbName) {
408 | object[key] = storage[key];
409 | }
410 | return object;
411 | }, {});
412 |
413 | if (!gittoken) {
414 | return;
415 | }
416 |
417 | //console.log(sitesTasksArray);
418 |
419 | // const jsondata = escape(JSON.stringify(storage));
420 | // null , 4 used for formatting :)
421 | const jsondata = JSON.stringify(sitesTasksArray, null, 4);
422 | //console.log(JSON.parse(jsondata));
423 | const escapeJSON = function (str) {
424 | return str
425 | .replace(/\\/g, "\\\\")
426 | .replace(/"/g, '\\"')
427 | .replace(/\n/g, "\\n")
428 | .replace(/\r/g, "\\r")
429 | .replace(/\t/g, "\\t");
430 | };
431 | console.log(escapeJSON(jsondata));
432 | var ajsettings = {
433 | async: true,
434 | crossDomain: true,
435 | url: gist_id
436 | ? "https://api.github.com/gists/" + gist_id
437 | : "https://api.github.com/gists",
438 | method: "POST",
439 | headers: {
440 | Authorization: "Bearer " + gittoken,
441 | "content-type": "application/json;charset=utf-8",
442 | },
443 | processData: false,
444 | data: `{\r\n "description": "Mission Control Chrome Extension Backup Data",\r\n "public": "${git_public}",\r\n "files": {\r\n "mission_control_ext_bkp.json": {\r\n "content": "${escapeJSON(
445 | jsondata
446 | )}"\r\n }\r\n }\r\n }`,
447 | };
448 |
449 | $.ajax(ajsettings).done(function (response) {
450 | console.log(response);
451 |
452 | for (let key in settings) {
453 | if (settings.hasOwnProperty(key)) {
454 | settings[key].gist_id = response.id;
455 | settings[key].last_sync = response.updated_at;
456 | }
457 | }
458 | console.log(storage);
459 |
460 | chrome.storage.local.set(
461 | storage,
462 | function () {
463 | $("#last_sync_info").text(
464 | "Last Synced " +
465 | timeSince(new Date(storage.settings[0].last_sync)) +
466 | " ago"
467 | );
468 | resolve("resolved");
469 | }.bind(this)
470 | );
471 | });
472 | }
473 | });
474 | });
475 | }
476 | // make it work on click after getting API
477 | })();
478 |
--------------------------------------------------------------------------------
/static/js/sortable.min.js:
--------------------------------------------------------------------------------
1 | /*! Sortable 1.10.1 - MIT | git://github.com/SortableJS/Sortable.git */
2 | !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).Sortable=e()}(this,function(){"use strict";function o(t){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function a(){return(a=Object.assign||function(t){for(var e=1;e"===e[0]&&(e=e.substring(1)),t)try{if(t.matches)return t.matches(e);if(t.msMatchesSelector)return t.msMatchesSelector(e);if(t.webkitMatchesSelector)return t.webkitMatchesSelector(e)}catch(t){return!1}return!1}}function P(t,e,n,o){if(t){n=n||document;do{if(null!=e&&(">"===e[0]?t.parentNode===n&&h(t,e):h(t,e))||o&&t===n)return t;if(t===n)break}while(t=(i=t).host&&i!==document&&i.host.nodeType?i.host:i.parentNode)}var i;return null}var f,p=/\s+/g;function k(t,e,n){if(t&&e)if(t.classList)t.classList[n?"add":"remove"](e);else{var o=(" "+t.className+" ").replace(p," ").replace(" "+e+" "," ");t.className=(o+(n?" "+e:"")).replace(p," ")}}function R(t,e,n){var o=t&&t.style;if(o){if(void 0===n)return document.defaultView&&document.defaultView.getComputedStyle?n=document.defaultView.getComputedStyle(t,""):t.currentStyle&&(n=t.currentStyle),void 0===e?n:n[e];e in o||-1!==e.indexOf("webkit")||(e="-webkit-"+e),o[e]=n+("string"==typeof n?"":"px")}}function v(t,e){var n="";if("string"==typeof t)n=t;else do{var o=R(t,"transform");o&&"none"!==o&&(n=o+" "+n)}while(!e&&(t=t.parentNode));var i=window.DOMMatrix||window.WebKitCSSMatrix||window.CSSMatrix;return i&&new i(n)}function g(t,e,n){if(t){var o=t.getElementsByTagName(e),i=0,r=o.length;if(n)for(;i=e.left-n&&r<=e.right+n,i=a>=e.top-n&&a<=e.bottom+n;return n&&o&&i?l=t:void 0}}),l}((t=t.touches?t.touches[0]:t).clientX,t.clientY);if(e){var n={};for(var o in t)t.hasOwnProperty(o)&&(n[o]=t[o]);n.target=n.rootEl=e,n.preventDefault=void 0,n.stopPropagation=void 0,e[j]._onDragOver(n)}}}function kt(t){z&&z.parentNode[j]._isOutsideThisEl(t.target)}function Rt(t,e){if(!t||!t.nodeType||1!==t.nodeType)throw"Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(t));this.el=t,this.options=e=a({},e),t[j]=this;var n={group:null,sort:!0,disabled:!1,store:null,handle:null,draggable:/^[uo]l$/i.test(t.nodeName)?">li":">*",swapThreshold:1,invertSwap:!1,invertedSwapThreshold:null,removeCloneOnHide:!0,direction:function(){return Ot(t,this.options)},ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",dragClass:"sortable-drag",ignore:"a, img",filter:null,preventOnFilter:!0,animation:0,easing:null,setData:function(t,e){t.setData("Text",e.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,delayOnTouchOnly:!1,touchStartThreshold:(Number.parseInt?Number:window).parseInt(window.devicePixelRatio,10)||1,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1,fallbackTolerance:0,fallbackOffset:{x:0,y:0},supportPointer:!1!==Rt.supportPointer&&"PointerEvent"in window,emptyInsertThreshold:5};for(var o in O.initializePlugins(this,t,n),n)o in e||(e[o]=n[o]);for(var i in At(e),this)"_"===i.charAt(0)&&"function"==typeof this[i]&&(this[i]=this[i].bind(this));this.nativeDraggable=!e.forceFallback&&xt,this.nativeDraggable&&(this.options.touchStartThreshold=1),e.supportPointer?u(t,"pointerdown",this._onTapStart):(u(t,"mousedown",this._onTapStart),u(t,"touchstart",this._onTapStart)),this.nativeDraggable&&(u(t,"dragover",this),u(t,"dragenter",this)),bt.push(this.el),e.store&&e.store.get&&this.sort(e.store.get(this)||[]),a(this,T())}function Xt(t,e,n,o,i,r,a,l){var s,c,u=t[j],d=u.options.onMove;return!window.CustomEvent||w||E?(s=document.createEvent("Event")).initEvent("move",!0,!0):s=new CustomEvent("move",{bubbles:!0,cancelable:!0}),s.to=e,s.from=t,s.dragged=n,s.draggedRect=o,s.related=i||e,s.relatedRect=r||X(e),s.willInsertAfter=l,s.originalEvent=a,t.dispatchEvent(s),d&&(c=d.call(u,s,a)),c}function Yt(t){t.draggable=!1}function Bt(){Dt=!1}function Ft(t){for(var e=t.tagName+t.className+t.src+t.href+t.textContent,n=e.length,o=0;n--;)o+=e.charCodeAt(n);return o.toString(36)}function Ht(t){return setTimeout(t,0)}function Lt(t){return clearTimeout(t)}Rt.prototype={constructor:Rt,_isOutsideThisEl:function(t){this.el.contains(t)||t===this.el||(ht=null)},_getDirection:function(t,e){return"function"==typeof this.options.direction?this.options.direction.call(this,t,e,z):this.options.direction},_onTapStart:function(e){if(e.cancelable){var n=this,o=this.el,t=this.options,i=t.preventOnFilter,r=e.type,a=e.touches&&e.touches[0]||e.pointerType&&"touch"===e.pointerType&&e,l=(a||e).target,s=e.target.shadowRoot&&(e.path&&e.path[0]||e.composedPath&&e.composedPath()[0])||l,c=t.filter;if(function(t){_t.length=0;var e=t.getElementsByTagName("input"),n=e.length;for(;n--;){var o=e[n];o.checked&&_t.push(o)}}(o),!z&&!(/mousedown|pointerdown/.test(r)&&0!==e.button||t.disabled||s.isContentEditable||(l=P(l,t.draggable,o,!1))&&l.animated||Z===l)){if(J=F(l),et=F(l,t.draggable),"function"==typeof c){if(c.call(this,e,l,this))return W({sortable:n,rootEl:s,name:"filter",targetEl:l,toEl:o,fromEl:o}),K("filter",n,{evt:e}),void(i&&e.cancelable&&e.preventDefault())}else if(c&&(c=c.split(",").some(function(t){if(t=P(s,t.trim(),o,!1))return W({sortable:n,rootEl:t,name:"filter",targetEl:l,fromEl:o,toEl:o}),K("filter",n,{evt:e}),!0})))return void(i&&e.cancelable&&e.preventDefault());t.handle&&!P(s,t.handle,o,!1)||this._prepareDragStart(e,a,l)}}},_prepareDragStart:function(t,e,n){var o,i=this,r=i.el,a=i.options,l=r.ownerDocument;if(n&&!z&&n.parentNode===r){var s=X(n);if(q=r,G=(z=n).parentNode,V=z.nextSibling,Z=n,ot=a.group,rt={target:Rt.dragged=z,clientX:(e||t).clientX,clientY:(e||t).clientY},ct=rt.clientX-s.left,ut=rt.clientY-s.top,this._lastX=(e||t).clientX,this._lastY=(e||t).clientY,z.style["will-change"]="all",o=function(){K("delayEnded",i,{evt:t}),Rt.eventCanceled?i._onDrop():(i._disableDelayedDragEvents(),!c&&i.nativeDraggable&&(z.draggable=!0),i._triggerDragStart(t,e),W({sortable:i,name:"choose",originalEvent:t}),k(z,a.chosenClass,!0))},a.ignore.split(",").forEach(function(t){g(z,t.trim(),Yt)}),u(l,"dragover",Pt),u(l,"mousemove",Pt),u(l,"touchmove",Pt),u(l,"mouseup",i._onDrop),u(l,"touchend",i._onDrop),u(l,"touchcancel",i._onDrop),c&&this.nativeDraggable&&(this.options.touchStartThreshold=4,z.draggable=!0),K("delayStart",this,{evt:t}),!a.delay||a.delayOnTouchOnly&&!e||this.nativeDraggable&&(E||w))o();else{if(Rt.eventCanceled)return void this._onDrop();u(l,"mouseup",i._disableDelayedDrag),u(l,"touchend",i._disableDelayedDrag),u(l,"touchcancel",i._disableDelayedDrag),u(l,"mousemove",i._delayedDragTouchMoveHandler),u(l,"touchmove",i._delayedDragTouchMoveHandler),a.supportPointer&&u(l,"pointermove",i._delayedDragTouchMoveHandler),i._dragStartTimer=setTimeout(o,a.delay)}}},_delayedDragTouchMoveHandler:function(t){var e=t.touches?t.touches[0]:t;Math.max(Math.abs(e.clientX-this._lastX),Math.abs(e.clientY-this._lastY))>=Math.floor(this.options.touchStartThreshold/(this.nativeDraggable&&window.devicePixelRatio||1))&&this._disableDelayedDrag()},_disableDelayedDrag:function(){z&&Yt(z),clearTimeout(this._dragStartTimer),this._disableDelayedDragEvents()},_disableDelayedDragEvents:function(){var t=this.el.ownerDocument;d(t,"mouseup",this._disableDelayedDrag),d(t,"touchend",this._disableDelayedDrag),d(t,"touchcancel",this._disableDelayedDrag),d(t,"mousemove",this._delayedDragTouchMoveHandler),d(t,"touchmove",this._delayedDragTouchMoveHandler),d(t,"pointermove",this._delayedDragTouchMoveHandler)},_triggerDragStart:function(t,e){e=e||"touch"==t.pointerType&&t,!this.nativeDraggable||e?this.options.supportPointer?u(document,"pointermove",this._onTouchMove):u(document,e?"touchmove":"mousemove",this._onTouchMove):(u(z,"dragend",this),u(q,"dragstart",this._onDragStart));try{document.selection?Ht(function(){document.selection.empty()}):window.getSelection().removeAllRanges()}catch(t){}},_dragStarted:function(t,e){if(vt=!1,q&&z){K("dragStarted",this,{evt:e}),this.nativeDraggable&&u(document,"dragover",kt);var n=this.options;t||k(z,n.dragClass,!1),k(z,n.ghostClass,!0),Rt.active=this,t&&this._appendGhost(),W({sortable:this,name:"start",originalEvent:e})}else this._nulling()},_emulateDragOver:function(){if(at){this._lastX=at.clientX,this._lastY=at.clientY,Nt();for(var t=document.elementFromPoint(at.clientX,at.clientY),e=t;t&&t.shadowRoot&&(t=t.shadowRoot.elementFromPoint(at.clientX,at.clientY))!==e;)e=t;if(z.parentNode[j]._isOutsideThisEl(t),e)do{if(e[j]){if(e[j]._onDragOver({clientX:at.clientX,clientY:at.clientY,target:t,rootEl:e})&&!this.options.dragoverBubble)break}t=e}while(e=e.parentNode);It()}},_onTouchMove:function(t){if(rt){var e=this.options,n=e.fallbackTolerance,o=e.fallbackOffset,i=t.touches?t.touches[0]:t,r=U&&v(U),a=U&&r&&r.a,l=U&&r&&r.d,s=Ct&>&&b(gt),c=(i.clientX-rt.clientX+o.x)/(a||1)+(s?s[0]-Et[0]:0)/(a||1),u=(i.clientY-rt.clientY+o.y)/(l||1)+(s?s[1]-Et[1]:0)/(l||1);if(!Rt.active&&!vt){if(n&&Math.max(Math.abs(i.clientX-this._lastX),Math.abs(i.clientY-this._lastY))o.right+10||t.clientX<=o.right&&t.clientY>o.bottom&&t.clientX>=o.left:t.clientX>o.right&&t.clientY>o.top||t.clientX<=o.right&&t.clientY>o.bottom+10}(n,a,this)&&!g.animated){if(g===z)return A(!1);if(g&&l===n.target&&(s=g),s&&(i=X(s)),!1!==Xt(q,l,z,o,s,i,n,!!s))return O(),l.appendChild(z),G=l,N(),A(!0)}else if(s.parentNode===l){i=X(s);var v,m,b,y=z.parentNode!==l,w=!function(t,e,n){var o=n?t.left:t.top,i=n?t.right:t.bottom,r=n?t.width:t.height,a=n?e.left:e.top,l=n?e.right:e.bottom,s=n?e.width:e.height;return o===a||i===l||o+r/2===a+s/2}(z.animated&&z.toRect||o,s.animated&&s.toRect||i,a),E=a?"top":"left",D=Y(s,"top","top")||Y(z,"top","top"),_=D?D.scrollTop:void 0;if(ht!==s&&(m=i[E],yt=!1,wt=!w&&e.invertSwap||y),0!==(v=function(t,e,n,o,i,r,a,l){var s=o?t.clientY:t.clientX,c=o?n.height:n.width,u=o?n.top:n.left,d=o?n.bottom:n.right,h=!1;if(!a)if(l&&pt