add support for tags
This commit is contained in:
parent
8f585ebc88
commit
de46310d93
38
TODO.org
38
TODO.org
|
@ -1,39 +1,29 @@
|
|||
* TODO some sort of append logic? e.g. don't dump immediately and add as subitems?
|
||||
* ???
|
||||
npm install --save-dev @babel/core @babel/preset-env
|
||||
npm install babel-preset-stage-0
|
||||
npm install babel-preset-env -- wtf is that shit??
|
||||
|
||||
npm run build
|
||||
|
||||
npm run flow
|
||||
|
||||
* DONE [#A] move server to a separate folder, systemd install script
|
||||
CLOSED: [2019-01-05 Sat 14:38]
|
||||
* TODO [#B] release somewhere? not sure if necessary
|
||||
* TODO [#B] docs on using
|
||||
|
||||
* START [#A] entering additional information and tags
|
||||
* TODO [#B] doesn't look like hotkey working unless you manually rebind.. wtf?
|
||||
|
||||
* TODO the benefit is that you can also add anything as a backend, e.g. you might be more of markdown fan or todo.txt
|
||||
|
||||
* TODO shortcut for org mode to create timestsamped note
|
||||
|
||||
* TODO [#C] motivation
|
||||
** TODO the benefit is that you can also add anything as a backend, e.g. you might be more of markdown fan or todo.txt
|
||||
|
||||
* TODO [#C] how to test it? try on different pages?
|
||||
* TODO [#C] some sort of append logic? e.g. don't dump immediately and add as subitems?
|
||||
* TODO [#D] do not minfy for dev
|
||||
* TODO not sure, maybe extension press should be default? control it via option?
|
||||
* TODO or, add menu to extension?
|
||||
|
||||
* TODO [#B] release somewhere? not sure if necessary
|
||||
* TODO unsafe-eval in content security policy??
|
||||
|
||||
* TODO make manifest templated so we don't have to hardcode actions
|
||||
|
||||
* TODO [#B] docs on using
|
||||
* DONE [#A] move server to a separate folder, systemd install script
|
||||
CLOSED: [2019-01-05 Sat 14:38]
|
||||
|
||||
* DONE [#A] entering additional information and tags
|
||||
CLOSED: [2019-01-06 Sun 20:41]
|
||||
|
||||
* DONE [#B] circleci?
|
||||
CLOSED: [2019-01-06 Sun 13:50]
|
||||
* DONE [#D] nicer manifest?
|
||||
CLOSED: [2019-01-06 Sun 13:43]
|
||||
* TODO [#D] do not minfy for dev
|
||||
* TODO [#C] motivation
|
||||
* TODO [#B] doesn't look like hotkey working unless you manually rebind.. wtf?
|
||||
|
||||
|
||||
* TODO [#C] how to test it? try on different pages?
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "grasp-extension",
|
||||
"version": "0.2.0",
|
||||
"version": "0.3.0",
|
||||
"description": "A reliable way of capturing web pages and content",
|
||||
"scripts": {
|
||||
"build": "webpack --progress --profile --colors",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
"""First API, local access only"""
|
||||
import json
|
||||
import re
|
||||
|
||||
import hug # type: ignore
|
||||
import hug.types as T # type: ignore
|
||||
|
@ -23,11 +24,16 @@ def capture(
|
|||
title: T.Nullable(T.text),
|
||||
selection: T.Nullable(T.text),
|
||||
comment: T.Nullable(T.text),
|
||||
tag_str: T.Nullable(T.text),
|
||||
):
|
||||
log("capturing", url, title, selection, comment)
|
||||
|
||||
heading = url
|
||||
parts = []
|
||||
tags = []
|
||||
if not empty(tag_str):
|
||||
tags = re.split('[\s,]', tag_str)
|
||||
tags = [t for t in tags if not empty(t)] # just in case
|
||||
|
||||
if not empty(title):
|
||||
heading = title
|
||||
|
@ -55,7 +61,7 @@ def capture(
|
|||
CAPTURE_PATH,
|
||||
heading=heading,
|
||||
body=body,
|
||||
tags=['grasp'],
|
||||
tags=tags,
|
||||
todo=False,
|
||||
)
|
||||
response.update({
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
// TODO do I really need to annotate all files with @flow??
|
||||
|
||||
import {COMMAND_CAPTURE_SIMPLE, METHOD_CAPTURE_WITH_EXTRAS, showNotification} from './common';
|
||||
import {capture_url} from './config';
|
||||
|
||||
import {defaultTagStr, capture_url} from './options';
|
||||
|
||||
type Params = {
|
||||
url: string,
|
||||
title: ?string,
|
||||
selection: ?string,
|
||||
comment: ?string,
|
||||
tag_str: ?string,
|
||||
}
|
||||
|
||||
|
||||
|
@ -19,7 +19,6 @@ function makeCaptureRequest(
|
|||
const data = JSON.stringify(params);
|
||||
console.log(`[background] capturing ${data}`);
|
||||
|
||||
|
||||
var request = new XMLHttpRequest();
|
||||
request.open('POST', capture_url(), true);
|
||||
request.onreadystatechange = () => {
|
||||
|
@ -51,13 +50,17 @@ function makeCaptureRequest(
|
|||
request.send(data);
|
||||
}
|
||||
|
||||
function capture(comment: ?string = null) {
|
||||
function capture(comment: ?string = null, tag_str: ?string = null) {
|
||||
chrome.tabs.query({currentWindow: true, active: true }, tabs => {
|
||||
const tab = tabs[0];
|
||||
if (tab.url == null) {
|
||||
showNotification('ERROR: trying to capture null');
|
||||
return;
|
||||
}
|
||||
if (tag_str === null) {
|
||||
tag_str = defaultTagStr();
|
||||
}
|
||||
|
||||
const url: string = tab.url;
|
||||
const title: ?string = tab.title;
|
||||
|
||||
|
@ -72,6 +75,7 @@ function capture(comment: ?string = null) {
|
|||
title: title,
|
||||
selection: selection,
|
||||
comment: comment,
|
||||
tag_str: tag_str,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -80,14 +84,15 @@ function capture(comment: ?string = null) {
|
|||
|
||||
chrome.commands.onCommand.addListener(command => {
|
||||
if (command === COMMAND_CAPTURE_SIMPLE) {
|
||||
capture(null);
|
||||
capture(null, null);
|
||||
}
|
||||
});
|
||||
|
||||
chrome.runtime.onMessage.addListener((message: any, sender: chrome$MessageSender, sendResponse) => {
|
||||
if (message.method === METHOD_CAPTURE_WITH_EXTRAS) {
|
||||
const comment = message.comment;
|
||||
capture(comment);
|
||||
const tag_str = message.tag_str;
|
||||
capture(comment, tag_str);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
/* @flow */
|
||||
|
||||
// TODO configure port in options?
|
||||
const capture_endpoint = 'capture';
|
||||
const port = 8090;
|
||||
|
||||
export function capture_url (): string {
|
||||
return `http://localhost:${port}/${capture_endpoint}`;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/* @flow */
|
||||
|
||||
const capture_endpoint = 'capture';
|
||||
|
||||
function port(): string {
|
||||
return "8090";
|
||||
}
|
||||
|
||||
// none means do not use tags
|
||||
export function defaultTagStr (): ?string {
|
||||
return 'grasp';
|
||||
}
|
||||
|
||||
export function capture_url (): string {
|
||||
return `http://localhost:${port()}/${capture_endpoint}`;
|
||||
}
|
|
@ -5,12 +5,18 @@ import {METHOD_CAPTURE_WITH_EXTRAS} from './common';
|
|||
// TODO template it in html too?
|
||||
const BUTTON_ID = 'button_id';
|
||||
const COMMENT_ID = 'comment_id';
|
||||
const TAGS_ID = 'tags_id';
|
||||
|
||||
function getComment(): HTMLInputElement {
|
||||
const comment = ((document.getElementById(COMMENT_ID) : any): HTMLInputElement);
|
||||
return comment;
|
||||
}
|
||||
|
||||
function getTags(): HTMLInputElement {
|
||||
const tags = ((document.getElementById(TAGS_ID) : any): HTMLInputElement);
|
||||
return tags;
|
||||
}
|
||||
|
||||
function getButton(): HTMLElement {
|
||||
const button = ((document.getElementById(BUTTON_ID): any): HTMLElement);
|
||||
return button;
|
||||
|
@ -18,25 +24,48 @@ function getButton(): HTMLElement {
|
|||
|
||||
function submitComment () {
|
||||
const comment_text = getComment().value;
|
||||
const tag_str = getTags().value;
|
||||
// TODO focus
|
||||
chrome.runtime.sendMessage({
|
||||
'method': METHOD_CAPTURE_WITH_EXTRAS,
|
||||
'comment': comment_text,
|
||||
'tag_str': tag_str,
|
||||
}, resp => {
|
||||
console.log("[popup] captured!");
|
||||
});
|
||||
window.close();
|
||||
}
|
||||
|
||||
// $FlowFixMe
|
||||
function ctrlEnterSubmit(e) {
|
||||
if (e.ctrlKey && e.key === 'Enter') {
|
||||
submitComment();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// https://stackoverflow.com/a/6003829/706389
|
||||
function moveCaretToEnd(el) {
|
||||
if (typeof el.selectionStart == "number") {
|
||||
el.selectionStart = el.selectionEnd = el.value.length;
|
||||
} else if (typeof el.createTextRange != "undefined") {
|
||||
el.focus();
|
||||
var range = el.createTextRange();
|
||||
range.collapse(false);
|
||||
range.select();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function setupPage () {
|
||||
const comment = getComment();
|
||||
comment.focus();
|
||||
// $FlowFixMe
|
||||
comment.addEventListener('keydown', e => {
|
||||
if (e.ctrlKey && e.key === 'Enter') {
|
||||
submitComment();
|
||||
}
|
||||
});
|
||||
comment.addEventListener('keydown', ctrlEnterSubmit);
|
||||
|
||||
const tags = getTags();
|
||||
tags.addEventListener('keydown', ctrlEnterSubmit);
|
||||
tags.addEventListener('focus', () => moveCaretToEnd(tags)); // to put cursor to the end of tags when tabbed
|
||||
|
||||
getButton().addEventListener('click', submitComment);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,10 @@
|
|||
<meta charset="UTF-8">
|
||||
</head>
|
||||
<body>
|
||||
<!-- TODO ugh didn't work -->
|
||||
<!-- <%= htmlWebpackPlugin.options.ids.tags %> -->
|
||||
<div><textarea id="comment_id" rows="4" cols="50" placeholder="Enter your comments; press Ctrl-Enter to capture"></textarea></div>
|
||||
<div><button id="button_id" type="button" align="right">capture!</button></div>
|
||||
<div><textarea id="tags_id" rows="1" cols="50">grasp</textarea></div>
|
||||
<div><button id="button_id" type="button" align="right">capture!</button></div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -81,7 +81,7 @@ var options = {
|
|||
new HtmlWebpackPlugin({
|
||||
template: path.join(__dirname, "src", "popup.html"),
|
||||
filename: "popup.html",
|
||||
chunks: ["popup"]
|
||||
chunks: ["popup"],
|
||||
}),
|
||||
new HtmlWebpackPlugin({
|
||||
template: path.join(__dirname, "src", "options.html"),
|
||||
|
|
Loading…
Reference in a new issue