annotation-board

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

Verzia zo dňa 27.05.2019. Pozri najnovšiu verziu.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, Greasemonkey alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, % alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, % alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey alebo Userscripts.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie správcu používateľských skriptov.

(Už mám správcu používateľských skriptov, nechajte ma ho nainštalovať!)

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

(Už mám správcu používateľských štýlov, nechajte ma ho nainštalovať!)

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