* Initial prototype of the V3 manifest extension * Make sure the content script is only injected once * Implement addNote button * More separation work for tasks, implement archive and update note * Add back missing functionality, add guide to install Extensions * Revert v2 changes --------- Co-authored-by: Thomas Rogers <Podginator@gmail.com>
1 line
13 KiB
JavaScript
1 line
13 KiB
JavaScript
(()=>{"use strict";var e,t=new Uint8Array(16);function n(){if(!e&&!(e="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&"function"==typeof msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto)))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return e(t)}const i=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;for(var r=[],o=0;o<256;++o)r.push((o+256).toString(16).substr(1));const s=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=(r[e[t+0]]+r[e[t+1]]+r[e[t+2]]+r[e[t+3]]+"-"+r[e[t+4]]+r[e[t+5]]+"-"+r[e[t+6]]+r[e[t+7]]+"-"+r[e[t+8]]+r[e[t+9]]+"-"+r[e[t+10]]+r[e[t+11]]+r[e[t+12]]+r[e[t+13]]+r[e[t+14]]+r[e[t+15]]).toLowerCase();if(!function(e){return"string"==typeof e&&i.test(e)}(n))throw TypeError("Stringified UUID is invalid");return n},a=function(e,t,i){var r=(e=e||{}).random||(e.rng||n)();if(r[6]=15&r[6]|64,r[8]=63&r[8]|128,t){i=i||0;for(var o=0;o<16;++o)t[i+o]=r[o];return t}return s(r)};const l=e=>{return t=void 0,n=void 0,r=function*(){return new Promise((t=>{chrome.storage.local.get(e,(n=>{const i=n&&n[e]||null;t(i)}))}))},new((i=void 0)||(i=Promise))((function(e,o){function s(e){try{l(r.next(e))}catch(e){o(e)}}function a(e){try{l(r.throw(e))}catch(e){o(e)}}function l(t){var n;t.done?e(t.value):(n=t.value,n instanceof i?n:new i((function(e){e(n)}))).then(s,a)}l((r=r.apply(t,n||[])).next())}));var t,n,i,r};var u=function(e,t,n,i){return new(n||(n=Promise))((function(r,o){function s(e){try{l(i.next(e))}catch(e){o(e)}}function a(e){try{l(i.throw(e))}catch(e){o(e)}}function l(e){var t;e.done?r(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(s,a)}l((i=i.apply(e,t||[])).next())}))};const c=e=>u(void 0,void 0,void 0,(function*(){var t,n;const i=yield l("omnivoreApiKey");let r={Accept:"application/json","Content-Type":"application/json"};i&&(r.Authorization=i);try{const i=null!==(n=null!==(t=yield l("omnivoreApiUrl"))&&void 0!==t?t:process.env.OMNIVORE_GRAPHQL_URL)&&void 0!==n?n:"";console.log(i);const o=yield fetch(`${i}/api/graphql`,{method:"POST",redirect:"follow",credentials:"include",mode:"cors",headers:r,body:e}),s=yield o.json();if(!("data"in s)||!s.data)throw new Error("No response data");return s.data}catch(t){console.log("[omnivore] error making api request: ",e)}}));var d=function(e,t,n,i){return new(n||(n=Promise))((function(r,o){function s(e){try{l(i.next(e))}catch(e){o(e)}}function a(e){try{l(i.throw(e))}catch(e){o(e)}}function l(e){var t;e.done?r(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(s,a)}l((i=i.apply(e,t||[])).next())}))};class g{constructor(){this.queue=[],this.isRunning=!1,this.isReady=!1,this.executeTask=e=>d(this,void 0,void 0,(function*(){var t,n;if(console.log("executing task: ",e),!this.libraryItemId)throw Error("Attempting to execute queue that is not ready.");try{let i=!1;switch(e.task){case"archive":yield(n=this.libraryItemId,u(void 0,void 0,void 0,(function*(){var e,t;const i=JSON.stringify({query:"mutation SetLinkArchived($input: ArchiveLinkInput!) {\n setLinkArchived(input: $input) {\n ... on ArchiveLinkSuccess {\n linkId\n message\n }\n ... on ArchiveLinkError {\n message\n errorCodes\n }\n }\n }\n ",variables:{input:{linkId:n,archived:!0}}}),r=yield c(i);return(null===(t=null===(e=r.setLinkArchived)||void 0===e?void 0:e.errorCodes)||void 0===t?void 0:t.length)?(console.log("[omnivore] api: error getting article:",r),r.setLinkArchived.errorCodes.indexOf("UNAUTHORIZED")>-1?(console.log("[omnivore] api is not authorized"),"unauthorized"):"failure"):"success"}))),i=!0;break;case"delete":yield function(e){return u(this,void 0,void 0,(function*(){const t=JSON.stringify({query:"mutation SetBookmarkArticle($input: SetBookmarkArticleInput!) {\n setBookmarkArticle(input: $input) {\n ... on SetBookmarkArticleSuccess {\n bookmarkedArticle {\n id\n }\n }\n ... on SetBookmarkArticleError {\n errorCodes\n }\n }\n }\n ",variables:{input:{articleID:e,bookmark:!1}}}),n=yield c(t);if(!n.setBookmarkArticle||n.setBookmarkArticle.errorCodes||!n.setBookmarkArticle.bookmarkedArticle)throw console.log("GQL Error deleting:",n),new Error("Error deleting.");return"success"}))}(this.libraryItemId),i=!0;break;case"addNote":yield function(e){var t,n,i,r;return u(this,void 0,void 0,(function*(){const o=JSON.stringify({query:"query GetArticle(\n $username: String!\n $slug: String!\n $includeFriendsHighlights: Boolean\n ) {\n article(username: $username, slug: $slug) {\n ... on ArticleSuccess {\n article {\n highlights(input: { includeFriends: $includeFriendsHighlights }) {\n ...HighlightFields\n }\n }\n }\n ... on ArticleError {\n errorCodes\n }\n }\n }\n fragment HighlightFields on Highlight {\n id\n type\n annotation\n }\n ",variables:{username:"me",slug:e.libraryItemId,includeFriendsHighlights:!1}}),s=yield c(o);if(null===(n=null===(t=s.article)||void 0===t?void 0:t.errorCodes)||void 0===n?void 0:n.length)return console.log("[omnivore] api: error getting article:",s),s.article.errorCodes.indexOf("UNAUTHORIZED")>-1?(console.log("[omnivore] api is not authorized"),"unauthorized"):"failure";console.log("DATA.ARTICLE: ",s.article);const l=null===(r=null===(i=s.article)||void 0===i?void 0:i.highlights)||void 0===r?void 0:r.find((e=>"NOTE"==e.type));if(l){const t=JSON.stringify({query:"\n mutation UpdateHighlight($input: UpdateHighlightInput!) {\n updateHighlight(input: $input) {\n ... on UpdateHighlightSuccess {\n highlight {\n id\n }\n }\n ... on UpdateHighlightError {\n errorCodes\n }\n }\n }\n ",variables:{input:{highlightId:l.id,annotation:l.annotation?l.annotation+"\n\n"+e.note:e.note}}}),n=yield c(t);return n.updateHighlight&&!n.updateHighlight.errorCodes&&n.updateHighlight.highlight?n.updateHighlight.highlight.id:void console.log("GQL Error updating note:",n)}{const t=a(),n=((e=21)=>crypto.getRandomValues(new Uint8Array(e)).reduce(((e,t)=>e+((t&=63)<36?t.toString(36):t<62?(t-26).toString(36).toUpperCase():t>62?"-":"_")),""))(8),i=JSON.stringify({query:"\n mutation CreateHighlight($input: CreateHighlightInput!) {\n createHighlight(input: $input) {\n ... on CreateHighlightSuccess {\n highlight {\n id\n }\n }\n ... on CreateHighlightError {\n errorCodes\n }\n }\n }\n ",variables:{input:{id:t,shortId:n,type:"NOTE",articleId:e.libraryItemId,annotation:e.note}}}),r=yield c(i);return r.createHighlight&&!r.createHighlight.errorCodes&&r.createHighlight.highlight?"success":(console.log("GQL Error setting note:",r),"failure")}}))}({note:e.note||"",libraryItemId:this.libraryItemId}),i=!0;break;case"setLabels":yield function(e,t){return u(this,void 0,void 0,(function*(){const n=JSON.stringify({query:"mutation SetLabels($input: SetLabelsInput!) {\n setLabels(input: $input) {\n ... on SetLabelsSuccess {\n labels {\n id\n name\n color\n }\n }\n ... on SetLabelsError {\n errorCodes\n }\n }\n }\n ",variables:{input:{pageId:e,labelIds:t}}}),i=yield c(n);if(!i.setLabels||i.setLabels.errorCodes||!i.setLabels.labels)throw console.log("GQL Error setting labels:",i),new Error("Error setting labels.");return i.setLabels.labels}))}(this.libraryItemId,null!==(t=e.labels)&&void 0!==t?t:[]),i=!0;break;case"editTitle":if(!e.title||!this.libraryItemId)throw new Error("Title not set, or library item not yet saved.");yield function(e,t){return u(this,void 0,void 0,(function*(){const n=JSON.stringify({query:"mutation UpdatePage($input: UpdatePageInput!) {\n updatePage(input: $input) {\n ... on UpdatePageSuccess {\n updatedPage {\n id\n }\n }\n ... on UpdatePageError {\n errorCodes\n }\n }\n }\n ",variables:{input:{pageId:e,title:t}}}),i=yield c(n);if(console.log(i),!i.updatePage||i.updatePage.errorCodes||!i.updatePage.updatedPage)throw console.log("GQL Error updating page:",i),new Error("Error updating title.");return"success"}))}(this.libraryItemId,e.title),i=!0;break;case"updateLabelCache":yield function(){return u(this,void 0,void 0,(function*(){const e=JSON.stringify({query:"query GetLabels {\n labels {\n ... on LabelsSuccess {\n labels {\n ...LabelFields\n }\n }\n ... on LabelsError {\n errorCodes\n }\n }\n }\n fragment LabelFields on Label {\n id\n name\n color\n description\n createdAt\n }\n "}),t=yield c(e);return t.labels&&!t.labels.errorCodes&&t.labels.labels?(yield(n={labels:t.labels.labels,labelsLastUpdated:(new Date).toISOString()},chrome.storage.local.set(n)),t.labels.labels):(console.log("GQL Error updating label cache response:",t,t),console.log(!t.labels,t.labels.errorCodes,!t.labels.labels),[]);var n}))}(),this.tabId&&chrome.tabs.sendMessage(this.tabId,{message:"updateLabelCache",status:"success",task:e.task})}i&&this.tabId&&chrome.tabs.sendMessage(this.tabId,{message:"updateToolbar",status:"success",task:e.task})}catch(t){console.log("[omnivore] task queue error: ",t),this.tabId&&(console.log("sending error message"),chrome.tabs.sendMessage(this.tabId,{message:"updateToolbar",status:"failure",task:e.task}))}}))}enqueue(e){this.queue.push(e),this.isReady&&this.runNext()}runNext(){return d(this,void 0,void 0,(function*(){if(this.isRunning||0===this.queue.length||!this.isReady)return;this.isRunning=!0;const e=this.queue.shift();if(e)try{yield this.executeTask(e)}catch(e){console.error("Task failed:",e)}finally{this.isRunning=!1,this.isReady&&this.runNext()}}))}setReady(e,t){console.log("setting ready"),this.tabId=e,this.libraryItemId=t,this.isReady=!0,this.runNext()}}var h=function(e,t,n,i){return new(n||(n=Promise))((function(r,o){function s(e){try{l(i.next(e))}catch(e){o(e)}}function a(e){try{l(i.throw(e))}catch(e){o(e)}}function l(e){var t;e.done?r(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(s,a)}l((i=i.apply(e,t||[])).next())}))};const p="undefined"!=typeof browser?browser:chrome,v={};chrome.runtime.onMessage.addListener(((e,t,n)=>h(void 0,void 0,void 0,(function*(){var n,i;console.log("message: ",e,"sender",null===(n=t.tab)||void 0===n?void 0:n.id);const r=null===(i=t.tab)||void 0===i?void 0:i.id;if("savePage"===e.action&&"object"==typeof(o=e)&&"string"==typeof o.url&&"string"==typeof o.title&&"string"==typeof o.clientRequestId&&"string"==typeof o.originalContent){const{result:t,libraryItemId:n}=yield function(e){var t,n,i;return u(this,void 0,void 0,(function*(){const r=JSON.stringify({query:"mutation SavePage ($input: SavePageInput!) {\n savePage(input:$input){\n ... on SaveSuccess {\n url\n clientRequestId\n }\n ... on SaveError {\n errorCodes\n }\n }\n }",variables:{input:Object.assign({source:"extension"},e)}}),o=yield c(r);return(null===(n=null===(t=o.savePage)||void 0===t?void 0:t.errorCodes)||void 0===n?void 0:n.length)?(console.log("[omnivore] api: error saving page:",o),o.savePage.errorCodes.indexOf("UNAUTHORIZED")>-1?(console.log("[omnivore] api is not authorized"),{result:"unauthorized"}):{result:"failure"}):{result:"success",libraryItemId:null===(i=o.savePage)||void 0===i?void 0:i.clientRequestId}}))}({url:e.url,title:e.title,clientRequestId:e.clientRequestId,originalContent:e.originalContent});if(console.log("result: ",t,"libraryItemId",n),r)switch(t){case"success":chrome.tabs.sendMessage(r,{message:"startToolbarDismiss",status:"success"}),n&&v[e.clientRequestId].setReady(r,n);break;case"failure":chrome.tabs.sendMessage(r,{message:"startToolbarDismiss",status:"failure"});break;case"unauthorized":chrome.tabs.sendMessage(r,{message:"showLoggedOutToolbar"})}}else if("enqueueTask"==e.action&&function(e){return"object"==typeof e&&"string"==typeof e.task&&"string"==typeof e.clientRequestId}(e)){const t=v[e.clientRequestId];console.log("enqueing task message: ",e),t.enqueue(Object.assign(Object.assign({},e),{libraryItemId:e.clientRequestId}))}var o;return!0})))),p.action.onClicked.addListener((e=>h(void 0,void 0,void 0,(function*(){const t=e.id;if(t){try{const e=yield(e=>h(void 0,void 0,void 0,(function*(){try{const t=yield chrome.tabs.sendMessage(e,{message:"ping"});return console.log("pingCheck: ",t),!0}catch(e){return!1}})))(t);e||(yield chrome.scripting.executeScript({target:{tabId:t},files:["content.js"]}))}catch(e){console.log("[omnivore] error injecting content script: ",e)}const e=a();v[e]=new g,chrome.tabs.sendMessage(t,{message:"savePage",clientRequestId:e})}}))))})(); |