annotation-board

allow you to add annotation after selected content and copy to clipboard and save to local server

Version au 27/05/2019. Voir la dernière version.

Vous devrez installer une extension telle que Tampermonkey, Greasemonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Userscripts pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension de gestionnaire de script utilisateur pour installer ce script.

(J'ai déjà un gestionnaire de scripts utilisateur, laissez-moi l'installer !)

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

(J'ai déjà un gestionnaire de style utilisateur, laissez-moi l'installer!)

// ==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 || 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]);