mirror of
https://github.com/laurent22/joplin.git
synced 2025-01-11 18:24:43 +02:00
Clipper: More consistent REST API
This commit is contained in:
parent
3822309657
commit
bdd9da3d22
@ -1,15 +1,25 @@
|
||||
let browser_ = null;
|
||||
let browserName_ = null;
|
||||
if (typeof browser !== 'undefined') {
|
||||
browser_ = browser;
|
||||
browserSupportsPromises_ = true;
|
||||
browserName_ = 'firefox';
|
||||
} else if (typeof chrome !== 'undefined') {
|
||||
browser_ = chrome;
|
||||
browserSupportsPromises_ = false;
|
||||
browserName_ = 'chrome';
|
||||
}
|
||||
|
||||
function env() {
|
||||
return 'prod';
|
||||
return !('update_url' in browser_.runtime.getManifest()) ? 'dev' : 'prod';
|
||||
let env_ = null;
|
||||
|
||||
// Make this function global so that it can be accessed
|
||||
// from the popup too.
|
||||
// https://stackoverflow.com/questions/6323184/communication-between-background-page-and-popup-page-in-a-chrome-extension
|
||||
window.joplinEnv = function() {
|
||||
if (env_) return env_;
|
||||
|
||||
env_ = !('update_url' in browser_.runtime.getManifest()) ? 'dev' : 'prod';
|
||||
return env_;
|
||||
}
|
||||
|
||||
async function browserCaptureVisibleTabs(windowId, options) {
|
||||
@ -22,8 +32,19 @@ async function browserCaptureVisibleTabs(windowId, options) {
|
||||
});
|
||||
}
|
||||
|
||||
browser_.runtime.onInstalled.addListener(function() {
|
||||
if (env() === 'dev') {
|
||||
browser_.runtime.onInstalled.addListener(function(details) {
|
||||
if (details && details.temporary) {
|
||||
// In Firefox - https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/runtime/onInstalled
|
||||
env_ = 'dev';
|
||||
} else if (browserName_ === 'chrome') {
|
||||
// In Chrome
|
||||
env_ = !('update_url' in browser_.runtime.getManifest()) ? 'dev' : 'prod';
|
||||
} else {
|
||||
// If we don't know, be safe and default to prod
|
||||
env_ = 'prod';
|
||||
}
|
||||
|
||||
if (window.joplinEnv() === 'dev') {
|
||||
browser_.browserAction.setIcon({
|
||||
path: 'icons/32-dev.png',
|
||||
});
|
||||
@ -34,9 +55,9 @@ browser_.runtime.onMessage.addListener((command) => {
|
||||
if (command.name === 'screenshotArea') {
|
||||
browserCaptureVisibleTabs(null, { format: 'jpeg' }).then((imageDataUrl) => {
|
||||
content = Object.assign({}, command.content);
|
||||
content.imageDataUrl = imageDataUrl;
|
||||
content.image_data_url = imageDataUrl;
|
||||
|
||||
fetch(command.apiBaseUrl + "/notes", {
|
||||
fetch(command.api_base_url + "/notes", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
|
@ -92,9 +92,9 @@
|
||||
name: 'clippedContent',
|
||||
html: article.body,
|
||||
title: article.title,
|
||||
baseUrl: baseUrl(),
|
||||
base_url: baseUrl(),
|
||||
url: location.origin + location.pathname,
|
||||
parentId: command.parentId,
|
||||
parent_id: command.parent_id,
|
||||
};
|
||||
|
||||
} else if (command.name === "completePageHtml") {
|
||||
@ -106,9 +106,9 @@
|
||||
name: 'clippedContent',
|
||||
html: cleanDocument.innerHTML,
|
||||
title: pageTitle(),
|
||||
baseUrl: baseUrl(),
|
||||
base_url: baseUrl(),
|
||||
url: location.origin + location.pathname,
|
||||
parentId: command.parentId,
|
||||
parent_id: command.parent_id,
|
||||
};
|
||||
|
||||
} else if (command.name === 'screenshot') {
|
||||
@ -207,15 +207,15 @@
|
||||
setTimeout(() => {
|
||||
const content = {
|
||||
title: pageTitle(),
|
||||
cropRect: selectionArea,
|
||||
crop_rect: selectionArea,
|
||||
url: location.origin + location.pathname,
|
||||
parentId: command.parentId,
|
||||
parent_id: command.parent_id,
|
||||
};
|
||||
|
||||
browser_.runtime.sendMessage({
|
||||
name: 'screenshotArea',
|
||||
content: content,
|
||||
apiBaseUrl: command.apiBaseUrl,
|
||||
api_base_url: command.api_base_url,
|
||||
});
|
||||
}, 100);
|
||||
}
|
||||
|
@ -30,14 +30,14 @@ class AppComponent extends Component {
|
||||
this.clipSimplified_click = () => {
|
||||
bridge().sendCommandToActiveTab({
|
||||
name: 'simplifiedPageHtml',
|
||||
parentId: this.props.selectedFolderId,
|
||||
parent_id: this.props.selectedFolderId,
|
||||
});
|
||||
}
|
||||
|
||||
this.clipComplete_click = () => {
|
||||
bridge().sendCommandToActiveTab({
|
||||
name: 'completePageHtml',
|
||||
parentId: this.props.selectedFolderId,
|
||||
parent_id: this.props.selectedFolderId,
|
||||
});
|
||||
}
|
||||
|
||||
@ -47,8 +47,8 @@ class AppComponent extends Component {
|
||||
|
||||
await bridge().sendCommandToActiveTab({
|
||||
name: 'screenshot',
|
||||
apiBaseUrl: baseUrl,
|
||||
parentId: this.props.selectedFolderId,
|
||||
api_base_url: baseUrl,
|
||||
parent_id: this.props.selectedFolderId,
|
||||
});
|
||||
|
||||
window.close();
|
||||
@ -118,7 +118,7 @@ class AppComponent extends Component {
|
||||
<div className="Preview">
|
||||
<input className={"Title"} value={content.title} onChange={this.contentTitle_change}/>
|
||||
<div className={"BodyWrapper"}>
|
||||
<div className={"Body"} dangerouslySetInnerHTML={{__html: content.bodyHtml}}></div>
|
||||
<div className={"Body"} dangerouslySetInnerHTML={{__html: content.body_html}}></div>
|
||||
</div>
|
||||
<a className={"Confirm Button"} onClick={this.confirm_click}>Confirm</a>
|
||||
</div>
|
||||
@ -182,7 +182,7 @@ class AppComponent extends Component {
|
||||
return (
|
||||
<div className="Folders">
|
||||
<label>In notebook: </label>
|
||||
<select value={this.props.selectedFolderId} onChange={this.folderSelect_change}>
|
||||
<select value={this.props.selectedFolderId || ''} onChange={this.folderSelect_change}>
|
||||
{ optionComps }
|
||||
</select>
|
||||
</div>
|
||||
|
@ -12,7 +12,7 @@ class Bridge {
|
||||
this.clipperServerPortStatus_ = 'searching';
|
||||
|
||||
this.browser_notify = async (command) => {
|
||||
console.info('Popup: Got command: ' + command.name);
|
||||
console.info('Popup: Got command:', command);
|
||||
|
||||
if (command.warning) {
|
||||
console.warn('Popup: Got warning: ' + command.warning);
|
||||
@ -24,10 +24,10 @@ class Bridge {
|
||||
if (command.name === 'clippedContent') {
|
||||
const content = {
|
||||
title: command.title,
|
||||
bodyHtml: command.html,
|
||||
baseUrl: command.baseUrl,
|
||||
url: command.url,
|
||||
parentId: command.parentId,
|
||||
body_html: command.html,
|
||||
base_url: command.base_url,
|
||||
source_url: command.url,
|
||||
parent_id: command.parent_id,
|
||||
};
|
||||
|
||||
this.dispatch({ type: 'CLIPPED_CONTENT_SET', content: content });
|
||||
@ -36,14 +36,21 @@ class Bridge {
|
||||
|
||||
this.browser_.runtime.onMessage.addListener(this.browser_notify);
|
||||
|
||||
console.info('Popup: Env: ', this.env());
|
||||
const backgroundPage = this.browser_.extension.getBackgroundPage();
|
||||
this.env_ = backgroundPage.joplinEnv();
|
||||
|
||||
console.info('Popup: Env:', this.env());
|
||||
|
||||
this.dispatch({
|
||||
type: 'ENV_SET',
|
||||
env: this.env(),
|
||||
});
|
||||
|
||||
this.findClipperServerPort();
|
||||
}
|
||||
|
||||
env() {
|
||||
return 'prod';
|
||||
return !('update_url' in this.browser().runtime.getManifest()) ? 'dev' : 'prod';
|
||||
return this.env_;
|
||||
}
|
||||
|
||||
browser() {
|
||||
@ -149,6 +156,12 @@ class Bridge {
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
this.browser().tabs.executeScript(options, () => {
|
||||
const e = this.browser().runtime.lastError;
|
||||
if (e) {
|
||||
const msg = ['tabsExecuteScript: Cannot load ' + JSON.stringify(options)]
|
||||
if (e.message) msg.push(e.message);
|
||||
reject(new Error(msg.join(': ')));
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
})
|
||||
|
@ -17,6 +17,7 @@ const defaultState = {
|
||||
},
|
||||
folders: [],
|
||||
selectedFolderId: null,
|
||||
env: 'prod',
|
||||
};
|
||||
|
||||
const reduxMiddleware = store => next => async (action) => {
|
||||
@ -60,6 +61,10 @@ function reducer(state = defaultState, action) {
|
||||
newState = Object.assign({}, state);
|
||||
newState.folders = action.folders;
|
||||
|
||||
if (!newState.selectedFolderId && action.folders.length) {
|
||||
newState.selectedFolderId = action.folders[0].id;
|
||||
}
|
||||
|
||||
} else if (action.type === 'SELECTED_FOLDER_SET') {
|
||||
|
||||
newState = Object.assign({}, state);
|
||||
@ -73,6 +78,11 @@ function reducer(state = defaultState, action) {
|
||||
if ('port' in action) clipperServer.port = action.port;
|
||||
newState.clipperServer = clipperServer;
|
||||
|
||||
} else if (action.type === 'ENV_SET') {
|
||||
|
||||
newState = Object.assign({}, state);
|
||||
newState.env = action.env;
|
||||
|
||||
}
|
||||
|
||||
return newState;
|
||||
|
@ -76,24 +76,24 @@ class ClipperServer {
|
||||
body: requestNote.body ? requestNote.body : '',
|
||||
};
|
||||
|
||||
if (requestNote.bodyHtml) {
|
||||
if (requestNote.body_html) {
|
||||
// Parsing will not work if the HTML is not wrapped in a top level tag, which is not guaranteed
|
||||
// when getting the content from elsewhere. So here wrap it - it won't change anything to the final
|
||||
// rendering but it makes sure everything will be parsed.
|
||||
output.body = await this.htmlToMdParser().parse('<div>' + requestNote.bodyHtml + '</div>', {
|
||||
baseUrl: requestNote.baseUrl ? requestNote.baseUrl : '',
|
||||
output.body = await this.htmlToMdParser().parse('<div>' + requestNote.body_html + '</div>', {
|
||||
baseUrl: requestNote.base_url ? requestNote.base_url : '',
|
||||
});
|
||||
}
|
||||
|
||||
if (requestNote.parentId) {
|
||||
output.parent_id = requestNote.parentId;
|
||||
if (requestNote.parent_id) {
|
||||
output.parent_id = requestNote.parent_id;
|
||||
} else {
|
||||
const folder = await Folder.defaultFolder();
|
||||
if (!folder) throw new Error('Cannot find folder for note');
|
||||
output.parent_id = folder.id;
|
||||
}
|
||||
|
||||
if (requestNote.url) output.source_url = requestNote.url;
|
||||
if (requestNote.source_url) output.source_url = requestNote.source_url;
|
||||
|
||||
return output;
|
||||
}
|
||||
@ -277,8 +277,8 @@ class ClipperServer {
|
||||
|
||||
note = await Note.save(note);
|
||||
|
||||
if (requestNote.imageDataUrl) {
|
||||
await this.attachImageFromDataUrl_(note, requestNote.imageDataUrl, requestNote.cropRect);
|
||||
if (requestNote.image_data_url) {
|
||||
await this.attachImageFromDataUrl_(note, requestNote.image_data_url, requestNote.crop_rect);
|
||||
}
|
||||
|
||||
this.logger().info('Request (' + requestId + '): Created note ' + note.id);
|
||||
|
Loading…
Reference in New Issue
Block a user