- // ==UserScript==
- // ==UserScript==
- // @name annotation-board
- // @name:zh-CN 注释墙
- // @description allow you to add annotation after selected content and copy to clipboard and save to local server
- // @description:zh-CN 选中内容后添加注释并复制到剪贴板, 同时在本地的服务其中新建一个副本, 参见 https://github.com/ezirmusitua/snippet-board
- // @version 0.2.0
- // @author jferroal
- // @license GPL-3.0
- // @require https://greasyfork.org/scripts/31793-jmul/code/JMUL.js?version=209567
- // @include http://*
- // @include https://*
- // @grant GM_xmlhttpRequest
- // @run-at document-start
- // @namespace https://greasyfork.org/users/34556
- // ==/UserScript==
-
- (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
- const elements = require('./element');
- const request = require('./snippet.service');
-
- class AnnotationBoard {
- constructor() {
- this.request = request;
- this.container = new elements.Container();
- this.textarea = new elements.Textarea();
- this.saveBtn = new elements.Button();
- this.saveBtn.listenClick(() => {
- this.textarea.copyToClipboard();
- this.request.save({
- link: window.location.href,
- raw_content: this.textarea.value,
- });
- this.hide();
- });
- this.container.appendChild([this.textarea, this.saveBtn]);
- this.container.element.appendTo(document.body);
- this.isShowing = false;
- }
-
- show() {
- this.textarea.appendSelection();
- this.container.show();
- this.isShowing = true;
- }
-
- shouldShow() {
- const isEmptySelection = !!this.textarea.element.getSelection();
- return !this.isShowing && isEmptySelection;
- }
-
- hide() {
- this.isShowing = false;
- this.container.hide('display', 'none');
- }
-
- shouldHide(event) {
- const target = event && event.target;
- if (!target && this.isShowing) {
- return true;
- } else {
- const inContainer = elements.Container.isContainer(target.id);
- const inTextarea = elements.Textarea.isTextarea(target.id);
- const inButton = elements.Button.isButton(target.id);
- return !inContainer && !inTextarea && !inButton && this.isShowing;
- }
- }
- }
-
- module.exports = AnnotationBoard;
- },{"./element":2,"./snippet.service":4}],2:[function(require,module,exports){
- const JMUL = window.JMUL || {};
-
- const AnnotationBoardId = {
- CONTAINER: 'annotation-container',
- TEXTAREA: 'annotation-textarea',
- BUTTON: 'annotation-button',
- };
-
- class BoardContainer {
- constructor() {
- this.element = new JMUL.Element('div');
- this.element.setId(AnnotationBoardId.CONTAINER);
- BoardContainer._initCss(this.element)
- }
-
- appendChild(children) {
- children.forEach((c) => {
- try {
- this.element.appendChild(c.element)
- } catch(er) {
- console.log(er);
- }
- });
- }
-
- show() {
- try {
- const pos = JMUL.Element.getSelectedPosition();
- this.element.setCss({
- display: 'flex',
- flexDirection: 'column',
- left: pos.x,
- top: pos.y,
- });
- } catch (err) {
- console.error(err);
- }
- }
-
- hide() {
- this.element.setCss({
- display: 'none',
- });
- }
-
- static isContainer(id) {
- return AnnotationBoardId.CONTAINER === id;
- }
-
- static _initCss(elem) {
- elem.setCss({
- display: 'none',
- fontFamily: 'Noto',
- border: '4px',
- boxShadow: '0px 3px 8px 1px rgba(0, 0, 0, 0.26)',
- position: 'absolute',
- backgroundColor: 'rgba(0, 0, 0, 0.56)',
- padding: '16px 4px 8px 4px',
- });
- }
- }
-
- class BoardEdit {
- constructor() {
- this.element = JMUL.Decorator.selectable(new JMUL.Element('textarea'));
- this.element.setId(AnnotationBoardId.TEXTAREA);
- BoardEdit._initCss(this.element);
- }
-
- appendSelection() {
- const prevVal = this.element.value();
- const selectedText = this.element.getSelection();
- const newVal = (!!prevVal && (prevVal + '\n') || '') + '========' + '\n' + selectedText + '\n';
- this.element.setValue(newVal)
- }
-
- hide() {
- this.element.setStyle('display', 'none');
- }
-
- copyToClipboard() {
- this.element.copyToClipboard();
- }
-
- get value() {
- return this.element.value();
- }
-
- static isTextarea(id) {
- return AnnotationBoardId.TEXTAREA === id;
- }
-
- static _initCss(elem) {
- elem.setCss({
- fontFamily: 'Noto',
- width: '240px',
- height: '128px',
- backgroundColor: 'rgba(255, 255, 255, 0.87)',
- marginBottom: '8px',
- borderRadius: '4px',
- color: 'rgba(0, 0, 0, 0.76)',
- fontSize: '12px',
- });
- }
- }
-
- class BoardButton {
- constructor() {
- this.element = new JMUL.Element('button');
- this.element.setId(AnnotationBoardId.BUTTON);
- this.element.setInnerHTML('复制到剪贴板');
- BoardButton._initCss(this.element);
- }
-
- listenClick(fn) {
- this.element.listen('click', (e) => fn());
- }
-
- static isButton(id) {
- return AnnotationBoardId.BUTTON === id;
- }
-
- static _initCss(elem) {
- elem.setCss({
- fontFamily: 'Noto',
- border: 'none',
- borderRadius: '4px',
- height: '24px',
- backgroundColor: 'rgba(255, 255, 255, 0.87)',
- color: 'rgba(0, 0, 0, 0.76)',
- fontSize: '14px',
- });
- }
- }
-
- module.exports = {
- Container: BoardContainer,
- Textarea: BoardEdit,
- Button: BoardButton,
- };
- },{}],3:[function(require,module,exports){
- const AnnotationBoard = require('./annotation-board');
-
- (function () {
- const annotationBoard = new AnnotationBoard();
- bindEvent();
- function bindEvent() {
- window.addEventListener('mouseup', (event) => {
- handleMouseUp(event);
- }, false);
- }
-
- function handleMouseUp(event) {
- if (annotationBoard.shouldShow()) {
- annotationBoard.show();
- } else if (annotationBoard.shouldHide(event)) {
- annotationBoard.hide();
- }
- }
- })();
-
- },{"./annotation-board":1}],4:[function(require,module,exports){
- const JMUL = window.JMUL || {};
-
- class SnippetService {
- constructor(host = 'http://127.0.0.1', port = 5000, _options = {}) {
- if (!SnippetService.instance) {
- this.host = host;
- this.port = port;
- this.options = _options;
- if (!this.options.headers) {
- this.options.headers = {'Content-Type': 'application/json'};
- }
- SnippetService.instance = this;
- }
- return SnippetService.instance;
- }
-
- save(data) {
- const request = new JMUL.Request(this.options);
- request.setMethod('POST');
- request.setUrl(this.host + ':' + this.port.toString() + '/snippet/api/v0.1.0');
- request.setData(data);
- request.send();
- }
- }
-
- SnippetService.instance = undefined;
-
- module.exports = new SnippetService();
- },{}]},{},[3]);