diff --git a/nullboard.html b/nullboard.html
index f062cfe..307fbe2 100644
--- a/nullboard.html
+++ b/nullboard.html
@@ -89,8 +89,15 @@
-moz-user-select: none;
}
+ @keyframes shake {
+ 33% { margin-left: -5px; }
+ 66% { margin-left: 5px; }
+ 100% { margin-left: 0px; }
+ }
+
body.ding {
- padding-top: 2px;
+ animation-name: shake;
+ animation-duration: 200ms;
}
a {
@@ -803,55 +810,55 @@
/*
* Dark mode
*/
- body.dark {
+ body.theme-dark {
background-color: #15171A;
color: #d6d6d6;
}
- .dark .board .head {
+ .theme-dark .board .head {
background: #202224;
}
/***/
- .dark .board .menu {
+ .theme-dark .board .menu {
background: linear-gradient(to right, #20222400, #202224 10px);
}
- .dark .board .menu a {
+ .theme-dark .board .menu a {
color: #aaa;
}
- .dark .board .menu a:hover {
+ .theme-dark .board .menu a:hover {
color: #fc4;
}
- .dark .board .menu a.warn:hover,
- .dark .board .ops a.warn:hover {
+ .theme-dark .board .menu a.warn:hover,
+ .theme-dark .board .ops a.warn:hover {
color: #fc5555 !important;
}
- .dark .board .head {
+ .theme-dark .board .head {
color: #eee;
}
- .dark .board .head .edit::placeholder {
+ .theme-dark .board .head .edit::placeholder {
color: #bf9d21;
}
/***/
- .dark .board .list {
+ .theme-dark .board .list {
background: #202224;
}
- .dark .board .note {
+ .theme-dark .board .note {
background: #2B2C2F;
background: linear-gradient(#2B2C2F, #27282B);
box-shadow: 0 1px 3px #0005;
text-shadow: 0 0 4px #0008;
}
- .dark.reveal .board .head .text a,
- .dark.reveal .board .note .text a {
+ .theme-dark.reveal .board .head .text a,
+ .theme-dark.reveal .board .note .text a {
color: #fc0;
}
@@ -861,46 +868,46 @@
100% { color: inherit; }
}
- .dark .board .head .text a:hover,
- .dark .board .note .text a:hover {
+ .theme-dark .board .head .text a:hover,
+ .theme-dark .board .note .text a:hover {
animation-name: whoomp-dark;
}
- .dark .board .note.raw {
+ .theme-dark .board .note.raw {
background: transparent;
box-shadow: none;
}
- .dark .board .note.raw .text {
+ .theme-dark .board .note.raw .text {
color: #eee;
text-shadow: 0 0 4px #0008;
}
- .dark .board .note .ops .teaser {
+ .theme-dark .board .note .ops .teaser {
color: #ccc;
}
- .dark .board .note .ops .bulk {
+ .theme-dark .board .note .ops .bulk {
background: #202224;
border-left: 1px solid #111;
border-bottom: 1px solid #111;
}
- .dark .board .note.raw .ops .bulk {
+ .theme-dark .board .note.raw .ops .bulk {
border: none;
}
- .dark .board .note .ops .bulk a {
+ .theme-dark .board .note .ops .bulk a {
color: #ccc;
}
- .dark .board .note .ops .bulk a:hover {
+ .theme-dark .board .note .ops .bulk a:hover {
color: #fc2;
}
- .dark .board .note.dragging,
- .dark .board .note.dragging.raw {
+ .theme-dark .board .note.dragging,
+ .theme-dark .board .note.dragging.raw {
background: #15171A;
box-shadow: 0 +1px 0 #000 inset,
0 -1px 0 #000 inset,
@@ -908,195 +915,195 @@
-1px 0 0 #000 inset;
}
- .dark .dragster {
+ .theme-dark .dragster {
box-shadow: 0px 1px 4px #000000;
background: #2e3032;
}
- .dark .dragster a {
+ .theme-dark .dragster a {
color: #d6d6d6;
}
/***/
- .dark textarea,
- .dark input {
+ .theme-dark textarea,
+ .theme-dark input {
background: #111315;
color: #eee;
}
- .dark .board .head.editing .edit {
+ .theme-dark .board .head.editing .edit {
outline: 1px solid #bc9908;
}
- .dark .board .note.editing {
+ .theme-dark .board .note.editing {
background: #111315;
outline: 1px solid #bc9908;
}
/***/
- .dark .config, .dark.crowded .config:hover {
+ .theme-dark .config, .theme-dark.crowded .config:hover {
background-color: #15171A;
}
- .dark .config a {
+ .theme-dark .config a {
color: #ddd;
}
- .dark .config a:hover {
+ .theme-dark .config a:hover {
color: #fc2;
}
- .dark .config .bulk div {
+ .theme-dark .config .bulk div {
border-top: 1px solid #fff2;
border-bottom: 1px solid #fff2;
}
- .dark .config .bulk div a.active {
+ .theme-dark .config .bulk div a.active {
color: #fc2;
}
- .dark .config .bulk a.switch-theme {
+ .theme-dark .config .bulk a.switch-theme {
border-top: 1px solid #fff2;
}
- .dark .config a.switch-theme i {
+ .theme-dark .config a.switch-theme i {
display: inline;
}
- .dark .config a.switch-theme b {
+ .theme-dark .config a.switch-theme b {
display: none;
}
/***/
- .dark .logo a {
+ .theme-dark .logo a {
color: #ccc;
}
- .dark .logo, .dark.crowded .logo:hover {
+ .theme-dark .logo, .theme-dark.crowded .logo:hover {
background: #15171A;
}
- .dark .logo a:hover {
+ .theme-dark .logo a:hover {
color: #fc2;
}
- .dark .logo > a:hover {
+ .theme-dark .logo > a:hover {
color: #fff;
}
/*
* Larger font
*/
- body.z1,
- body.z1 input,
- body.z1 textarea {
+ body.fsize-z1,
+ body.fsize-z1 input,
+ body.fsize-z1 textarea {
font-size: 15px;
}
- .z1 .board {
+ .fsize-z1 .board {
min-width: 290px;
}
- .z1 .board u:before {
+ .fsize-z1 .board u:before {
font-size: 19px;
line-height: 12px;
}
- .z1 .board .head .text {
+ .fsize-z1 .board .head .text {
min-height: 22px;
}
- .z1 .board .head .text,
- .z1 .board .head .edit {
+ .fsize-z1 .board .head .text,
+ .fsize-z1 .board .head .edit {
font-size: 15px;
line-height: 22px;
}
- .z1 .board .head .edit::placeholder {
+ .fsize-z1 .board .head .edit::placeholder {
font-size: 10px;
line-height: 23px;
}
- .z1 .board .menu {
+ .fsize-z1 .board .menu {
height: 22px;
font-size: 13px;
line-height: 22px;
}
- .z1 .board .list {
+ .fsize-z1 .board .list {
width: 290px;
}
- .z1 .board .note .text,
- .z1 .board .note .edit,
- .z1 .dragster {
+ .fsize-z1 .board .note .text,
+ .fsize-z1 .board .note .edit,
+ .fsize-z1 .dragster {
font-size: 13px;
}
- .z1 .board .note .text {
+ .fsize-z1 .board .note .text {
min-height: 16px;
}
- .z1 .board .note.collapsed {
+ .fsize-z1 .board .note.collapsed {
height: 26px;
}
- .z1 .board .note.collapsed .text {
+ .fsize-z1 .board .note.collapsed .text {
height: 17px;
line-height: 25px;
}
- .z1 .dragster.collapsed {
+ .fsize-z1 .dragster.collapsed {
line-height: 24px;
}
- .z1 .board .note .ops {
+ .fsize-z1 .board .note .ops {
font-size: 10px;
}
/***/
- .z1 .logo {
+ .fsize-z1 .logo {
font-size: 13px;
line-height: 21px;
}
- .z1 .logo .bulk a:before {
+ .fsize-z1 .logo .bulk a:before {
width: 13px;
}
/***/
- .z1 .config {
+ .fsize-z1 .config {
font-size: 13px;
line-height: 21px;
}
- .z1 .config .bulk div a.active:before {
+ .fsize-z1 .config .bulk div a.active:before {
width: 15px;
}
- .z1 .config a.switch-fsize i {
+ .fsize-z1 .config a.switch-fsize i {
display: inline;
}
- .z1 .config a.switch-fsize b {
+ .fsize-z1 .config a.switch-fsize b {
display: none;
}
/***/
- .z1 .overlay .license {
+ .fsize-z1 .overlay .license {
font-size: 14px;
line-height: 18px;
width: 443px;
}
- .z1 .overlay .about {
+ .fsize-z1 .overlay .about {
font-size: 12px;
line-height: 18px;
width: 277px;
}
- .z1 .overlay .about h1 {
+ .fsize-z1 .overlay .about h1 {
font-size: 17px;
width: 277px;
}
@@ -1210,36 +1217,443 @@
+
+
+
-// function htmlDecode(enc)
-// {
-// return $('tt .encoder').html(enc).text();
-// }
-
- function setText($note, text)
- {
- $note.attr('_text', text);
-
- text = htmlEncode(text);
- hmmm = /\b(https?:\/\/[^\s]+)/mg;
-
- text = text.replace(hmmm, function(url){
- return '' + url + '';
- });
-
- $note.html(text);
- }
-
- function getText($note)
- {
- return $note.attr('_text');
- }
-
- /*
- * board ops - save/load/parse/peek/nuke/import
- */
- function saveBoard()
- {
- var $board = $('.wrap .board');
- var board = new Board( getText($board.find('> .head .text')) );
-
- $board.find('.list').each(function(){
- var $list = $(this);
- var l = board.addList( getText($list.find('.head .text')) );
-
- $list.find('.note').each(function(){
- var $note = $(this)
- var n = l.addNote( getText($note.find('.text')) );
- n.raw = $note.hasClass('raw');
- n.min = $note.hasClass('collapsed');
- });
- });
-
- //
- var rev_new = document.nb.board.history[0] + 1;
- var rev_old = document.nb.board.revision;
-
- document.nb.board.revision = rev_new;
-
- board.id = document.nb.board.id;
- board.revision = document.nb.board.revision;
-
- var blob_id = board.id + '.' + board.revision;
-
- localStorage.setItem('nullboard.board.' + blob_id, JSON.stringify(board));
- localStorage.setItem('nullboard.board.' + board.id, board.revision);
- console.log('Saved nullboard.board.' + blob_id + ' of ' + board.title);
-
- //
- trimBoardHistory(rev_old, rev_new, 50);
-
- updateUndoRedo();
- updateBoardIndex();
- }
-
- function parseBoard(blob)
- {
- var board;
-
- try
- {
- board = JSON.parse(blob);
- }
- catch(x)
- {
- console.log('Malformed JSON');
- return false;
- }
-
- if (typeof board.format === 'undefined')
- {
- console.log('Board.format is missing');
- return false;
- }
-
- if (board.format != document.nb.dataVersion)
- {
- console.log('Board.format is wrong', board.format, document.nb.dataVersion);
- return false;
- }
-
- if (! board.revision)
- {
- console.log("Board.revision is missing");
- return false;
- }
-
- return $.extend(new Board, board);
- }
-
- function loadCurrentBoardBlob(board_id)
- {
- var revision;
-
- revision = localStorage.getItem('nullboard.board.' + board_id);
- if (! revision)
- return false;
-
- return localStorage.getItem('nullboard.board.' + board_id + '.' + revision);
- }
-
- function loadBoard(board_id)
- {
- var blob;
- var board;
-
- blob = loadCurrentBoardBlob(board_id);
- if (! blob)
- return false;
-
- board = parseBoard(blob);
- if (! board)
- {
- alert('Whoops. Error parsing board data.');
- console.log('Whoops, there it is:', blob);
- return false;
- }
-
- if (board.id != board_id)
- {
- alert('Whoops. Malformed board.');
- console.log('Whoops, there it is:', board.id, board_id);
- return false;
- }
-
- board.history = loadBoardHistory(board.id);
-
- return board;
- }
-
- //
- function loadBoardHistory(board_id)
- {
- var re = new RegExp('^nullboard\.board\.' + board_id + '\.(\\d+)$');
- var r = [];
-
- for (var i=0; i .head .menu .bulk');
- var $menu_b = $b.find('> .head .menu .bulk');
-
- var pos_a = $a.offset().left;
- var pos_b = $b.offset().left;
-
- $a.css({ position: 'relative' });
- $b.css({ position: 'relative' });
-
- $menu_a.hide();
- $menu_b.hide();
-
- $a.animate({ left: (pos_b - pos_a) + 'px' }, 'fast');
- $b.animate({ left: (pos_a - pos_b) + 'px' }, 'fast', function(){
-
- if (left) $list.prev().before($list);
- else $list.before($list.next());
-
- $a.css({ position: '', left: '' });
- $b.css({ position: '', left: '' });
-
- $menu_a.css({ display: '' });
- $menu_b.css({ display: '' });
-
- saveBoard();
- });
- }
-
- //
- function openBoard(board_id)
- {
- closeBoard(true);
-
- document.nb.board = loadBoard(board_id);
-
- localStorage.setItem('nullboard.last_board', board_id);
-
- showBoard(true);
- }
-
- function reopenBoard(revision)
- {
- var board_id = document.nb.board.id;
-
- var via_menu = $('.wrap .board > .head .menu .bulk').is(':visible');
-
- localStorage.setItem('nullboard.board.' + board_id, revision);
- openBoard(board_id);
-
- if (via_menu)
- {
- var $menu = $('.wrap .board > .head .menu');
- var $teaser = $menu.find('.teaser');
- var $bulk = $menu.find('.bulk');
-
- $teaser.hide().delay(100).queue(function(){ $(this).css('display', '').dequeue(); });
- $bulk.show().delay(100).queue(function(){ $(this).css('display', '').dequeue(); });
- }
- }
-
- function closeBoard(quick)
- {
- var $board = $('.wrap .board');
-
- if (quick)
- $board.remove();
- else
- $board
- .animate({ opacity: 0 }, 'fast')
- .queue(function(){ $board.remove(); });
-
- document.nb.board = null;
- localStorage.setItem('nullboard.last_board', null);
-
- updateUndoRedo();
- updateBoardIndex();
- }
-
- //
- function addBoard()
- {
- document.nb.board = new Board('');
- document.nb.board.history = [ 0 ];
-
- localStorage.setItem('nullboard.last_board', document.nb.board_id);
-
- showBoard(false);
-
- $('.wrap .board .head').addClass('brand-new');
- $('.wrap .board .head .text').click();
- }
-
- function deleteBoard()
- {
- var $list = $('.wrap .board .list');
-
- if ($list.length && ! confirm("PERMANENTLY delete this board, all its lists and their notes?"))
- return;
-
- nukeBoard();
- closeBoard();
- }
-
- //
- function undoBoard()
- {
- if (! document.nb.board)
- return false;
-
- var hist = document.nb.board.history;
- var have = document.nb.board.revision;
- var want = 0;
-
- for (var i=0; i ' + want);
-
- reopenBoard(want);
- return true;
- }
-
- function redoBoard()
- {
- if (! document.nb.board)
- return false;
-
- var hist = document.nb.board.history;
- var have = document.nb.board.revision;
- var want = 0;
-
- for (var i=1; i ' + want);
-
- reopenBoard(want);
- return true;
- }
-
- //
- function showBoard(quick)
- {
- var board = document.nb.board;
-
- var $wrap = $('.wrap');
- var $bdiv = $('tt .board');
- var $ldiv = $('tt .list');
- var $ndiv = $('tt .note');
-
- var $b = $bdiv.clone();
- var $b_lists = $b.find('.lists');
-
- $b[0].board_id = board.id;
- setText( $b.find('.head .text'), board.title );
-
- board.lists.forEach(function(list){
-
- var $l = $ldiv.clone();
- var $l_notes = $l.find('.notes');
-
- setText( $l.find('.head .text'), list.title );
-
- list.notes.forEach(function(n){
- var $n = $ndiv.clone();
- setText( $n.find('.text'), n.text );
- if (n.raw) $n.addClass('raw');
- if (n.min) $n.addClass('collapsed');
- $l_notes.append($n);
- });
-
- $b_lists.append($l);
- });
-
- if (quick)
- $wrap.html('').append($b);
- else
- $wrap.html('')
- .css({ opacity: 0 })
- .append($b)
- .animate({ opacity: 1 });
-
- updatePageTitle();
- updateUndoRedo();
- updateBoardIndex();
- setupListScrolling();
- }
-
- /*
- *
- */
- function updatePageTitle()
- {
- if (! document.nb.board)
- {
- document.title = 'Nullboard';
- return;
- }
-
- var $text = $('.wrap .board > .head .text');
- var title = getText( $text );
-
- document.nb.board.title = title;
- document.title = 'NB - ' + (title || '(unnamed board)');
- }
-
- function updateUndoRedo()
- {
- var $undo = $('.board .menu .undo-board');
- var $redo = $('.board .menu .redo-board');
-
- var undo = false;
- var redo = false;
-
- if (document.nb.board)
- {
- var history = document.nb.board.history;
- var rev = document.nb.board.revision;
-
- undo = (rev != history[history.length-1]);
- redo = (rev != history[0]);
- }
-
- if (undo) $undo.show(); else $undo.hide();
- if (redo) $redo.show(); else $redo.hide();
- }
-
- function updateBoardIndex()
- {
- var $index = $('.config .boards');
- var $export = $('.config .exp-board');
- var $entry = $('tt .load-board');
-
- var $board = $('.wrap .board');
- var id_now = document.nb.board && document.nb.board.id;
- var empty = true;
-
- $index.html('');
- $index.hide();
-
- for (var i=0; i$1');
-
- //
- var c1 = [];
- var c2 = [];
-
- text.substr(qos).trim().split('\n').forEach(function(line){
- line = line.split(':');
- c1.push( line[0].trim() + ':' );
- c2.push( line[1].trim() );
- });
-
- bulk += '' + c1.join('
') + '';
- bulk += '' + c2.join('
') + '';
-
- //
- var links =
- [
- { text: '2-clause BSD license', href: 'https://opensource.org/licenses/BSD-2-Clause/' },
- { text: 'Commons Clause', href: 'https://commonsclause.com/' }
- ];
-
- links.forEach(function(l){
- bulk = bulk.replace(l.text, '' + l.text + '');
- });
-
- return bulk.trim();
- }
-
- //
- function setRevealState(ev)
- {
- var raw = ev.originalEvent;
- var caps = raw.getModifierState && raw.getModifierState( 'CapsLock' );
-
- if (caps) $('body').addClass('reveal');
- else $('body').removeClass('reveal');
- }
-
- function handleTab(ev)
- {
- var $this = $(this);
- var $note = $this.closest('.note');
- var $sibl = ev.shiftKey ? $note.prev() : $note.next();
-
- if ($sibl.length)
- {
- stopEditing($this, false);
- $sibl.find('.text').click();
- }
- }
-
- //
- function adjustLayout()
- {
- var $body = $('body');
- var $board = $('.board');
-
- if (! $board.length)
- return;
-
- var lists = $board.find('.list').length;
- var lists_w = (lists < 2) ? 250 : 260 * lists - 10;
- var body_w = $body.width();
-
- if (lists_w + 190 <= body_w)
- {
- $board.css('max-width', '');
- $body.removeClass('crowded');
- }
- else
- {
- var max = Math.floor( (body_w - 40) / 260 );
- max = (max < 2) ? 250 : 260 * max - 10;
- $board.css('max-width', max + 'px');
- $body.addClass('crowded');
- }
- }
-
- //
- function adjustListScroller()
- {
- var $board = $('.board');
- if (! $board.length)
- return;
-
- var $lists = $('.board .lists');
- var $scroller = $('.board .lists-scroller');
- var $inner = $scroller.find('div');
-
- var max = $board.width();
- var want = $lists[0].scrollWidth;
- var have = $inner.width();
-
- if (want <= max)
- {
- $scroller.hide();
- return;
- }
-
- $scroller.show();
- if (want == have)
- return;
-
- $inner.width(want);
- cloneScrollPos($lists, $scroller);
- }
-
- //
- function cloneScrollPos($src, $dst)
- {
- var src = $src[0];
- var dst = $dst[0];
-
- if (src._busyScrolling)
- {
- src._busyScrolling--;
- return;
- }
-
- dst._busyScrolling++;
- dst.scrollLeft = src.scrollLeft;
- }
-
- function setupListScrolling()
- {
- var $lists = $('.board .lists');
- var $scroller = $('.board .lists-scroller');
-
- adjustListScroller();
-
- $lists[0]._busyScrolling = 0;
- $scroller[0]._busyScrolling = 0;
-
- $scroller.on('scroll', function(){ cloneScrollPos($scroller, $lists); });
- $lists .on('scroll', function(){ cloneScrollPos($lists, $scroller); });
-
- adjustLayout();
- }
-
- /*
- * this should *really* be in a separate file
- */
- function noteLocation($item)
- {
- var loc = 0;
- for (var $p = $item.closest('.note'); $p.length; $p = $p.prev(), loc += 1);
- for (var $p = $item.closest('.list'); $p.length; $p = $p.prev(), loc += 10000);
- return loc;
- }
+
+
+
-