From 061834572ad05b85997477dea9b3e2dc67d7321a Mon Sep 17 00:00:00 2001 From: Skylar Ittner Date: Wed, 28 Nov 2018 19:51:37 -0700 Subject: [PATCH] Add to-do list support (close #5), add overflow menu for action buttons --- action.php | 32 +++++++++++ composer.json | 5 +- composer.lock | 130 +++++++++++++++++++++++++++++++++++++++++++- langs/en/notes.json | 4 +- lib/Note.lib.php | 57 ++++++++++++++++++- pages/home.php | 40 +++++++++++--- static/css/home.css | 13 +++++ static/js/home.js | 40 +++++++++++++- 8 files changed, 304 insertions(+), 17 deletions(-) diff --git a/action.php b/action.php index 517fc29..ac57152 100644 --- a/action.php +++ b/action.php @@ -106,4 +106,36 @@ switch ($VARS['action']) { $note->saveNote(); returnToSender(""); break; + case "maketodolist": + if (empty($VARS['noteid'])) { + die($Strings->get("invalid parameters")); + } + $note = Note::loadNote($VARS['noteid']); + if (!$note->hasWriteAccess(new User($_SESSION['uid']))) { + die($Strings->get("invalid parameters")); + } + $note->toChecklist(); + $note->saveNote(); + returnToSender(""); + break; + case "togglecheckitem": + if (empty($VARS['noteid'])) { + die($Strings->get("invalid parameters")); + } + $note = Note::loadNote($VARS['noteid']); + if (!$note->hasWriteAccess(new User($_SESSION['uid']))) { + die($Strings->get("invalid parameters")); + } + + if (!empty($VARS['text'])) { + $note->toggleChecklistItem($VARS['text']); + $note->saveNote(); + } + + if (isset($VARS['reload'])) { + returnToSender(""); + } else { + http_response_code(204); + } + break; } \ No newline at end of file diff --git a/composer.json b/composer.json index 3542cee..1c00eec 100644 --- a/composer.json +++ b/composer.json @@ -5,7 +5,10 @@ "require": { "catfan/medoo": "^1.5", "guzzlehttp/guzzle": "^6.2", - "erusev/parsedown": "^1.7" + "erusev/parsedown": "^1.7", + "leblanc-simon/parsedown-checkbox": "^0.0.2", + "erusev/parsedown-extra": "^0.7.1", + "vanilla/htmlawed": "v2.2.4.1" }, "license": "MPL-2.0", "authors": [ diff --git a/composer.lock b/composer.lock index b680b7d..10fd048 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "1aea304797149ba2b5bccc0f6d82c060", + "content-hash": "b50c578394552657e0fcab936a4b1a01", "packages": [ { "name": "catfan/medoo", @@ -111,6 +111,50 @@ ], "time": "2018-03-08T01:11:30+00:00" }, + { + "name": "erusev/parsedown-extra", + "version": "0.7.1", + "source": { + "type": "git", + "url": "https://github.com/erusev/parsedown-extra.git", + "reference": "0db5cce7354e4b76f155d092ab5eb3981c21258c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/erusev/parsedown-extra/zipball/0db5cce7354e4b76f155d092ab5eb3981c21258c", + "reference": "0db5cce7354e4b76f155d092ab5eb3981c21258c", + "shasum": "" + }, + "require": { + "erusev/parsedown": "~1.4" + }, + "type": "library", + "autoload": { + "psr-0": { + "ParsedownExtra": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Emanuil Rusev", + "email": "hello@erusev.com", + "homepage": "http://erusev.com" + } + ], + "description": "An extension of Parsedown that adds support for Markdown Extra.", + "homepage": "https://github.com/erusev/parsedown-extra", + "keywords": [ + "markdown", + "markdown extra", + "parsedown", + "parser" + ], + "time": "2015-11-01T10:19:22+00:00" + }, { "name": "guzzlehttp/guzzle", "version": "6.3.3", @@ -292,6 +336,51 @@ ], "time": "2017-03-20T17:10:46+00:00" }, + { + "name": "leblanc-simon/parsedown-checkbox", + "version": "0.0.2", + "source": { + "type": "git", + "url": "https://github.com/leblanc-simon/parsedown-checkbox.git", + "reference": "abd857aafc890f55421c87cb9b3cfe9b2791f23f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/leblanc-simon/parsedown-checkbox/zipball/abd857aafc890f55421c87cb9b3cfe9b2791f23f", + "reference": "abd857aafc890f55421c87cb9b3cfe9b2791f23f", + "shasum": "" + }, + "require": { + "erusev/parsedown-extra": "^0.7.1" + }, + "type": "library", + "autoload": { + "files": [ + "ParsedownCheckbox.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Simon Leblanc", + "email": "contact@leblanc-simon.eu", + "homepage": "https://www.leblanc-simon.fr" + } + ], + "description": "An extension of Parsedown and ParsedownExtra that adds support for checkbox", + "homepage": "https://github.com/leblanc-simon/parsedown-checkbox", + "keywords": [ + "checkbox", + "markdown", + "markdown extra", + "parsedown", + "parser" + ], + "time": "2017-05-10T03:43:13+00:00" + }, { "name": "psr/http-message", "version": "1.0.1", @@ -341,6 +430,45 @@ "response" ], "time": "2016-08-06T14:39:51+00:00" + }, + { + "name": "vanilla/htmlawed", + "version": "v2.2.4.1", + "source": { + "type": "git", + "url": "https://github.com/vanilla/htmlawed.git", + "reference": "58651edbc4c45a2d6b5254b8a9a69dc63ff1457b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vanilla/htmlawed/zipball/58651edbc4c45a2d6b5254b8a9a69dc63ff1457b", + "reference": "58651edbc4c45a2d6b5254b8a9a69dc63ff1457b", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "tburry/pquery": "~1.0.1" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/Htmlawed.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0" + ], + "authors": [ + { + "name": "Todd Burry", + "email": "todd@vanillaforums.com" + } + ], + "description": "A composer wrapper for the htmLawed library to purify & filter HTML. Tested with PHPUnit and PhantomJS!", + "time": "2017-09-13T19:20:25+00:00" } ], "packages-dev": [], diff --git a/langs/en/notes.json b/langs/en/notes.json index 305141d..1ddc0b5 100644 --- a/langs/en/notes.json +++ b/langs/en/notes.json @@ -12,5 +12,7 @@ "Cancel": "Cancel", "Save": "Save", "Close": "Close", - "Refresh": "Refresh" + "Refresh": "Refresh", + "Make a List": "Make a List", + "More": "More" } diff --git a/lib/Note.lib.php b/lib/Note.lib.php index 1380453..c7ed319 100644 --- a/lib/Note.lib.php +++ b/lib/Note.lib.php @@ -116,9 +116,19 @@ class Note { * @return string */ public function getHTML(bool $fragment = true): string { - $parsedown = new Parsedown; - $parsedown->setSafeMode(true); - return $parsedown->text($this->content); + $parsedown = new ParsedownCheckbox(); + $html = $parsedown->text($this->content); + $safehtml = Htmlawed::filter($html, ['safe' => 1]); + if ($fragment) { + return $safehtml; + } + $document = "\n" + . "\n" + . "\n" + . "" . $this->getCleanTitle() . " (" . $note->getModified() . ")\n" + . "\n" + . $safehtml; + return $document; } /** @@ -293,6 +303,47 @@ class Note { $this->favorite = $favorite; } + /** + * Convert normal lines of text to checklist items. + */ + public function toChecklist() { + $text = explode("\n", $this->getText()); + for ($i = 0; $i < count($text); $i++) { + if (preg_match("/^[^\s\=\#\-<](.+)/", $text[$i])) { + if (count($text) > $i && preg_match("/^[\=-](.+)/", $text[$i + 1])) { + // Don't do it if the next line makes this one a heading + continue; + } + $text[$i] = "- [ ] " . $text[$i]; + } + } + $this->setText(implode("\n", $text)); + } + + /** + * Toggle the checked status of a checklist item. + * @param string $item The text of the item to toggle. + */ + public function toggleChecklistItem(string $item) { + $text = explode("\n", $this->getText()); + $item = trim(str_replace("\n", "", $item)); + for ($i = 0; $i < count($text); $i++) { + if (!preg_match("/^- \[[Xx ]\] .*/", $text[$i])) { + continue; + } + $linecleaned = trim(preg_replace("/^- \[[Xx ]\] /", "", $text[$i])); + if ($item != $linecleaned) { + continue; + } + if (preg_match("/^- \[[Xx]\] .*/", $text[$i])) { + $text[$i] = preg_replace("/^- \[[Xx]\] /", "- [ ] ", $text[$i]); + } else if (preg_match("/^- \[ \] .*/", $text[$i])) { + $text[$i] = preg_replace("/^- \[ \] /", "- [x] ", $text[$i]); + } + } + $this->setText(implode("\n", $text)); + } + /** * Get this note as an array. * @return string diff --git a/pages/home.php b/pages/home.php index ce6031e..0e7eec8 100644 --- a/pages/home.php +++ b/pages/home.php @@ -107,19 +107,41 @@ foreach ($colors as $c) {
- " data-color="getColor(); ?>" data-noteid="getID(); ?>"> - + " data-noteid="getID(); ?>"> +
-
- - + -
- - - + +
diff --git a/static/css/home.css b/static/css/home.css index 09df9cf..7e4023d 100644 --- a/static/css/home.css +++ b/static/css/home.css @@ -24,4 +24,17 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/. .note-text table tbody tr:nth-child(odd) { background-color: rgba(255,255,255,0.15); +} + +.dropdown-menu { + z-index: 9999999; + transform: translate3d(-100px, -85px, 0px) !important; +} + +.dropdown-item { + color: #212121 !important; +} + +.parsedown-task-list-close { + text-decoration: line-through; } \ No newline at end of file diff --git a/static/js/home.js b/static/js/home.js index b192795..f371e03 100644 --- a/static/js/home.js +++ b/static/js/home.js @@ -22,6 +22,7 @@ setInterval(function () { var favbtn = notecard.find(".favorite-btn"); notecard.find(".note-text").html(n['html']); + $(".parsedown-task-list input[type=checkbox]").removeAttr("disabled"); if (n.favorite) { favbtn.addClass("text-warning"); favbtn.html(''); @@ -43,7 +44,11 @@ $(".notecard").on("click", ".notecard-click2open", function () { document.location.href = "./app.php?page=editnote¬e=" + $(this).parent().data("note"); }); -$('[data-toggle="tooltip"]').tooltip(); +var tooltipoptions = { + placement: 'bottom' +}; +$('[data-toggle="tooltip"]').tooltip(tooltipoptions); +$('[data-tooltip="tooltip"]').tooltip(tooltipoptions); window.shuffleInstance = new window.Shuffle(document.getElementById('grid'), { itemSelector: '.grid__brick', @@ -51,4 +56,35 @@ window.shuffleInstance = new window.Shuffle(document.getElementById('grid'), { }); // Do the opposite of