jsq-stickyNotes

Press "shift + left key" to add sticky notes in any webpage wherever you like

目前为 2022-03-13 提交的版本。查看 最新版本

// ==UserScript==
// @name       jsq-stickyNotes
// @namespace  sticky notes and jump over jsl xq
// @version v1
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js
// @description  Press "shift + left key" to add sticky notes in any webpage wherever you like
// @include      /^https?://*/
// @exclude      /^https?://www.baidu.com/*/
// @exclude      /^https?://www\.google\./
// @exclude      /^https?://\.bing\./
// @encoding    utf-8
// @grant        GM_xmlhttpRequest
// @grant       GM_registerMenuCommand
// @license      MIT license
// @run-at document-end
// ==/UserScript==
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

(function($) {

	$.fn.draggable = function(options) {
		var settings = $.extend({
			handle: undefined,
			msg: {},
			callfunction: function() {}
		}, options);
		var _eleFunc = function() {
			var x0, y0,
				ele = $(this),
				handle;
			handle = (settings.handle === undefined ? ele : ele.find(settings.handle).eq(0) === undefined ? ele : ele.find(settings.handle).eq(0));
			ele.css({
				position: "absolute"
			}); //make sure that the "postion" is "absolute"
			handle.bind('mousedown', function(e0) {
				handle.css({
					cursor: "move"
				}); //set the appearance of cursor
				x0 = ele.offset().left - e0.pageX; //*1
				y0 = ele.offset().top - e0.pageY; //*1
				$(document).bind('mousemove', function(e1) { //bind the mousemove event, caution:this event must be bind to "document"
					ele.css({
						left: x0 + e1.pageX,
						top: y0 + e1.pageY
					}); //this expression and the expression of *1 equal to "ele.origin_offset+mouse.current_offset-mouse.origin_offset"
				});
				$(document).one('mouseup', settings.msg, function(e) { //when the mouse up,unbind the mousemove event,bind only once
					settings.callfunction(e); //callback function
					$(document).unbind('mousemove');
					handle.css({
						cursor: "auto"
					});
				});
			});
		};
		return this.each(_eleFunc);
	};
})(jQuery);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////

