html5sticky.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732
  1. /**
  2. * 笔记管理工具
  3. * @author zxlie
  4. */
  5. let stickywidth = 220; // width of sticky note (can't be less than 200)
  6. let stickyheight = 200; // height of sticky note (can't be less than 200)
  7. let max_notes = 10000; // maximum number of notes one can store
  8. let allowed_tags = '<br /><br><ol></ol><ul></ul><li></li><strong></strong><i></i>';
  9. let html5sticky = {};
  10. const STICKYNOTES_ALLKEYS = 'stickynotes|allkeys';
  11. const STICKYNOTES_FOLDERS = 'stickynotes|folders';
  12. const STICKYNOTES_SELECTED_FOLDER = 'stickynotes|selected|folder';
  13. // add a note
  14. html5sticky.addNote = function () {
  15. // count total present notes
  16. let tnotes = $('.note_common').length;
  17. if (tnotes === max_notes) {
  18. html5sticky.showMessage('#FFE16B', 'black', '当前便签笔记已经足够多了,不能再添加了!');
  19. return false;
  20. }
  21. // unique localstorage identifier for this sticky note
  22. let nindex = 'stickynote_' + (new Date * 1);
  23. let dated = getDateTime();
  24. let dateStr = new Date();
  25. // get random color
  26. let bgcolor = html5sticky.getColor();
  27. let folderId = html5sticky.getCurrentFolder()[1];
  28. let stickynote = $('<div class="note_common ' + bgcolor + '" />').appendTo($('#main'));
  29. // add tape to stickynote
  30. html5sticky.addPin(stickynote);
  31. $(stickynote).append($('<h2>' + dated + '</h2>'));
  32. $(stickynote).append($('<p></p>'));
  33. // append identifier
  34. $(stickynote).append($('<span id="idf_' + nindex + '" />'));
  35. // set width and height of the sticky note
  36. $('.note_common').css({width: stickywidth + 'px', height: stickyheight + 'px'});
  37. $('.note_common p').css({height: (stickyheight - 60) + 'px', width: (stickywidth + 9) + 'px'});
  38. // scroll to newly added sticky note
  39. $('html, body').animate({
  40. scrollTop: $(stickynote).offset().top
  41. });
  42. // 先存key,再存数据
  43. let allKeys = (localStorage.getItem(STICKYNOTES_ALLKEYS) || '').split(',');
  44. allKeys.push(nindex + '|text');
  45. allKeys.push(nindex + '|bgcolor');
  46. allKeys.push(nindex + '|dated');
  47. allKeys.push(nindex + '|folderid');
  48. localStorage.setItem(STICKYNOTES_ALLKEYS, allKeys.join(','));
  49. // 存数据
  50. localStorage.setItem(nindex + '|text', $(stickynote).find('h2').text() + '|' + $(stickynote).find('p').text());
  51. localStorage.setItem(nindex + '|bgcolor', bgcolor);
  52. localStorage.setItem(nindex + '|dated', dated + '|' + getISODateTime(dateStr));
  53. localStorage.setItem(nindex + '|folderid', folderId);
  54. html5sticky.enlargeNote(stickynote);
  55. html5sticky.updateNotesCountForFolder();
  56. };
  57. // save note
  58. html5sticky.saveNote = function (el) {
  59. let identifier = html5sticky.getIdentifier($(el));
  60. let htext = html5sticky.stripTags($(el).closest('.bignote').find('.hedit')[0].value, allowed_tags);
  61. let ptext = html5sticky.stripTags($(el).closest('.bignote').find('.pedit')[0].value, allowed_tags);
  62. ptext = ptext.replace(/\r?\n/g, '<br />');
  63. localStorage.setItem(identifier + '|text', htext + '|' + ptext);
  64. let theNoteEl = $('[id^=idf_' + identifier + ']').closest('.note_common');
  65. theNoteEl.find('h2').text(htext);
  66. theNoteEl.find('p').html(ptext);
  67. let oldFolder = localStorage.getItem(identifier + '|folderid') || 0;
  68. let newFolder = $(el).closest('.bignote').find('.fedit')[0].value;
  69. localStorage.setItem(identifier + '|folderid', newFolder);
  70. html5sticky.closeNote(el);
  71. html5sticky.showMessage('#9BED87', 'black', '笔记保存成功!');
  72. // 发生了文件夹变更
  73. if (String(oldFolder) !== String(newFolder)) {
  74. theNoteEl.fadeOut('slow', function () {
  75. theNoteEl.remove();
  76. if (!$(".note_common").length > 0) {
  77. $('#removenotes').slideUp('slow');
  78. }
  79. });
  80. html5sticky.updateNotesCountForFolder();
  81. }
  82. };
  83. html5sticky.updateNotesCountForFolder = function () {
  84. // 刷新folder计数
  85. let allKeys = (localStorage.getItem(STICKYNOTES_ALLKEYS) || '').split(',');
  86. let folders = html5sticky.loadFolders();
  87. Object.keys(folders).forEach(f => {
  88. let counter = allKeys.filter(key => /\|folderid/.test(key) && (String(folders[f]) === (localStorage.getItem(key) || '0'))).length;
  89. $('#f_' + folders[f]).find('i').text('(' + counter + ')');
  90. });
  91. };
  92. // get note identifier
  93. html5sticky.getIdentifier = function (el) {
  94. if (!el) {
  95. return 'stickynote_' + (new Date * 1 + Math.floor(Math.random() * 10));
  96. }
  97. let identifier = $(el).closest('.bignote').find('[id^=idf_]').attr('id');
  98. if (typeof identifier == 'undefined' || identifier == null) {
  99. identifier = $(el).closest('.note_common').find('[id^=idf_]').attr('id');
  100. }
  101. if (typeof identifier != 'undefined') {
  102. identifier = identifier.replace('idf_', '');
  103. return identifier;
  104. }
  105. else {
  106. return false;
  107. }
  108. };
  109. html5sticky.deleteNoteById = function (identifier) {
  110. localStorage.removeItem(identifier);
  111. localStorage.removeItem(identifier + '|text');
  112. localStorage.removeItem(identifier + '|bgcolor');
  113. localStorage.removeItem(identifier + '|dated');
  114. localStorage.removeItem(identifier + '|folderid');
  115. let allKeys = (localStorage.getItem(STICKYNOTES_ALLKEYS) || '').split(',');
  116. ['text', 'bgcolor', 'dated', 'folderid'].forEach(function (item) {
  117. let id = identifier + '|' + item;
  118. allKeys.indexOf(id) > -1 && allKeys.splice(allKeys.indexOf(id), 1);
  119. });
  120. localStorage.setItem(STICKYNOTES_ALLKEYS, allKeys.join(','));
  121. };
  122. // delete note
  123. html5sticky.deleteNote = function (el) {
  124. if (confirm('确定要删除这个便签笔记吗,一旦删除则不可恢复,请三思?')) {
  125. let identifier = html5sticky.getIdentifier($(el));
  126. html5sticky.deleteNoteById(identifier);
  127. $(el).closest('.note_common').fadeOut('slow', function () {
  128. $(el).closest('.note_common').remove();
  129. });
  130. }
  131. };
  132. // delete all notes
  133. html5sticky.deleteAllNotes = function () {
  134. if (confirm('建议删除之前先【全部导出】,否则一旦删除则不可恢复,请三思?')) {
  135. $('.note_common').fadeOut('slow', function () {
  136. $('.note_common').remove();
  137. let allKeys = (localStorage.getItem(STICKYNOTES_ALLKEYS) || '').split(',');
  138. allKeys.forEach(function (key) {
  139. localStorage.removeItem(key);
  140. });
  141. localStorage.removeItem(STICKYNOTES_ALLKEYS);
  142. html5sticky.deleteAllFolders();
  143. location.reload(true);
  144. });
  145. }
  146. };
  147. // close big note
  148. html5sticky.closeNote = function (el) {
  149. $(el).closest('.bignote')[html5sticky.getAnimation(true)]('slow', function () {
  150. $('#overlay').remove();
  151. });
  152. };
  153. // edit note
  154. html5sticky.editNote = function ($clone, el) {
  155. let ptext = $clone.find('p').html();
  156. ptext = ptext.replace(/(<br \/>|<br>)/g, '\n');
  157. $clone.find('p').replaceWith('<textarea class="pedit" placeholder="在这里添加笔记" />');
  158. $clone.find('.pedit')
  159. .val(ptext)
  160. .css({
  161. 'marginTop': '5px',
  162. 'resize': 'none',
  163. 'outline': 'none'
  164. })
  165. .addClass('inset')
  166. .width('568px')
  167. .height('280px');
  168. // make content editable
  169. let htext = $clone.find('h2').text();
  170. $clone.find('h2').replaceWith('<input type="text" class="hedit" />');
  171. $('.hedit').addClass('inset').val(html5sticky.stripTags(htext, allowed_tags)).width(250);
  172. // folder-list
  173. let folders = html5sticky.loadFolders();
  174. let folderid = localStorage.getItem($clone.find('span[id^="idf_"]').attr('id').replace('idf_', '') + '|folderid') || '0';
  175. $('.hedit').after('<select class="fedit form-control">' + Object.keys(folders).map(f => {
  176. return `<option value="${folders[f]}" ${folders[f] == folderid ? 'selected' : ''}>${f}</option>`
  177. }).join('') + '</select>');
  178. // put in Close button
  179. $(`<a href="#" class="close_stickynote x-btn-min">关闭</a>`)
  180. .css({
  181. position: 'absolute',
  182. top: 5,
  183. right: 5,
  184. color: '#000'
  185. })
  186. .appendTo($clone);
  187. // put in Save button
  188. $(`<a href="#" class="save_stickynote x-btn-min">保存</a>`)
  189. .css({
  190. position: 'absolute',
  191. top: 5,
  192. right: 40,
  193. color: '#000'
  194. })
  195. .appendTo($clone);
  196. };
  197. html5sticky.getNotesByFolderId = function (folderId) {
  198. // load notes
  199. let allKeys = (localStorage.getItem(STICKYNOTES_ALLKEYS) || '').split(',');
  200. let result = [];
  201. allKeys.forEach(key => {
  202. if (!/\|text/.test(key)) {
  203. return false;
  204. }
  205. let id = key.replace('|text', '');
  206. // 按照folder id寻找对应目录下的便签
  207. let folderid = localStorage.getItem(id + '|folderid') || '0';
  208. if (String(folderId) !== folderid) {
  209. return false;
  210. }
  211. result.push(id);
  212. });
  213. return result;
  214. };
  215. // load all notes
  216. html5sticky.loadNotes = function (folderId) {
  217. let mainEl = $('#main').html('');
  218. let notes = html5sticky.getNotesByFolderId(folderId);
  219. notes.forEach(id => {
  220. let stickynote, bgcolor, htext, ptext, temp_array;
  221. // get color and rotation level
  222. bgcolor = localStorage.getItem(id + '|bgcolor');
  223. // get text info
  224. temp_array = localStorage.getItem(id + '|text').split('|');
  225. htext = temp_array[0];
  226. ptext = temp_array[1];
  227. stickynote = $('<div class="note_common ' + bgcolor + '" />').appendTo(mainEl);
  228. html5sticky.addPin(stickynote);
  229. $(stickynote).append($('<h2></h2>'));
  230. $(stickynote).append($('<p></p>'));
  231. // append identifier
  232. $(stickynote).append($('<span id="idf_' + id + '" />'));
  233. $(stickynote).find('h2').text(html5sticky.stripTags(htext, allowed_tags));
  234. $(stickynote).find('p').html(html5sticky.stripTags(ptext, allowed_tags));
  235. // set width and height of the sticky note
  236. $('.note_common').css({width: stickywidth + 'px', height: stickyheight + 'px'});
  237. $('.note_common p').css({height: (stickyheight - 60) + 'px', width: (stickywidth - 24) + 'px'});
  238. });
  239. $('#f_' + folderId).find('i').text('(' + notes.length + ')');
  240. };
  241. // collapse notes
  242. html5sticky.collapse = function () {
  243. let height = parseInt($('.note_common:first').find('h2').height() || 0, 10) + 'px';
  244. $('.note_common').animate({height: height}, function () {
  245. $('.note_common').find('p').hide();
  246. });
  247. };
  248. // expand notes
  249. html5sticky.expand = function () {
  250. $('.note_common').animate({height: stickyheight}, function () {
  251. $('.note_common').find('p').fadeIn('slow');
  252. });
  253. };
  254. // share note
  255. html5sticky.showMessage = function (bgcolor, color, msg, callback) {
  256. if (!$('#smsg').is(':visible')) {
  257. $('html, body').animate({
  258. scrollTop: 0
  259. }, 500, function () {
  260. if (!$('#smsg').length) {
  261. $('<div id="smsg">' + msg + '</div>').appendTo($('body')).css({
  262. position: 'absolute',
  263. top: 0,
  264. left: 0,
  265. right: 0,
  266. height: '40px',
  267. lineHeight: '40px',
  268. background: bgcolor,
  269. color: color,
  270. zIndex: 1000,
  271. fontWeight: 'bold',
  272. textAlign: 'center',
  273. opacity: 0.9,
  274. margin: 'auto',
  275. display: 'none'
  276. }).slideDown('show');
  277. setTimeout(function () {
  278. $('#smsg').animate({'width': 'hide'}, function () {
  279. $('#smsg').remove();
  280. callback && callback();
  281. });
  282. }, 2000);
  283. }
  284. });
  285. }
  286. };
  287. // get random color
  288. html5sticky.getColor = function () {
  289. let text = "";
  290. let possible = "0123456789";
  291. text += possible.charAt(Math.floor(Math.random() * possible.length));
  292. return 'stickynote' + text;
  293. };
  294. // get random animation string
  295. html5sticky.getAnimation = function (hideAnimation) {
  296. let words = [];
  297. if (typeof hideAnimation !== 'undefined') {
  298. words[1] = "hide";
  299. words[2] = "fadeOut";
  300. words[3] = "slideUp";
  301. }
  302. else {
  303. words[1] = "show";
  304. words[2] = "fadeIn";
  305. words[3] = "slideDown";
  306. }
  307. // Generate a random number between 1 and 3
  308. let rnd = Math.ceil(Math.random() * 3);
  309. return words[rnd];
  310. };
  311. // add pin to note
  312. html5sticky.addPin = function (el) {
  313. let close = $(`<div class="btn-close"><a href="#" class="delete_stickynote x-btn-min">删除</a></div>`);
  314. let tag = $(`<div align="center"><img pin-png src="${html5sticky.images['pin.png']}" alt=""></div>`);
  315. $(close).css({
  316. position: 'absolute',
  317. top: -15,
  318. right: -15
  319. }).hide().prependTo($(el));
  320. $(tag).css({
  321. position: 'absolute',
  322. zIndex: 99,
  323. top: -15,
  324. left: parseInt(stickywidth / 2, 10) - 10
  325. }).prependTo($(el));
  326. };
  327. // enlarge note for editing
  328. html5sticky.enlargeNote = function (el) {
  329. $this = $(el);
  330. // create overlay
  331. $('<div id="overlay" />').css({
  332. position: 'fixed',
  333. background: 'rgba(0,0,0,0.5)',
  334. top: '0',
  335. left: '0',
  336. width: '100%',
  337. height: '100%',
  338. zIndex: '100'
  339. }).appendTo($('body'));
  340. $clone = $(el).clone().removeClass('note_common').addClass('bignote').appendTo($('#overlay'));
  341. // remove the pin
  342. $clone.find($('img[pin-png]').closest('div')).hide();
  343. $($clone).css({
  344. position: 'absolute',
  345. zIndex: 500,
  346. cursor: 'default',
  347. paddingTop: '5px',
  348. width: '600px',
  349. height: '376px',
  350. top: '50%',
  351. left: '50%',
  352. display: 'none',
  353. marginLeft: '-300px',
  354. marginTop: '-200px'
  355. });
  356. $($clone)[html5sticky.getAnimation()](400);
  357. // add date and time info
  358. let dateStr = '', dateAgo = '';
  359. let identifier = html5sticky.getIdentifier($(el));
  360. let dateTime = localStorage.getItem(identifier + '|dated');
  361. let timeImg = `<img class="left" align="absmiddle" time-png src="${html5sticky.images['time.png']}">`;
  362. dateStr = dateTime.split('|')[0];
  363. dateAgo = prettyDate(dateTime.split('|')[1]);
  364. dateStr = (dateStr.length > 0) ? '创建于:' + dateStr : '';
  365. dateAgo = (dateAgo.length > 0) ? ' (' + dateAgo + ')' : '';
  366. timeImg = (dateStr.length > 0) ? timeImg : '';
  367. $('<div class="timeago left" />').prependTo($clone);
  368. $('.timeago').css({fontSize: '12px', fontFamily: 'tahoma'})
  369. .html(timeImg + '&nbsp;&nbsp;' + dateStr + dateAgo)
  370. .after('<div class="clear" />');
  371. // hide the utility buttons
  372. $($clone).find('.icons-footer').hide();
  373. // make content editable
  374. html5sticky.editNote($clone, el);
  375. };
  376. // http://phpjs.org/functions/strip_tags:535
  377. html5sticky.stripTags = function (input, allowed) {
  378. allowed = (((allowed || "") + "").toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join('');
  379. let tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi,
  380. commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi;
  381. return input.replace(commentsAndPhpTags, '').replace(tags, function ($0, $1) {
  382. return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '';
  383. });
  384. };
  385. // 全部notes导出到本地
  386. html5sticky.export = function () {
  387. let allKeys = (localStorage.getItem(STICKYNOTES_ALLKEYS) || '').split(',');
  388. let zipper = null;
  389. if (allKeys.length) {
  390. zipper = new JSZip();
  391. }
  392. let zpFolder = {};
  393. allKeys.forEach(key => {
  394. if (!/\|text/.test(key)) {
  395. return false;
  396. }
  397. let id = key.replace('|text', '');
  398. let dated, htext, ptext, temp_array, folderid;
  399. dated = localStorage.getItem(id + '|dated');
  400. folderid = localStorage.getItem(id + '|folderid') || '0';
  401. if (!zpFolder[folderid]) {
  402. let forderName = html5sticky.findFolderNameById(folderid);
  403. zpFolder[folderid] = zipper.folder(forderName);
  404. }
  405. // get text info
  406. temp_array = localStorage.getItem(id + '|text').split('|');
  407. htext = temp_array[0];
  408. ptext = temp_array[1];
  409. zpFolder[folderid].file(htext + '.txt', [
  410. '# title:' + htext,
  411. '# date:' + dated,
  412. '# content:\n' + ptext
  413. ].join('\n\n'));
  414. });
  415. if (zipper) {
  416. zipper.generateAsync({type: "blob"})
  417. .then(function (content) {
  418. let elA = document.createElement('a');
  419. elA.style.cssText = 'position:absolute;top:-1000px;left:-10000px;';
  420. elA.setAttribute('download', '我的便签笔记-' + (new Date * 1) + '.zip');
  421. elA.href = URL.createObjectURL(new Blob([content], {type: 'application/octet-stream'}));
  422. document.body.appendChild(elA);
  423. elA.click();
  424. });
  425. }
  426. };
  427. // 导入笔记
  428. html5sticky.importNotes = function () {
  429. let Model = (function () {
  430. zip.useWebWorkers = false;
  431. let URL = window.webkitURL || window.mozURL || window.URL;
  432. return {
  433. getEntries: function (file, onend) {
  434. zip.createReader(new zip.BlobReader(file), function (zipReader) {
  435. zipReader.getEntries(onend);
  436. }, function (e) {
  437. console.log(e);
  438. });
  439. },
  440. getEntryFile: function (entry, onend, onprogress) {
  441. entry.getData(new zip.TextWriter(), function (text) {
  442. onend(text);
  443. }, onprogress);
  444. }
  445. };
  446. })();
  447. let fileInput = document.createElement('input');
  448. fileInput.type = 'file';
  449. fileInput.accept = 'application/zip';
  450. fileInput.style.cssText = 'position:absolute;top:-100px;left:-100px';
  451. fileInput.addEventListener('change', function (evt) {
  452. Model.getEntries(fileInput.files[0], function (entries) {
  453. let counter = 0;
  454. let size = entries.filter((entry) => !entry.directory).length;
  455. entries.forEach(function (entry) {
  456. if (entry.directory) {
  457. counter++;
  458. let fname = entry.filename.replace(/\//, '');
  459. let folders = html5sticky.loadFolders();
  460. if (!folders[fname]) {
  461. html5sticky.saveFolder(fname, new Date().getTime());
  462. }
  463. } else {
  464. Model.getEntryFile(entry, function (text) {
  465. let identifier = html5sticky.getIdentifier();
  466. let htext = text.split('# date:')[0].split('# title:')[1].trim();
  467. let dtext = text.split('# date:')[1].split('# content:')[0].trim();
  468. let ptext = text.split('# content:')[1].trim().replace(/\r?\n/g, '<br />');
  469. let folderId = html5sticky.findFolderByName(entry.filename.split('/')[0]);
  470. // 先存key,再存数据
  471. let allKeys = (localStorage.getItem(STICKYNOTES_ALLKEYS) || '').split(',');
  472. allKeys.push(identifier + '|text');
  473. allKeys.push(identifier + '|bgcolor');
  474. allKeys.push(identifier + '|dated');
  475. allKeys.push(identifier + '|folderid');
  476. localStorage.setItem(STICKYNOTES_ALLKEYS, allKeys.join(','));
  477. localStorage.setItem(identifier + '|text', htext + '|' + ptext);
  478. localStorage.setItem(identifier + '|bgcolor', html5sticky.getColor());
  479. localStorage.setItem(identifier + '|dated', dtext);
  480. localStorage.setItem(identifier + '|folderid', folderId);
  481. counter++;
  482. if (counter === size) {
  483. html5sticky.showMessage('#9BED87', 'black', '操作成功!共导入' + counter + '条笔记!', () => {
  484. location.reload();
  485. });
  486. }
  487. });
  488. }
  489. });
  490. });
  491. }, false);
  492. document.body.appendChild(fileInput);
  493. fileInput.click();
  494. };
  495. html5sticky.buildFoldersAndInitNotes = function () {
  496. let folders = html5sticky.loadFolders();
  497. Object.keys(folders).forEach((f, idx) => {
  498. html5sticky.createFolder(f, folders[f]);
  499. html5sticky.loadNotes(folders[f]);
  500. });
  501. let current = html5sticky.getCurrentFolder();
  502. let folderId = current[1];
  503. if (!$('li#f_' + folderId).length) {
  504. folderId = folders[Object.keys(folders)[0]];
  505. }
  506. $('li#f_' + folderId).addClass('x-selected');
  507. html5sticky.loadNotes(folderId);
  508. };
  509. html5sticky.loadFolders = function () {
  510. let folders = JSON.parse(localStorage.getItem(STICKYNOTES_FOLDERS) || '{}') || {};
  511. if (!folders['默认文件夹']) {
  512. folders['默认文件夹'] = '0';
  513. }
  514. return folders;
  515. };
  516. html5sticky.deleteAllFolders = function () {
  517. localStorage.setItem(STICKYNOTES_FOLDERS, '{}');
  518. localStorage.setItem(STICKYNOTES_SELECTED_FOLDER, '[]')
  519. };
  520. /**
  521. * 保存、更新、删除 三合一的方法
  522. * @param folder 不为空时才进行保存
  523. * @param fId 文件夹ID
  524. * @param oldFolder 不为空时,表示要删除
  525. */
  526. html5sticky.saveFolder = function (folder, fId, oldFolder) {
  527. let folders = html5sticky.loadFolders();
  528. if (folder) {
  529. folders[folder] = fId;
  530. }
  531. if (oldFolder) {
  532. delete folders[oldFolder];
  533. }
  534. localStorage.setItem(STICKYNOTES_FOLDERS, JSON.stringify(folders));
  535. };
  536. html5sticky.createFolder = function (folder, fId) {
  537. folder = folder || window.prompt('新建文件夹');
  538. if (folder) {
  539. if (!fId) {
  540. let folders = html5sticky.loadFolders();
  541. if (folders[folder]) {
  542. return alert('你已经创建过这个文件夹!');
  543. }
  544. }
  545. fId = fId || new Date().getTime();
  546. html5sticky.saveFolder(folder, fId);
  547. let elFd = $('<li><span></span><i>(0)</i><a class="btn-delete">删除</a><a class="btn-rename">重命名</a></li>').find('span').text(folder).end().attr('id', 'f_' + fId).appendTo('#folders');
  548. elFd.find('a.btn-rename').click(e => {
  549. e.stopPropagation();
  550. let fname = window.prompt('新的文件夹名称');
  551. if (fname && fname !== folder) {
  552. html5sticky.saveFolder(fname, fId, folder);
  553. elFd.find('span').text(fname);
  554. }
  555. });
  556. elFd.find('a.btn-delete').click(e => {
  557. e.stopPropagation();
  558. let count = parseInt(elFd.find('i').text().replace(/\W/g, ''));
  559. if (count && !window.confirm('当前文件夹下包含【' + count + '】个便签,建议先将笔记挪到其他文件夹再进行删除!如果你想暴力删除,那你可以继续了!!!')) {
  560. return false;
  561. }
  562. // 删文件夹
  563. html5sticky.saveFolder(null, fId, folder);
  564. elFd.remove();
  565. // 删笔记
  566. let notes = html5sticky.getNotesByFolderId(fId);
  567. notes.forEach(noteId => html5sticky.deleteNoteById(noteId));
  568. $('#main').html('');
  569. html5sticky.showMessage('#9BED87', 'black', '文件夹已删除成功!笔记本将重新加载!');
  570. setTimeout(() => {location.reload(true);},2000);
  571. });
  572. return elFd;
  573. } else if (folder !== null) {
  574. return alert('文件夹名不能为空!');
  575. }
  576. };
  577. html5sticky.getCurrentFolder = function () {
  578. let folder = JSON.parse(localStorage.getItem(STICKYNOTES_SELECTED_FOLDER) || '[]') || [];
  579. if (!folder.length) {
  580. folder = ['默认文件夹', '0'];
  581. }
  582. return folder;
  583. };
  584. html5sticky.setCurrentFolder = function (txt, id) {
  585. localStorage.setItem(STICKYNOTES_SELECTED_FOLDER, JSON.stringify([txt, id]));
  586. };
  587. html5sticky.findFolderNameById = function (folderId) {
  588. let folders = html5sticky.loadFolders();
  589. let arr = Object.keys(folders).filter(f => String(folders[f]) === String(folderId));
  590. return arr.length ? arr[0] : '默认文件夹';
  591. };
  592. html5sticky.findFolderByName = function (name) {
  593. let folders = JSON.parse(localStorage.getItem(STICKYNOTES_FOLDERS) || '{}') || {};
  594. if (!folders['默认文件夹']) {
  595. folders['默认文件夹'] = '0';
  596. }
  597. return folders[name];
  598. };
  599. html5sticky.images = {
  600. 'pin.png': 'data:image/png;base64,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',
  601. 'time.png': 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACpklEQVQ4EXVTXUiTYRR+1dV90GUXIXRTGGVEF0EtC2GCZdlkQTf+pPtseNNVeiOERFgSBlJQYbpkVqT5sx/ndLNM5zb37dvn9jk156ZjIZYlROK7PfFON7esA4fzvN95znPOy/leQvZaFiGEObP/4Z30bsh6o1TmjMrlsuQnZ3X1vn9hxmHctCapbtv8o8XHSF5RXuLAYjpmuUxLTiqXaRRlrW3XblibS1TWRyWqsWelKj2LzSWqj2nYyjgaxfVWQnanJbKTl89JVRWI1VXiu7oc61w5YnVViZiOWY5xGJfVpIaR5SsKtJU1MGo0mwaulhpqb9MBde2WXq2meo6jA2puG6s5auC4TW1FDWT5xQUpAULIBZvdgfnlZSrOL2Bm4QukYBCBUBizSyEEmIfC8C8uYin6ldrsTrCaDAGPR8D6tzUaWVnB2uoqRK8Io9GMz+MTCTcYTODdbgwPmanL6WIClzIEpnkPotEoDYVCCIeXEQjMwelywyvOQPCK8PklOHkfhsYcsUkHD3LoyJkMAVH0oefDAJ20O6B724Mphwt6oxmj1jFYRm0Yn7DDoK2PO/rq0fWiObb/YtPxdAG5mxfgEbzUL0lwuqYhSbOYcjgRiURgHh6Jv3zaBqvuDuLBGhpfuAVtS6mPkFOpn60wMDcPk9myyfMC7dcbKRPr7RukGxs/Y686OuGzW+LvdV3QPb4Kl/7+1rRFC5JzVpGcIrfzdfcvaTYAN+9J3JkXvPAIIniPF+3tHXHPuAk++wgd7HkXFyZsv22mfhByICGQvaOSSwgp3FkP2zFbEzufOF10s8zY240lcRKLwies+KfwoOmeRAhJvZ2kSHKiPTHv/JXyJy0Pgx3P23403G2wEEIO/0VqzFYqlTn/cqAx2YC9woNphdl/AEtNsQjc350zAAAAAElFTkSuQmCC'
  602. };