You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

310 lines
9.7 KiB

1 month ago
// helpers {{{
function htmlEsc(str) {
return str.replace(/&/g,"&amp;").replace(/>/g,"&gt;").replace(/</g,"&lt;");
}
function setPopupMode(mode) {
$("body").removeClass("clip info config").addClass(mode);
}
function showSuccessMsg(msg) {
$("#info").html(msg);
setPopupMode("info");
setTimeout( function() { window.close() }, 3000 );
}
function showErrMsg(msg) {
$("#info").html(msg);
setPopupMode("info");
}
function g(){return((1+Math.random())*65536|0).toString(16).substring(1)}
function generateUUID(){return g()+g()+"-"+g()+"-"+g()+"-"+g()+"-"+g()+g()+g()}
// }}}
console = chrome.extension.getBackgroundPage().console;
const contentTypes = {
"bookmark": [
{
urlPattern: /^xxx$/,
fields: {},
workflowyFormat: function(data, tab) {
return {
name: tab.title,
description: tab.url
};
}
}
],
"tab": [
{
urlPattern: /^https?:\/\/tabs.ultimate-guitar.com\/tab\//,
fields: {
title: { selector: 'h1', attribute: 'textContent' },
artist: { selector: 'h1 + span', attribute: 'textContent' },
tab: { selector: 'article pre', attribute: 'textContent' }
},
workflowyFormat: function(data, tab) {
return {
name: "<span class='colored c-gray'>" + data.title.trim() + "</span>",
description: data.artist + "\n\n" + "<i>" + data.tab + "</i>"
};
}
}
],
};
function initConfigPopup(tab) { // {{{
setPopupMode("config");
var status;
if (!localStorage.userid) {
status = "Not synchronized";
} else {
status = "Synchronized";
}
$("#status").html("Status: " + status);
// Clear existing buttons
$("#content-type-buttons").empty();
// Create a button for each content type
Object.keys(contentTypes).forEach(function(type) {
var button = $('<button>')
.text("Set '" + type + "' inbox")
.on('click', function() {
setInboxForContentType(type, tab);
});
$("#content-type-buttons").append(button);
});
$("#resetbutton").on("click", function() {
chrome.extension.getBackgroundPage().refreshWorkflowyData(function(err) {
if (err) {
showErrorMsg("Error syncing to WorkFlowy.");
} else {
$("#status").html("Sync successful!");
}
});
});
}
// }}}
function setInboxForContentType(type, tab) { // {{{
console.log("Setting inbox for type: " + type);
chrome.tabs.executeScript(
{ code: "document.getElementsByClassName(\"project selected\")[0].getAttribute(\"projectid\");" },
function(response) {
console.log("Page responded with " + response);
if (response && response[0] != "None") {
var inbox = getInboxObject(); // Get the current inbox object
inbox[type] = response[0]; // Set the inbox for the specific type
setInboxObject(inbox); // Update the inbox object in localStorage
showSuccessMsg(type.charAt(0).toUpperCase() + type.slice(1) + " inbox set successfully.");
} else {
showErrMsg("Problem setting inbox location for " + type + ".");
}
}
);
}
function getInboxObject() {
try {
return JSON.parse(localStorage.inbox || '{}');
} catch (e) {
console.error("Error parsing inbox from localStorage:", e);
return {};
}
}
function setInboxObject(inboxObj) {
localStorage.inbox = JSON.stringify(inboxObj);
}
// }}}
function initClipperPopup(tab) { // {{{
if (! localStorage.userid || ! localStorage.inbox) {
showErrMsg("Extension not configured. "
+ "<a href=\"https://workflowy.com\">Navigate "
+ "to WorkFlowy</a> then press this button again.");
console.log("extension not configured");
return;
}
var contentType = "bookmark";
var contentInfo = contentTypes[contentType][0];
for (let i = 0; i < Object.keys(contentTypes).length; i++) {
var key = Object.keys(contentTypes)[i];
contentTypes[key].forEach(function(content){
if (tab.url.match(content['urlPattern'])){
contentType = key;
contentInfo = content;
}
});
}
var fieldSelectors = contentInfo['fields'];
// contentType = Object.keys(contentTypes).find(key => tab.url.match(contentTypes[key].urlPattern));
console.log("contentType", contentType);
if (contentType === undefined) {
contentType = "bookmark";
console.log("contentType", contentType);
}
var inboxObject = getInboxObject();
if (!(contentType in inboxObject)) {
showErrMsg("Inbox not set for " + contentType);
return;
}
let extractionScript = `var extractedData = {};`;
for (let field in fieldSelectors) {
let selector = fieldSelectors[field].selector;
let attribute = fieldSelectors[field].attribute;
extractionScript += `
var element = document.querySelector('${selector}');
extractedData['${field}'] = element ? element['${attribute}'].trim() : '';
`;
}
extractionScript += 'extractedData;';
setPopupMode("clip");
chrome.tabs.executeScript(tab.id, { code: extractionScript }, function(results) {
if (results && results[0]) {
let extractedData = results[0];
let formattedData = contentInfo.workflowyFormat(extractedData, tab);
$("#name").val(formattedData["name"]);
$("#description").val(formattedData["description"]);
}
});
$("#name").focus();
$("#inboxlink").attr("href", "https://workflowy.com/#/" + inboxObject[contentType] );
$("#inboxlink").html("Go to " + contentType + " inbox");
$("#clipbutton").html("Save " + contentType)
$("#clipbutton").on("click", function () { clipToWorkflowy( $("#name").val(), $("#description").val(), inboxObject[contentType]); });
}
// }}}
function clipToWorkflowy(name, description, inboxId) { // {{{
var newuuid = generateUUID();
var timestamp = Math.floor((new Date()).getTime()/1000) - localStorage.joined;
var request = [{
"most_recent_operation_transaction_id": localStorage.transid,
"operations": [
{ "type": "create",
"data": {
"projectid": newuuid,
"parentid": inboxId,
"priority": 9999
},
"client_timestamp": timestamp,
"undo_data": {}
},
{ "type":"edit",
"data": {
"projectid": newuuid,
"name": name,
"description": description
},
"client_timestamp": timestamp,
"undo_data": {
"previous_last_modified": timestamp,
"previous_name": "",
"previous_description": ""
}
}
]
}];
console.log("Trying to save to workflowy:",
{ timestamp: timestamp,
name: name,
description: description,
name: name,
description: description,
client_id: "2015-11-17 19:25:15.397732",
client_version: 15,
push_poll_id: localStorage.pollid,
push_poll_data: JSON.stringify(request),
crosscheck_user_id: localStorage.userid,
localstorage: localStorage }
);
var data = new FormData();
data.append("client_id", "2015-11-17 19:25:15.397732");
data.append("client_version", 15);
data.append("push_poll_id", localStorage.pollid);
data.append("push_poll_data", JSON.stringify(request));
data.append("crosscheck_user_id", localStorage.userid);
var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://workflowy.com/push_and_poll', true);
xhr.onload = function () {
var respObj = JSON.parse(this.responseText);
console.log("XHR response from server:", respObj);
if (respObj.logged_out) {
showErrMsg("WorkFlowy thinks you're logged out! Make sure you're logged in, and if this message persists then try resynchronizing the extension.");
} else if ( ! respObj.results ) {
showErrMsg("Unknown error!");
} else if (respObj.results[0].error_encountered_in_remote_operations) {
showErrMsg("Unknown error!");
} else {
var oldid = localStorage.transid;
localStorage.transid = respObj.results[0].new_most_recent_operation_transaction_id;
console.log("got new transid: changed from " + oldid + " to " + localStorage.transid);
showSuccessMsg("Successfully clipped!<br><br>"
+ "<small><a href=\"https://workflowy.com/#/"
+ newuuid.substr(24) + "\">view in WorkFlowy</a>"
+ "</small>");
}
};
xhr.send(data);
}
// }}}
document.addEventListener('DOMContentLoaded', function() { // {{{
chrome.tabs.query({ active: true, currentWindow: true }, function(tabs) {
var tab = tabs[0];
console.log("browser action got clicked @ " + tab.url);
$("body").on("click", "a", function() {
chrome.tabs.create({url: $(this).attr("href") });
return false;
});
if (tab.url.match(/^https?:\/\/(?:www\.)?workflowy.com/)) {
initConfigPopup(tab);
} else {
initClipperPopup(tab);
}
});
});
// }}}