var pNote = (function($) {
    const server = 'http://172.28.109.103:3000';
    var day = new Date();
    var mark = String(day.getFullYear()) + String(day.getMonth()) +String(day.getDate());
    console.log('pnote', mark);

    function getPost(flag, data = ''){
        return new Promise(res => {
        GM_xmlhttpRequest({
            method: flag,
            headers: { 'Content-Type': 'application/json', 'host': location.hostname },
            data: data,
            url: server,
            onload: (r) => {
                if(flag==='GET'){
                    if(r.response !== 'no'){localStorage.setItem('wxz-sto', r.response)}
                    //else { alert('no data')} // get 方法只会回传 no 或者 data数据
                }else if(flag === 'POST'){
                    if(r.response === 'ok'){
                        console.log('upload done');
                    }else if (r.response === 'err' || r.response === 'no' ){
                        alert('upload err'); // post方法会回传 ok no 或者 err 三种
                    }
                };
                res()
            }
        })
    })
    };

	function setCSS() {
		var css = '	<style type="text/css">\
	.wxz-noteDiv{\
	z-index:99;\
	box-shadow:0 0 9px rgba(0,0,0,.9);\
	background:#FFCC00;\
	width:200px;\
	position:absolute;\
    opacity:0.8;\
	outline:0 none;\
}\
.wxz-noteDiv-head{\
	background:#FFCC00;\
	outline:0 none;\
	text-align:center;\
	 width:200px;\
	 line-height: initial;\
	 font:13px/1.5 "微软雅黑",arial,serif;\
}\
.wxz-noteDiv-head-title{\
	text-align:center;\
}\
.wxz-noteDiv-head-close{\
	cursor:pointer;\
	position:absolute;\
	right:5px;\
}\
.wxz-noteDiv-content{\
	background:#FFFF66 ;\
	padding:5px 9px;\
	font:13px/1.5 "微软雅黑",arial,serif;\
	word-wrap:break-word;\
	min-height:200px;\
	outline:0 none;\
	text-align:left;\
}\
	</style>';
		$('head:first').append(css);
	}

	async function getSTO() {
		//import localStorage.mysto to stotage
		var sto;
        if (localStorage.getItem('down-note') !== mark){
            await getPost('GET');  //每天同步一次
            //console.log('test'); //测试是不是 变成同步模式了
            localStorage.setItem('down-note', mark);
        };
		if (localStorage.getItem('wxz-sto') !== null) {
			sto = JSON.parse(localStorage.getItem('wxz-sto'));
		} else {
			sto = {};
		}
		return sto;
	}

	function upDateSTO(storage) {
        var data = JSON.stringify(storage)
		localStorage.setItem('wxz-sto', data); //update localStorage.mysto with storage
        getPost('POST', data);
	}

	async function addNoteToStorage(keyName, x, y, text) {
        await getSTO().then(v => {
            var path = {},
			temp = {},
			storage = v; //just call for add notes  not for update or delete
            temp.keyName = keyName;
            temp.x = x;
            temp.y = y;
            temp.text = text;
            if (storage[location.pathname] !== undefined) {
                path = storage[location.pathname];
            }
            path[temp.keyName] = temp; //save notes to path
            storage[location.pathname] = path;
            upDateSTO(storage); //update local storage
            path = null;
            temp = null;
            storage = null;
        });
};


	async function removeNoteFromStorage(keyName) {
        await getSTO().then(v => {
            var path = {},
			storage = v;
            path = storage[location.pathname];
            if (path !== undefined) {
                delete path[keyName];
                if (Object.keys(path).length === 0) {
                    delete storage[location.pathname];
                } else {
                    storage[location.pathname] = path;
                }
                //update the localStorage.pathname
                upDateSTO(storage);
            }
            path = null;
            storage = null;
        });
	};

	function save(keyName) {
		var
			x, y, text,
			selector = "div[keyName='" + keyName + "']";
		x = $(selector).css('left');
		y = $(selector).css('top');
		text = $(selector).find('.wxz-noteDiv-content').html();
		addNoteToStorage(keyName, x, y, text);
		$(selector).find('.wxz-noteDiv-head-flag').text('');
	}

	function del(keyName) {
		if (confirm("Do you like to delete the note?")) {
			var selector = "div[keyName='" + keyName + "']";
			$(selector).remove();
			removeNoteFromStorage(keyName);
		}
	}

	function show(keyName, x, y, text) {
		var
			html = '<div class="wxz-noteDiv" >\
<div class="wxz-noteDiv-head">\
<nobr class="wxz-noteDiv-head-flag">*</nobr><nobr class="wxz-noteDiv-head-title"></nobr><nobr class="wxz-noteDiv-head-close">X</nobr>\
</div>\
<div class="wxz-noteDiv-content" contenteditable="true"></div>\
</div>',
			thisNote,
			tempTime = new Date(parseInt(keyName, 10));
		thisNote = $(html);
		thisNote.appendTo('body:first');
		thisNote.attr('keyName', keyName);
		thisNote.find('.wxz-noteDiv-head-title').html(tempTime.toDateString());
		//set the coordinate
		thisNote.css({
			position: 'absolute',
			top: y,
			left: x
		});
		//write text to content
		thisNote.find('.wxz-noteDiv-content').html(text);
		// draggable;
		thisNote.draggable({
				handle: '.wxz-noteDiv-head',
				msg: {
					msg: keyName
				},
				callfunction: function(e) {
					save(e.data.msg);
				}
			}
		);
		//bind click event
		thisNote.find('.wxz-noteDiv-head-close').bind('click', {
			msg: keyName
		}, function(e) {
			del(e.data.msg);
		});
		//save when it lost focus
		thisNote.focusout({
			msg: keyName
		}, function(e) {
			save(e.data.msg);
		});
		thisNote.focusin(function() {
			thisNote.find('.wxz-noteDiv-head-flag').text('*');
		});

	}

	async function loadNotes() {
        await getSTO().then(v => {
            var noteList;
            var storage =v;
            //console.log('oooo',storage );
            if (storage[location.pathname] !== undefined) {
                noteList = storage[location.pathname];
                $.each(noteList, function(i, e) {
                    show(e.keyName, e.x, e.y, e.text);
                });
                $('.wxz-noteDiv-head-flag').text('');
            }
            console.log('load notes successfully');
            },
            //e => alert(e) //能正常显示 ,也会报err,没找到原因。
        );
	}

	// function showNotes() {
	// 	$("wxz-noteDiv").css({
	// 		'display': 'inline'
	// 	});
	// }

	// function closeNotes() {
	// 	$("wxz-noteDiv").css({
	// 		'display': 'none'
	// 	});
	// }

	return {
		init: function() {
			setCSS();
			loadNotes();
			$("body").mousedown(function(e) {
				if (e.shiftKey) {
					var
						x = e.pageX,
						y = e.pageY,
						keyName = (new Date()).getTime();
					// keyName = e.timeStamp;//a bug in firefox since 2004
					e.preventDefault();
					show(keyName, x, y, '');
					console.log('new note');
				}
			});
			console.log('initialized successfully');
		}

	};

})(jQuery);

pNote.init();