From dac23e38d95bb8a1850812524c179c9e9eb12ec9 Mon Sep 17 00:00:00 2001 From: Alexander Date: Fri, 10 Aug 2018 13:27:17 +0300 Subject: [PATCH 01/90] Add support for converting to MD when paste HTML --- browser/components/CodeEditor.js | 17 ++++++ package.json | 4 +- yarn.lock | 93 ++++++++++++++++++++++++++++++-- 3 files changed, 110 insertions(+), 4 deletions(-) diff --git a/browser/components/CodeEditor.js b/browser/components/CodeEditor.js index 1b546ed1..eb4299e4 100644 --- a/browser/components/CodeEditor.js +++ b/browser/components/CodeEditor.js @@ -14,6 +14,8 @@ import consts from 'browser/lib/consts' import fs from 'fs' const { ipcRenderer } = require('electron') import normalizeEditorFontFamily from 'browser/lib/normalizeEditorFontFamily' +import TurndownService from 'turndown' +import { gfm } from 'turndown-plugin-gfm' CodeMirror.modeURL = '../node_modules/codemirror/mode/%N/%N.js' @@ -52,6 +54,9 @@ export default class CodeEditor extends React.Component { this.searchState = null this.formatTable = () => this.handleFormatTable() + + this.turndownService = new TurndownService() + this.turndownService.use(gfm) } handleSearch (msg) { @@ -406,6 +411,12 @@ export default class CodeEditor extends React.Component { ) return prevChar === '](' && nextChar === ')' } + + const pastedHtml = clipboardData.getData('text/html') + if (pastedHtml !== '') { + this.handlePasteHtml(e, editor, pastedHtml) + } + if (dataTransferItem.type.match('image')) { attachmentManagement.handlePastImageEvent(this, storageKey, noteKey, dataTransferItem) } else if (this.props.fetchUrlTitle && isURL(pastedTxt) && !isInLinkTag(editor)) { @@ -459,6 +470,12 @@ export default class CodeEditor extends React.Component { }) } + handlePasteHtml (e, editor, pastedHtml) { + e.preventDefault() + const markdown = this.turndownService.turndown(pastedHtml) + editor.replaceSelection(markdown) + } + mapNormalResponse (response, pastedTxt) { return this.decodeResponse(response).then((body) => { return new Promise((resolve, reject) => { diff --git a/package.json b/package.json index fbbb025f..d7d49b80 100644 --- a/package.json +++ b/package.json @@ -100,7 +100,9 @@ "sanitize-html": "^1.18.2", "striptags": "^2.2.1", "unique-slug": "2.0.0", - "uuid": "^3.2.1" + "uuid": "^3.2.1", + "turndown":"^4.0.2", + "turndown-plugin-gfm":"^1.0.2" }, "devDependencies": { "ava": "^0.25.0", diff --git a/yarn.lock b/yarn.lock index f77252ca..0f4f6b48 100644 --- a/yarn.lock +++ b/yarn.lock @@ -93,6 +93,10 @@ abab@^1.0.3, abab@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e" +abab@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.0.tgz#aba0ab4c5eee2d4c79d3487d85450fb2376ebb0f" + abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" @@ -138,6 +142,10 @@ acorn@^5.0.0, acorn@^5.3.0, acorn@^5.5.0: version "5.5.3" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.3.tgz#f473dd47e0277a08e28e9bec5aeeb04751f0b8c9" +acorn@^5.5.3: + version "5.7.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.1.tgz#f095829297706a7c9776958c0afc8930a9b9d9d8" + ajv-keywords@^1.0.0: version "1.5.1" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" @@ -2162,6 +2170,12 @@ cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": dependencies: cssom "0.3.x" +cssstyle@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.0.0.tgz#79b16d51ec5591faec60e688891f15d2a5705129" + dependencies: + cssom "0.3.x" + ctype@0.5.3: version "0.5.3" resolved "https://registry.yarnpkg.com/ctype/-/ctype-0.5.3.tgz#82c18c2461f74114ef16c135224ad0b9144ca12f" @@ -2673,7 +2687,7 @@ domelementtype@~1.1.1: version "1.1.3" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b" -domexception@^1.0.0: +domexception@^1.0.0, domexception@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" dependencies: @@ -3010,6 +3024,17 @@ escodegen@^1.6.1, escodegen@^1.9.0: optionalDependencies: source-map "~0.6.1" +escodegen@^1.9.1: + version "1.11.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.11.0.tgz#b27a9389481d5bfd5bec76f7bb1eb3f8f4556589" + dependencies: + esprima "^3.1.3" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + escope@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" @@ -5257,6 +5282,37 @@ jsdom@^11.5.1: ws "^4.0.0" xml-name-validator "^3.0.0" +jsdom@^11.9.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8" + dependencies: + abab "^2.0.0" + acorn "^5.5.3" + acorn-globals "^4.1.0" + array-equal "^1.0.0" + cssom ">= 0.3.2 < 0.4.0" + cssstyle "^1.0.0" + data-urls "^1.0.0" + domexception "^1.0.1" + escodegen "^1.9.1" + html-encoding-sniffer "^1.0.2" + left-pad "^1.3.0" + nwsapi "^2.0.7" + parse5 "4.0.0" + pn "^1.1.0" + request "^2.87.0" + request-promise-native "^1.0.5" + sax "^1.2.4" + symbol-tree "^3.2.2" + tough-cookie "^2.3.4" + w3c-hr-time "^1.0.1" + webidl-conversions "^4.0.2" + whatwg-encoding "^1.0.3" + whatwg-mimetype "^2.1.0" + whatwg-url "^6.4.1" + ws "^5.2.0" + xml-name-validator "^3.0.0" + jsdom@^9.4.2: version "9.12.0" resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-9.12.0.tgz#e8c546fffcb06c00d4833ca84410fed7f8a097d4" @@ -5416,7 +5472,7 @@ lcid@^1.0.0: dependencies: invert-kv "^1.0.0" -left-pad@^1.2.0: +left-pad@^1.2.0, left-pad@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e" @@ -6288,6 +6344,10 @@ nwsapi@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.0.0.tgz#7c8faf4ad501e1d17a651ebc5547f966b547c5c7" +nwsapi@^2.0.7: + version "2.0.8" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.0.8.tgz#e3603579b7e162b3dbedae4fb24e46f771d8fa24" + oauth-sign@~0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.6.0.tgz#7dbeae44f6ca454e1f168451d630746735813ce3" @@ -7028,6 +7088,10 @@ pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" +psl@^1.1.24: + version "1.1.29" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67" + punycode@1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" @@ -7510,7 +7574,7 @@ request@2.55.0: tough-cookie ">=0.12.0" tunnel-agent "~0.4.0" -request@^2.45.0, request@^2.79.0, request@^2.83.0: +request@^2.45.0, request@^2.79.0, request@^2.83.0, request@^2.87.0: version "2.87.0" resolved "https://registry.yarnpkg.com/request/-/request-2.87.0.tgz#32f00235cd08d482b4d0d68db93a829c0ed5756e" dependencies: @@ -8515,6 +8579,13 @@ tough-cookie@>=0.12.0, tough-cookie@>=2.3.3, tough-cookie@^2.3.2, tough-cookie@^ dependencies: punycode "^1.4.1" +tough-cookie@^2.3.4: + version "2.4.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" + dependencies: + psl "^1.1.24" + punycode "^1.4.1" + tr46@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" @@ -8565,6 +8636,16 @@ tunnel-agent@~0.4.0: version "0.4.3" resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" +turndown-plugin-gfm@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/turndown-plugin-gfm/-/turndown-plugin-gfm-1.0.2.tgz#6f8678a361f35220b2bdf5619e6049add75bf1c7" + +turndown@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/turndown/-/turndown-4.0.2.tgz#c3ddb8ba32a3665723599be2f4e7860adb6042ae" + dependencies: + jsdom "^11.9.0" + tweetnacl@^0.14.3, tweetnacl@~0.14.0: version "0.14.5" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" @@ -9098,6 +9179,12 @@ ws@^4.0.0: async-limiter "~1.0.0" safe-buffer "~5.1.0" +ws@^5.2.0: + version "5.2.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" + dependencies: + async-limiter "~1.0.0" + xdg-basedir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" From 5bf3824f28d41d89180df0520bb4175c5a52eee8 Mon Sep 17 00:00:00 2001 From: Alexander Date: Fri, 10 Aug 2018 15:15:19 +0300 Subject: [PATCH 02/90] Fix --- browser/components/CodeEditor.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/browser/components/CodeEditor.js b/browser/components/CodeEditor.js index eb4299e4..43b16bc9 100644 --- a/browser/components/CodeEditor.js +++ b/browser/components/CodeEditor.js @@ -415,9 +415,7 @@ export default class CodeEditor extends React.Component { const pastedHtml = clipboardData.getData('text/html') if (pastedHtml !== '') { this.handlePasteHtml(e, editor, pastedHtml) - } - - if (dataTransferItem.type.match('image')) { + } else if (dataTransferItem.type.match('image')) { attachmentManagement.handlePastImageEvent(this, storageKey, noteKey, dataTransferItem) } else if (this.props.fetchUrlTitle && isURL(pastedTxt) && !isInLinkTag(editor)) { this.handlePasteUrl(e, editor, pastedTxt) From 73fbf49ba4cb3603b7f381ec9e3626b5efa0537d Mon Sep 17 00:00:00 2001 From: Baptiste Augrain Date: Tue, 21 Aug 2018 00:19:26 +0200 Subject: [PATCH 03/90] - show tags of note in alphabetical order - enable live count of notes --- browser/components/NoteItem.js | 16 ++++-- browser/components/TagListItem.js | 2 +- browser/main/Detail/MarkdownNoteDetail.js | 3 +- browser/main/Detail/SnippetNoteDetail.js | 1 + browser/main/Detail/TagSelect.js | 4 +- browser/main/NoteList/index.js | 1 + browser/main/SideNav/index.js | 18 +++++- browser/main/modals/PreferencesModal/UiTab.js | 55 +++++++++++++++---- locales/en.json | 4 +- locales/fr.json | 4 +- 10 files changed, 81 insertions(+), 27 deletions(-) diff --git a/browser/components/NoteItem.js b/browser/components/NoteItem.js index 5073dc73..b0731eca 100644 --- a/browser/components/NoteItem.js +++ b/browser/components/NoteItem.js @@ -24,16 +24,19 @@ const TagElement = ({ tagName }) => ( /** * @description Tag element list component. * @param {Array|null} tags + * @param {boolean} showTagsAlphabetically * @return {React.Component} */ -const TagElementList = tags => { +const TagElementList = (tags, showTagsAlphabetically) => { if (!isArray(tags)) { return [] } - const tagElements = tags.map(tag => TagElement({ tagName: tag })) - - return tagElements + if (showTagsAlphabetically) { + return _.sortBy(tags).map(tag => TagElement({ tagName: tag })) + } else { + return tags.map(tag => TagElement({ tagName: tag })) + } } /** @@ -55,7 +58,8 @@ const NoteItem = ({ pathname, storageName, folderName, - viewType + viewType, + showTagsAlphabetically }) => (
{note.tags.length > 0 - ? TagElementList(note.tags) + ? TagElementList(note.tags, showTagsAlphabetically) : handleClickTagListItem(name)}> {`# ${name}`} - {count} + {count !== 0 ? count : ''}
diff --git a/browser/main/Detail/MarkdownNoteDetail.js b/browser/main/Detail/MarkdownNoteDetail.js index 82073162..705736e9 100755 --- a/browser/main/Detail/MarkdownNoteDetail.js +++ b/browser/main/Detail/MarkdownNoteDetail.js @@ -312,7 +312,7 @@ class MarkdownNoteDetail extends React.Component { } render () { - const { data, location } = this.props + const { data, location, config } = this.props const { note, editorType } = this.state const storageKey = note.storage const folderKey = note.folder @@ -363,6 +363,7 @@ class MarkdownNoteDetail extends React.Component { diff --git a/browser/main/Detail/SnippetNoteDetail.js b/browser/main/Detail/SnippetNoteDetail.js index 652d1f53..3633ec85 100644 --- a/browser/main/Detail/SnippetNoteDetail.js +++ b/browser/main/Detail/SnippetNoteDetail.js @@ -744,6 +744,7 @@ class SnippetNoteDetail extends React.Component { this.handleChange(e)} />
diff --git a/browser/main/Detail/TagSelect.js b/browser/main/Detail/TagSelect.js index e251dd42..e51d5673 100644 --- a/browser/main/Detail/TagSelect.js +++ b/browser/main/Detail/TagSelect.js @@ -119,10 +119,10 @@ class TagSelect extends React.Component { } render () { - const { value, className } = this.props + const { value, className, showTagsAlphabetically } = this.props const tagList = _.isArray(value) - ? value.map((tag) => { + ? (showTagsAlphabetically ? _.sortBy(value) : value).map((tag) => { return ( ) } diff --git a/browser/main/SideNav/index.js b/browser/main/SideNav/index.js index c4fa417b..d1292f68 100644 --- a/browser/main/SideNav/index.js +++ b/browser/main/SideNav/index.js @@ -19,6 +19,10 @@ import {SortableContainer} from 'react-sortable-hoc' import i18n from 'browser/lib/i18n' import context from 'browser/lib/context' +function findOne(haystack, arr) { + return arr.some(v => haystack.indexOf(v) >= 0) +} + class SideNav extends React.Component { // TODO: should not use electron stuff v0.7 @@ -144,12 +148,20 @@ class SideNav extends React.Component { tagListComponent () { const { data, location, config } = this.props - const relatedTags = this.getRelatedTags(this.getActiveTags(location.pathname), data.noteMap) + const activeTags = this.getActiveTags(location.pathname) + const relatedTags = this.getRelatedTags(activeTags, data.noteMap) let tagList = _.sortBy(data.tagNoteMap.map( (tag, name) => ({ name, size: tag.size, related: relatedTags.has(name) }) - ), ['name']).filter( + ).filter( tag => tag.size > 0 - ) + ), ['name']) + if (config.ui.enableLiveNoteCounts && activeTags.length !== 0) { + const notesTags = data.noteMap.map(note => note.tags) + tagList = tagList.map(tag => { + tag.size = notesTags.filter(tags => tags.includes(tag.name) && findOne(tags, activeTags)).length + return tag + }) + } if (config.sortTagsBy === 'COUNTER') { tagList = _.sortBy(tagList, item => (0 - item.size)) } diff --git a/browser/main/modals/PreferencesModal/UiTab.js b/browser/main/modals/PreferencesModal/UiTab.js index aa3568e7..40269190 100644 --- a/browser/main/modals/PreferencesModal/UiTab.js +++ b/browser/main/modals/PreferencesModal/UiTab.js @@ -70,6 +70,8 @@ class UiTab extends React.Component { showCopyNotification: this.refs.showCopyNotification.checked, confirmDeletion: this.refs.confirmDeletion.checked, showOnlyRelatedTags: this.refs.showOnlyRelatedTags.checked, + showTagsAlphabetically: this.refs.showTagsAlphabetically.checked, + enableLiveNoteCounts: this.refs.enableLiveNoteCounts.checked, disableDirectWrite: this.refs.uiD2w != null ? this.refs.uiD2w.checked : false @@ -172,7 +174,9 @@ class UiTab extends React.Component {
{i18n.__('Interface')}
- {i18n.__('Interface Theme')} +
+ {i18n.__('Interface Theme')} +
this.handleUIChange(e)} @@ -221,16 +227,6 @@ class UiTab extends React.Component { {i18n.__('Show a confirmation dialog when deleting notes')}
-
- -
{ global.process.platform === 'win32' ?
@@ -246,6 +242,41 @@ class UiTab extends React.Component {
: null } +
Tags
+ +
+ +
+ +
+ +
+ +
+ +
+
Editor
diff --git a/locales/en.json b/locales/en.json index a9767492..d01a6175 100644 --- a/locales/en.json +++ b/locales/en.json @@ -175,5 +175,7 @@ "Allow styles": "Allow styles", "Allow dangerous html tags": "Allow dangerous html tags", "Convert textual arrows to beautiful signs. ⚠ This will interfere with using HTML comments in your Markdown.": "Convert textual arrows to beautiful signs. ⚠ This will interfere with using HTML comments in your Markdown.", - "⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠": "⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠" + "⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠": "⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠", + "Show tags of a note in alphabetical order": "Show tags of a note in alphabetical order", + "Enable live count of notes": "Enable live count of notes" } diff --git a/locales/fr.json b/locales/fr.json index 8b880aa6..33a7c503 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -152,5 +152,7 @@ "Allow styles": "Accepter les styles", "Allow dangerous html tags": "Accepter les tags html dangereux", "Convert textual arrows to beautiful signs. ⚠ This will interfere with using HTML comments in your Markdown.": "Convertir des flèches textuelles en jolis signes. ⚠ Cela va interferérer avec les éventuels commentaires HTML dans votre Markdown.", - "⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠": "⚠ Vous avez collé un lien qui référence une pièce-jointe qui n'a pas pu être récupéré dans le dossier de stockage de la note. Coller des liens qui font référence à des pièces-jointes ne fonctionne que si la source et la destination et la même. Veuillez plutôt utiliser du Drag & Drop ! ⚠" + "⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠": "⚠ Vous avez collé un lien qui référence une pièce-jointe qui n'a pas pu être récupéré dans le dossier de stockage de la note. Coller des liens qui font référence à des pièces-jointes ne fonctionne que si la source et la destination et la même. Veuillez plutôt utiliser du Drag & Drop ! ⚠", + "Show tags of a note in alphabetical order": "Afficher les tags d'une note par ordre alphabétique", + "Enable live count of notes": "Activer le comptage live des notes" } From 7cde30d3522a4c23d6995ccb68393a12ab6c85e1 Mon Sep 17 00:00:00 2001 From: Baptiste Augrain Date: Tue, 21 Aug 2018 00:24:03 +0200 Subject: [PATCH 04/90] fix lint errors --- browser/main/SideNav/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/browser/main/SideNav/index.js b/browser/main/SideNav/index.js index d1292f68..0dd34989 100644 --- a/browser/main/SideNav/index.js +++ b/browser/main/SideNav/index.js @@ -19,8 +19,8 @@ import {SortableContainer} from 'react-sortable-hoc' import i18n from 'browser/lib/i18n' import context from 'browser/lib/context' -function findOne(haystack, arr) { - return arr.some(v => haystack.indexOf(v) >= 0) +function findOne (haystack, arr) { + return arr.some(v => haystack.indexOf(v) >= 0) } class SideNav extends React.Component { From a59100176184b9700da1cb1b838106a6baf6736c Mon Sep 17 00:00:00 2001 From: Baptiste Augrain Date: Sat, 25 Aug 2018 20:18:59 +0200 Subject: [PATCH 05/90] add parameter to specify the height of the diagram, fixing #2335 --- browser/components/render/MermaidRender.js | 1 + browser/lib/markdown.js | 2 +- browser/styles/index.styl | 6 +++++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/browser/components/render/MermaidRender.js b/browser/components/render/MermaidRender.js index 12dce327..bac52b2c 100644 --- a/browser/components/render/MermaidRender.js +++ b/browser/components/render/MermaidRender.js @@ -28,6 +28,7 @@ function render (element, content, theme) { }) mermaidAPI.render(getId(), content, (svgGraph) => { element.innerHTML = svgGraph + element.style.height = element.attributes.getNamedItem('data-height').value + 'vh' }) } catch (e) { console.error(e) diff --git a/browser/lib/markdown.js b/browser/lib/markdown.js index 49fd2f86..d4bc72e4 100644 --- a/browser/lib/markdown.js +++ b/browser/lib/markdown.js @@ -44,7 +44,7 @@ class Markdown { return `
${str}
` } if (langType === 'mermaid') { - return `
${str}
` + return `
${str}
` } return '
' +
           '' + fileName + '' +
diff --git a/browser/styles/index.styl b/browser/styles/index.styl
index 7d32e77a..8f917fcf 100644
--- a/browser/styles/index.styl
+++ b/browser/styles/index.styl
@@ -383,4 +383,8 @@ modalmonokai()
   width 100%
   background-color $ui-monokai-backgroundColor
   overflow hidden
-  border-radius $modal-border-radius
\ No newline at end of file
+  border-radius $modal-border-radius
+
+pre.mermaid svg {
+  max-width 100% !important
+}
\ No newline at end of file

From 3bdc88cecb6ed117312e2860e3c84afc5b803d69 Mon Sep 17 00:00:00 2001
From: Baptiste Augrain 
Date: Sat, 25 Aug 2018 23:14:05 +0200
Subject: [PATCH 06/90] fixing sanitization of inline html like () #1992

---
 browser/lib/markdown-it-sanitize-html.js | 86 +++++++++++++++++++++++-
 browser/lib/markdown.js                  |  6 +-
 2 files changed, 90 insertions(+), 2 deletions(-)

diff --git a/browser/lib/markdown-it-sanitize-html.js b/browser/lib/markdown-it-sanitize-html.js
index 05e5e7be..ea27bfa0 100644
--- a/browser/lib/markdown-it-sanitize-html.js
+++ b/browser/lib/markdown-it-sanitize-html.js
@@ -2,6 +2,7 @@
 
 import sanitizeHtml from 'sanitize-html'
 import { escapeHtmlCharacters } from './utils'
+import url from 'url'
 
 module.exports = function sanitizePlugin (md, options) {
   options = options || {}
@@ -25,7 +26,7 @@ module.exports = function sanitizePlugin (md, options) {
         const inlineTokens = state.tokens[tokenIdx].children
         for (let childIdx = 0; childIdx < inlineTokens.length; childIdx++) {
           if (inlineTokens[childIdx].type === 'html_inline') {
-            inlineTokens[childIdx].content = sanitizeHtml(
+            inlineTokens[childIdx].content = sanitizeInline(
               inlineTokens[childIdx].content,
               options
             )
@@ -35,3 +36,86 @@ module.exports = function sanitizePlugin (md, options) {
     }
   })
 }
+
+const tag_regex = /<([A-Z][A-Z0-9]*)\s*((?:\s*[A-Z][A-Z0-9]*(?:="(?:[^\"]+)\")?)*)\s*>|<\/([A-Z][A-Z0-9]*)\s*>/i
+const attributes_regex = /([A-Z][A-Z0-9]*)(="[^\"]+\")?/ig
+
+function sanitizeInline(html, options) {
+  let match = tag_regex.exec(html)
+  if (!match) {
+    return ''
+  }
+  
+  const { allowedTags, allowedAttributes, allowedIframeHostnames, selfClosing, allowedSchemesAppliedToAttributes } = options
+  
+  if (match[1] !== null) {
+    // opening tag
+    const tag = match[1].toLowerCase()
+    if (allowedTags.indexOf(tag) === -1) {
+      return ''
+    }
+    
+    const attributes = match[2]
+    
+    let attrs = ''
+    let name
+    let value
+    
+    while ((match = attributes_regex.exec(attributes))) {
+      name = match[1].toLowerCase()
+      value = match[2]
+      
+      if (allowedAttributes['*'].indexOf(name) !== -1 || (allowedAttributes[tag] && allowedAttributes[tag].indexOf(name) !== -1)) {
+        if (allowedSchemesAppliedToAttributes.indexOf(name) !== -1) {
+          if (naughtyHRef(value) || (tag === 'iframe' && name === 'src' && naughtyIFrame(value))) {
+            continue
+          }
+        }
+        
+        attrs += ` ${name}${value}`
+      }
+    }
+    
+    if (selfClosing.indexOf(tag)) {
+      return '<' + tag + attrs + ' />'
+    } else {
+      return '<' + tag + attrs + '>'
+    }
+  } else {
+    // closing tag
+    if (allowedTags.indexOf(match[3].toLowerCase()) !== -1) {
+      return html
+    } else {
+      return ''
+    }
+  }
+}
+
+function naughtyHRef(name, href, options) {
+  href = href.replace(/[\x00-\x20]+/g, '')
+  href = href.replace(/<\!\-\-.*?\-\-\>/g, '')
+  
+  const matches = href.match(/^([a-zA-Z]+)\:/)
+  if (!matches) {
+    if (href.match(/^[\/\\]{2}/)) {
+      return !options.allowProtocolRelative
+    }
+
+    // No scheme
+    return false
+  }
+
+  const scheme = matches[1].toLowerCase()
+
+  return options.allowedSchemes.indexOf(scheme) === -1
+}
+
+function naughtyIFrame(src) {
+  try {
+    const parsed = url.parse(src, false, true)
+    
+    return allowedIframeHostnames.index(parsed.hostname) === -1
+  } catch (e) {
+    return true
+  }
+}
\ No newline at end of file
diff --git a/browser/lib/markdown.js b/browser/lib/markdown.js
index 49fd2f86..90b1ccea 100644
--- a/browser/lib/markdown.js
+++ b/browser/lib/markdown.js
@@ -105,7 +105,11 @@ class Markdown {
           'iframe': ['src', 'width', 'height', 'frameborder', 'allowfullscreen'],
           'input': ['type', 'id', 'checked']
         },
-        allowedIframeHostnames: ['www.youtube.com']
+        allowedIframeHostnames: ['www.youtube.com'],
+        selfClosing: [ 'img', 'br', 'hr', 'input' ],
+        allowedSchemes: [ 'http', 'https', 'ftp', 'mailto' ],
+        allowedSchemesAppliedToAttributes: [ 'href', 'src', 'cite' ],
+        allowProtocolRelative: true
       })
     }
 

From fabc975b2025c12402312862c26abfb12bcc00b4 Mon Sep 17 00:00:00 2001
From: Baptiste Augrain 
Date: Sat, 25 Aug 2018 23:36:43 +0200
Subject: [PATCH 07/90] - fix lint errors - correctly parse self-closed tag -
 fix naughty functions

---
 browser/lib/markdown-it-sanitize-html.js | 46 ++++++++++++------------
 1 file changed, 23 insertions(+), 23 deletions(-)

diff --git a/browser/lib/markdown-it-sanitize-html.js b/browser/lib/markdown-it-sanitize-html.js
index ea27bfa0..9bdd3034 100644
--- a/browser/lib/markdown-it-sanitize-html.js
+++ b/browser/lib/markdown-it-sanitize-html.js
@@ -37,45 +37,45 @@ module.exports = function sanitizePlugin (md, options) {
   })
 }
 
-const tag_regex = /<([A-Z][A-Z0-9]*)\s*((?:\s*[A-Z][A-Z0-9]*(?:="(?:[^\"]+)\")?)*)\s*>|<\/([A-Z][A-Z0-9]*)\s*>/i
-const attributes_regex = /([A-Z][A-Z0-9]*)(="[^\"]+\")?/ig
+const tagRegex = /<([A-Z][A-Z0-9]*)\s*((?:\s*[A-Z][A-Z0-9]*(?:="(?:[^\"]+)\")?)*)\s*\/?>|<\/([A-Z][A-Z0-9]*)\s*>/i
+const attributesRegex = /([A-Z][A-Z0-9]*)(="[^\"]+\")?/ig
 
-function sanitizeInline(html, options) {
-  let match = tag_regex.exec(html)
+function sanitizeInline (html, options) {
+  let match = tagRegex.exec(html)
   if (!match) {
     return ''
   }
-  
-  const { allowedTags, allowedAttributes, allowedIframeHostnames, selfClosing, allowedSchemesAppliedToAttributes } = options
-  
-  if (match[1] !== null) {
+
+  const { allowedTags, allowedAttributes, selfClosing, allowedSchemesAppliedToAttributes } = options
+
+  if (match[1] !== undefined) {
     // opening tag
     const tag = match[1].toLowerCase()
     if (allowedTags.indexOf(tag) === -1) {
       return ''
     }
-    
+
     const attributes = match[2]
-    
+
     let attrs = ''
     let name
     let value
-    
-    while ((match = attributes_regex.exec(attributes))) {
+
+    while ((match = attributesRegex.exec(attributes))) {
       name = match[1].toLowerCase()
       value = match[2]
-      
+
       if (allowedAttributes['*'].indexOf(name) !== -1 || (allowedAttributes[tag] && allowedAttributes[tag].indexOf(name) !== -1)) {
         if (allowedSchemesAppliedToAttributes.indexOf(name) !== -1) {
-          if (naughtyHRef(value) || (tag === 'iframe' && name === 'src' && naughtyIFrame(value))) {
+          if (naughtyHRef(value, options) || (tag === 'iframe' && name === 'src' && naughtyIFrame(value, options))) {
             continue
           }
         }
-        
+
         attrs += ` ${name}${value}`
       }
     }
-    
+
     if (selfClosing.indexOf(tag)) {
       return '<' + tag + attrs + ' />'
     } else {
@@ -91,10 +91,10 @@ function sanitizeInline(html, options) {
   }
 }
 
-function naughtyHRef(name, href, options) {
-  href = href.replace(/[\x00-\x20]+/g, '')
+function naughtyHRef (href, options) {
+  // href = href.replace(/[\x00-\x20]+/g, '')
   href = href.replace(/<\!\-\-.*?\-\-\>/g, '')
-  
+
   const matches = href.match(/^([a-zA-Z]+)\:/)
   if (!matches) {
     if (href.match(/^[\/\\]{2}/)) {
@@ -110,12 +110,12 @@ function naughtyHRef(name, href, options) {
   return options.allowedSchemes.indexOf(scheme) === -1
 }
 
-function naughtyIFrame(src) {
+function naughtyIFrame (src, options) {
   try {
     const parsed = url.parse(src, false, true)
-    
-    return allowedIframeHostnames.index(parsed.hostname) === -1
+
+    return options.allowedIframeHostnames.index(parsed.hostname) === -1
   } catch (e) {
     return true
   }
-}
\ No newline at end of file
+}

From 2a838ebb0b46bad08f54f46256396fac1c52c02a Mon Sep 17 00:00:00 2001
From: Baptiste Augrain 
Date: Sun, 26 Aug 2018 00:14:29 +0200
Subject: [PATCH 08/90] fixing single quoted attributes

---
 browser/lib/markdown-it-sanitize-html.js | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/browser/lib/markdown-it-sanitize-html.js b/browser/lib/markdown-it-sanitize-html.js
index 9bdd3034..ce6c5e29 100644
--- a/browser/lib/markdown-it-sanitize-html.js
+++ b/browser/lib/markdown-it-sanitize-html.js
@@ -37,8 +37,8 @@ module.exports = function sanitizePlugin (md, options) {
   })
 }
 
-const tagRegex = /<([A-Z][A-Z0-9]*)\s*((?:\s*[A-Z][A-Z0-9]*(?:="(?:[^\"]+)\")?)*)\s*\/?>|<\/([A-Z][A-Z0-9]*)\s*>/i
-const attributesRegex = /([A-Z][A-Z0-9]*)(="[^\"]+\")?/ig
+const tagRegex = /<([A-Z][A-Z0-9]*)\s*((?:\s*[A-Z][A-Z0-9]*(?:=("|')(?:[^\3]+?)\3)?)*)\s*\/?>|<\/([A-Z][A-Z0-9]*)\s*>/i
+const attributesRegex = /([A-Z][A-Z0-9]*)(?:=("|')([^\2]+?)\2)?/ig
 
 function sanitizeInline (html, options) {
   let match = tagRegex.exec(html)
@@ -63,7 +63,7 @@ function sanitizeInline (html, options) {
 
     while ((match = attributesRegex.exec(attributes))) {
       name = match[1].toLowerCase()
-      value = match[2]
+      value = match[3]
 
       if (allowedAttributes['*'].indexOf(name) !== -1 || (allowedAttributes[tag] && allowedAttributes[tag].indexOf(name) !== -1)) {
         if (allowedSchemesAppliedToAttributes.indexOf(name) !== -1) {
@@ -72,7 +72,10 @@ function sanitizeInline (html, options) {
           }
         }
 
-        attrs += ` ${name}${value}`
+        attrs += ` ${name}`
+        if (match[2]) {
+          attrs += `="${value}"`
+        }
       }
     }
 
@@ -83,7 +86,7 @@ function sanitizeInline (html, options) {
     }
   } else {
     // closing tag
-    if (allowedTags.indexOf(match[3].toLowerCase()) !== -1) {
+    if (allowedTags.indexOf(match[4].toLowerCase()) !== -1) {
       return html
     } else {
       return ''

From 5006aaae38d409aab09d0b9b1bd73e19be09959b Mon Sep 17 00:00:00 2001
From: Baptiste Augrain 
Date: Tue, 28 Aug 2018 01:44:33 +0200
Subject: [PATCH 09/90] fix live note counts when multiple tags are selected

---
 browser/main/SideNav/index.js | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/browser/main/SideNav/index.js b/browser/main/SideNav/index.js
index 0dd34989..65f76691 100644
--- a/browser/main/SideNav/index.js
+++ b/browser/main/SideNav/index.js
@@ -19,8 +19,8 @@ import {SortableContainer} from 'react-sortable-hoc'
 import i18n from 'browser/lib/i18n'
 import context from 'browser/lib/context'
 
-function findOne (haystack, arr) {
-  return arr.some(v => haystack.indexOf(v) >= 0)
+function matchActiveTags (tags, activeTags) {
+  return _.every(activeTags, v => tags.indexOf(v) >= 0)
 }
 
 class SideNav extends React.Component {
@@ -158,7 +158,7 @@ class SideNav extends React.Component {
     if (config.ui.enableLiveNoteCounts && activeTags.length !== 0) {
       const notesTags = data.noteMap.map(note => note.tags)
       tagList = tagList.map(tag => {
-        tag.size = notesTags.filter(tags => tags.includes(tag.name) && findOne(tags, activeTags)).length
+        tag.size = notesTags.filter(tags => tags.includes(tag.name) && matchActiveTags(tags, activeTags)).length
         return tag
       })
     }

From 8b4a9dd3259b6935e9fc2c6b346ca62d0ee02cdb Mon Sep 17 00:00:00 2001
From: Baptiste Augrain 
Date: Wed, 29 Aug 2018 19:28:09 +0200
Subject: [PATCH 10/90] add `saveTagsAlphabetically` option

---
 browser/main/Detail/MarkdownNoteDetail.js     |  1 +
 browser/main/Detail/SnippetNoteDetail.js      |  1 +
 browser/main/Detail/TagSelect.js              | 10 ++++++++--
 browser/main/modals/PreferencesModal/UiTab.js | 12 ++++++++++++
 locales/en.json                               |  1 +
 locales/fr.json                               |  1 +
 6 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/browser/main/Detail/MarkdownNoteDetail.js b/browser/main/Detail/MarkdownNoteDetail.js
index 705736e9..1e30d28b 100755
--- a/browser/main/Detail/MarkdownNoteDetail.js
+++ b/browser/main/Detail/MarkdownNoteDetail.js
@@ -363,6 +363,7 @@ class MarkdownNoteDetail extends React.Component {
         
diff --git a/browser/main/Detail/SnippetNoteDetail.js b/browser/main/Detail/SnippetNoteDetail.js
index 3633ec85..4a54e7c4 100644
--- a/browser/main/Detail/SnippetNoteDetail.js
+++ b/browser/main/Detail/SnippetNoteDetail.js
@@ -744,6 +744,7 @@ class SnippetNoteDetail extends React.Component {
          this.handleChange(e)}
         />
diff --git a/browser/main/Detail/TagSelect.js b/browser/main/Detail/TagSelect.js
index e51d5673..9bfbabbe 100644
--- a/browser/main/Detail/TagSelect.js
+++ b/browser/main/Detail/TagSelect.js
@@ -82,8 +82,14 @@ class TagSelect extends React.Component {
     value = _.isArray(value)
       ? value.slice()
       : []
-    value.push(newTag)
-    value = _.uniq(value)
+
+    if (!_.includes(value, newTag)) {
+        value.push(newTag)
+    }
+
+    if (this.props.saveTagsAlphabetically) {
+      value = _.sortBy(value)
+    }
 
     this.setState({
       newTag: ''
diff --git a/browser/main/modals/PreferencesModal/UiTab.js b/browser/main/modals/PreferencesModal/UiTab.js
index 40269190..a53281bc 100644
--- a/browser/main/modals/PreferencesModal/UiTab.js
+++ b/browser/main/modals/PreferencesModal/UiTab.js
@@ -71,6 +71,7 @@ class UiTab extends React.Component {
         confirmDeletion: this.refs.confirmDeletion.checked,
         showOnlyRelatedTags: this.refs.showOnlyRelatedTags.checked,
         showTagsAlphabetically: this.refs.showTagsAlphabetically.checked,
+        saveTagsAlphabetically: this.refs.saveTagsAlphabetically.checked,
         enableLiveNoteCounts: this.refs.enableLiveNoteCounts.checked,
         disableDirectWrite: this.refs.uiD2w != null
           ? this.refs.uiD2w.checked
@@ -244,6 +245,17 @@ class UiTab extends React.Component {
           }
           
Tags
+
+ +
+
- +
diff --git a/browser/styles/Detail/TagSelect.styl b/browser/styles/Detail/TagSelect.styl index 84fd74c2..69adc72b 100644 --- a/browser/styles/Detail/TagSelect.styl +++ b/browser/styles/Detail/TagSelect.styl @@ -14,18 +14,18 @@ list-style none padding 0 margin 0 - + border-radius 4px margin .2em 0 0 background-color $ui-noteList-backgroundColor border 1px solid rgba(0,0,0,.3) box-shadow .05em .2em .6em rgba(0,0,0,.2) text-shadow none - + &:empty, &[hidden] display none - + &:before content "" position absolute @@ -39,12 +39,12 @@ border-bottom 0 -webkit-transform rotate(45deg) transform rotate(45deg) - + li position relative padding 6px 18px 6px 10px cursor pointer - + li[aria-selected="true"] background-color alpha($ui-button--active-backgroundColor, 40%) color $ui-text-color @@ -53,15 +53,15 @@ body[data-theme="dark"] .TagSelect .react-autosuggest__input color $ui-dark-text-color - + ul border-color $ui-dark-borderColor background-color $ui-dark-noteList-backgroundColor color $ui-dark-text-color - + &:before background-color $ui-dark-noteList-backgroundColor - + li[aria-selected="true"] background-color $ui-dark-button--active-backgroundColor color $ui-dark-text-color @@ -70,32 +70,49 @@ body[data-theme="monokai"] .TagSelect .react-autosuggest__input color $ui-monokai-text-color - + ul border-color $ui-monokai-borderColor background-color $ui-monokai-noteList-backgroundColor color $ui-monokai-text-color - + &:before background-color $ui-dark-noteList-backgroundColor - + li[aria-selected="true"] background-color $ui-monokai-button-backgroundColor color $ui-monokai-text-color +body[data-theme="dracula"] + .TagSelect + .react-autosuggest__input + color $ui-dracula-text-color + + ul + border-color $ui-dracula-borderColor + background-color $ui-dracula-noteList-backgroundColor + color $ui-dracula-text-color + + &:before + background-color $ui-dark-noteList-backgroundColor + + li[aria-selected="true"] + background-color $ui-dracula-button-backgroundColor + color $ui-dracula-text-color + body[data-theme="solarized-dark"] .TagSelect .react-autosuggest__input color $ui-solarized-dark-text-color - + ul border-color $ui-solarized-dark-borderColor background-color $ui-solarized-dark-noteList-backgroundColor color $ui-solarized-dark-text-color - + &:before background-color $ui-solarized-dark-noteList-backgroundColor - + li[aria-selected="true"] background-color $ui-dark-button--active-backgroundColor color $ui-solarized-dark-text-color @@ -104,6 +121,6 @@ body[data-theme="white"] .TagSelect ul background-color $ui-white-noteList-backgroundColor - + li[aria-selected="true"] background-color $ui-button--active-backgroundColor \ No newline at end of file diff --git a/browser/styles/index.styl b/browser/styles/index.styl index a490b41c..e5eae141 100644 --- a/browser/styles/index.styl +++ b/browser/styles/index.styl @@ -383,4 +383,30 @@ modalMonokai() width 100% background-color $ui-monokai-backgroundColor overflow hidden + border-radius $modal-border-radius + +/******* Dracula theme ********/ +$ui-dracula-backgroundColor = #282a36 +$ui-dracula-noteList-backgroundColor = #282a36 +$ui-dracula-noteDetail-backgroundColor = #282a36 + +$ui-dracula-text-color = #f8f8f2 +$ui-dracula-active-color = #50fa7b + +$ui-dracula-borderColor = #44475a + +$ui-dracula-tag-backgroundColor = #50fa7b + +$ui-dracula-button-backgroundColor = #44475a +$ui-dracula-button--active-color = #ff79c6 +$ui-dracula-button--active-backgroundColor = #50fa7b +$ui-dracula-button--hover-backgroundColor = lighten($ui-dracula-backgroundColor, 10%) +$ui-dracula-button--focus-borderColor = lighten(#bd93f9, 25%) + +modalDracula() + position relative + z-index $modal-z-index + width 100% + background-color $ui-dracula-backgroundColor + overflow hidden border-radius $modal-border-radius \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 50374f74..1cc5fb08 100644 --- a/yarn.lock +++ b/yarn.lock @@ -188,6 +188,12 @@ ansi-escapes@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" +ansi-red@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-red/-/ansi-red-0.1.1.tgz#8c638f9d1080800a353c9c28c8a81ca4705d946c" + dependencies: + ansi-wrap "0.1.0" + ansi-regex@^0.2.0, ansi-regex@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-0.2.1.tgz#0d8e946967a3d8143f93e24e298525fc1b2235f9" @@ -218,6 +224,10 @@ ansi-styles@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178" +ansi-wrap@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" + anymatch@^1.3.0: version "1.3.2" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" @@ -255,7 +265,7 @@ argparse@^1.0.7, argparse@~1.0.3: dependencies: sprintf-js "~1.0.2" -"argparse@~ 0.1.11": +"argparse@~ 0.1.11", argparse@~0.1.15: version "0.1.16" resolved "https://registry.yarnpkg.com/argparse/-/argparse-0.1.16.tgz#cfd01e0fbba3d6caed049fbd758d40f65196f57c" dependencies: @@ -459,6 +469,10 @@ auto-bind@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/auto-bind/-/auto-bind-1.2.0.tgz#8b7e318aad53d43ba8a8ecaf0066d85d5f798cd6" +autolinker@~0.15.0: + version "0.15.3" + resolved "https://registry.yarnpkg.com/autolinker/-/autolinker-0.15.3.tgz#342417d8f2f3461b14cf09088d5edf8791dc9832" + autoprefixer@^6.3.1: version "6.7.7" resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-6.7.7.tgz#1dbd1c835658e35ce3f9984099db00585c782014" @@ -1793,7 +1807,7 @@ codemirror@^5.39.0: version "5.39.0" resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.39.0.tgz#4654f7d2f7e525e04a62e72d9482348ccb37dce5" -coffee-script@^1.10.0: +coffee-script@^1.10.0, coffee-script@^1.12.4: version "1.12.7" resolved "https://registry.yarnpkg.com/coffee-script/-/coffee-script-1.12.7.tgz#c05dae0cb79591d05b3070a8433a98c9a89ccc53" @@ -2666,6 +2680,10 @@ devtron@^1.1.0: highlight.js "^9.3.0" humanize-plus "^1.8.1" +diacritics-map@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/diacritics-map/-/diacritics-map-0.1.0.tgz#6dfc0ff9d01000a2edf2865371cac316e94977af" + diff@^3.2.0: version "3.5.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" @@ -4030,6 +4048,16 @@ graphlibrary@^2.2.0: dependencies: lodash "^4.17.5" +gray-matter@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/gray-matter/-/gray-matter-2.1.1.tgz#3042d9adec2a1ded6a7707a9ed2380f8a17a430e" + dependencies: + ansi-red "^0.1.1" + coffee-script "^1.12.4" + extend-shallow "^2.0.1" + js-yaml "^3.8.1" + toml "^2.3.2" + growly@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" @@ -5254,6 +5282,13 @@ js-yaml@^3.10.0, js-yaml@^3.5.1, js-yaml@^3.7.0: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@^3.8.1: + version "3.12.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + js-yaml@~2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-2.0.5.tgz#a25ae6509999e97df278c6719da11bd0687743a8" @@ -5487,6 +5522,12 @@ lazy-cache@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" +lazy-cache@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-2.0.2.tgz#b9190a4f913354694840859f8a8f7084d8822264" + dependencies: + set-getter "^0.1.0" + lcid@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" @@ -5514,6 +5555,15 @@ linkify-it@~1.2.0, linkify-it@~1.2.2: dependencies: uc.micro "^1.0.1" +list-item@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/list-item/-/list-item-1.1.1.tgz#0c65d00e287cb663ccb3cb3849a77e89ec268a56" + dependencies: + expand-range "^1.8.1" + extend-shallow "^2.0.1" + is-number "^2.1.0" + repeat-string "^1.5.2" + load-json-file@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" @@ -5783,6 +5833,27 @@ markdown-it@^6.0.1: mdurl "~1.0.1" uc.micro "^1.0.1" +markdown-link@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/markdown-link/-/markdown-link-0.1.1.tgz#32c5c65199a6457316322d1e4229d13407c8c7cf" + +markdown-toc@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/markdown-toc/-/markdown-toc-1.2.0.tgz#44a15606844490314afc0444483f9e7b1122c339" + dependencies: + concat-stream "^1.5.2" + diacritics-map "^0.1.0" + gray-matter "^2.1.0" + lazy-cache "^2.0.2" + list-item "^1.1.1" + markdown-link "^0.1.1" + minimist "^1.2.0" + mixin-deep "^1.1.3" + object.pick "^1.2.0" + remarkable "^1.7.1" + repeat-string "^1.6.1" + strip-color "^0.1.0" + match-at@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/match-at/-/match-at-0.1.1.tgz#25d040d291777704d5e6556bbb79230ec2de0540" @@ -6028,7 +6099,7 @@ minizlib@^1.1.0: dependencies: minipass "^2.2.1" -mixin-deep@^1.2.0: +mixin-deep@^1.1.3, mixin-deep@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" dependencies: @@ -6400,7 +6471,7 @@ object.omit@^2.0.0: for-own "^0.1.4" is-extendable "^0.1.1" -object.pick@^1.3.0: +object.pick@^1.2.0, object.pick@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" dependencies: @@ -7544,6 +7615,13 @@ release-zalgo@^1.0.0: dependencies: es6-error "^4.0.1" +remarkable@^1.7.1: + version "1.7.1" + resolved "https://registry.yarnpkg.com/remarkable/-/remarkable-1.7.1.tgz#aaca4972100b66a642a63a1021ca4bac1be3bff6" + dependencies: + argparse "~0.1.15" + autolinker "~0.15.0" + remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" @@ -7879,6 +7957,12 @@ set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" +set-getter@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/set-getter/-/set-getter-0.1.0.tgz#d769c182c9d5a51f409145f2fba82e5e86e80376" + dependencies: + to-object-path "^0.3.0" + set-immediate-shim@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" @@ -8325,6 +8409,10 @@ strip-bom@^2.0.0: dependencies: is-utf8 "^0.2.0" +strip-color@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/strip-color/-/strip-color-0.1.0.tgz#106f65d3d3e6a2d9401cac0eb0ce8b8a702b4f7b" + strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" @@ -8606,6 +8694,10 @@ toggle-selection@^1.0.3: version "1.0.6" resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32" +toml@^2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/toml/-/toml-2.3.3.tgz#8d683d729577cb286231dfc7a8affe58d31728fb" + touch@0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/touch/-/touch-0.0.3.tgz#51aef3d449571d4f287a5d87c9c8b49181a0db1d" From 610503472a50c534419a412267bdb7653edc7558 Mon Sep 17 00:00:00 2001 From: William Grant Date: Sun, 23 Sep 2018 16:35:26 +0200 Subject: [PATCH 23/90] finished styling --- browser/components/NoteItem.styl | 2 +- browser/main/Detail/FolderSelect.styl | 6 +++--- browser/main/Detail/TagSelect.styl | 4 ++-- browser/main/Detail/ToggleModeButton.styl | 4 ++-- browser/styles/index.styl | 18 ++++++++++++++---- 5 files changed, 22 insertions(+), 12 deletions(-) diff --git a/browser/components/NoteItem.styl b/browser/components/NoteItem.styl index 9a1cdbf2..6659fd05 100644 --- a/browser/components/NoteItem.styl +++ b/browser/components/NoteItem.styl @@ -441,7 +441,7 @@ body[data-theme="dracula"] .item-title .item-title-icon .item-bottom-time - color $ui-dracula-text-color + color $ui-dracula-active-color .item-bottom-tagList-item background-color alpha(#f8f8f2, 10%) color $ui-dracula-text-color diff --git a/browser/main/Detail/FolderSelect.styl b/browser/main/Detail/FolderSelect.styl index 7232ab2d..fe045e3a 100644 --- a/browser/main/Detail/FolderSelect.styl +++ b/browser/main/Detail/FolderSelect.styl @@ -162,10 +162,10 @@ body[data-theme="monokai"] body[data-theme="dracula"] .root - color $ui-dark-text-color + color $ui-dracula-text-color &:hover color #f8f8f2 - background-color $ui-dracula-button--hover-backgroundColor + background-color $ui-dark-button--hover-backgroundColor border-color $ui-dracula-borderColor .search-optionList @@ -181,7 +181,7 @@ body[data-theme="dracula"] background-color $ui-dracula-button--active-backgroundColor color $ui-dracula-button--active-color &:hover - background-color $ui-dracula-button--active-backgroundColor + background-color $ui-dark-button--hover-backgroundColor color $ui-dracula-button--active-color .search-optionList-item-name-surfix color $ui-dracula-inactive-text-color diff --git a/browser/main/Detail/TagSelect.styl b/browser/main/Detail/TagSelect.styl index e25e7868..68a9816b 100644 --- a/browser/main/Detail/TagSelect.styl +++ b/browser/main/Detail/TagSelect.styl @@ -78,11 +78,11 @@ body[data-theme="monokai"] body[data-theme="dracula"] .tag - background-color $ui-dracula-button-backgroundColor + background-color $ui-dracula-tag-backgroundColor .tag-removeButton border-color $ui-dracula-button--focus-borderColor background-color transparent .tag-label - color $ui-dracula-text-color \ No newline at end of file + color $ui-dracula-borderColor \ No newline at end of file diff --git a/browser/main/Detail/ToggleModeButton.styl b/browser/main/Detail/ToggleModeButton.styl index 21733af6..ddcd2cbd 100644 --- a/browser/main/Detail/ToggleModeButton.styl +++ b/browser/main/Detail/ToggleModeButton.styl @@ -68,5 +68,5 @@ body[data-theme="dracula"] .control-toggleModeButton background-color #282a36 .active - background-color #ff79c6 - box-shadow 2px 0px 7px #222222 \ No newline at end of file + background-color #bd93f9 + box-shadow 2px 0px 7px #222222 diff --git a/browser/styles/index.styl b/browser/styles/index.styl index e5eae141..72a8c5b3 100644 --- a/browser/styles/index.styl +++ b/browser/styles/index.styl @@ -128,6 +128,16 @@ colorMonokaiPrimaryButton() &:active:hover background-color $dark-primary-button-background--active +colorDraculaPrimaryButton() + color $ui-dracula-text-color + background-color $ui-dracula-button-backgroundColor + border none + &:hover + background-color $ui-dracula-button--active-backgroundColor + &:active + &:active:hover + background-color $ui-dracula-button--active-backgroundColor + // Danger button(Brand color) $danger-button-background = #c9302c @@ -391,17 +401,17 @@ $ui-dracula-noteList-backgroundColor = #282a36 $ui-dracula-noteDetail-backgroundColor = #282a36 $ui-dracula-text-color = #f8f8f2 -$ui-dracula-active-color = #50fa7b +$ui-dracula-active-color = #bd93f9 $ui-dracula-borderColor = #44475a $ui-dracula-tag-backgroundColor = #50fa7b $ui-dracula-button-backgroundColor = #44475a -$ui-dracula-button--active-color = #ff79c6 -$ui-dracula-button--active-backgroundColor = #50fa7b +$ui-dracula-button--active-color = #f8f8f2 +$ui-dracula-button--active-backgroundColor = #bd93f9 $ui-dracula-button--hover-backgroundColor = lighten($ui-dracula-backgroundColor, 10%) -$ui-dracula-button--focus-borderColor = lighten(#bd93f9, 25%) +$ui-dracula-button--focus-borderColor = lighten(#44475a, 25%) modalDracula() position relative From f41f4939bc73a54fcf9ebc416781ed7ecc703a43 Mon Sep 17 00:00:00 2001 From: William Grant Date: Sun, 23 Sep 2018 17:10:39 +0200 Subject: [PATCH 24/90] fix for the new folder modal --- browser/main/modals/CreateFolderModal.styl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/browser/main/modals/CreateFolderModal.styl b/browser/main/modals/CreateFolderModal.styl index e5ebb8ea..93848683 100644 --- a/browser/main/modals/CreateFolderModal.styl +++ b/browser/main/modals/CreateFolderModal.styl @@ -129,7 +129,7 @@ body[data-theme="monokai"] .control-confirmButton colorMonokaiPrimaryButton() -body[data-theme="Dracula"] +body[data-theme="dracula"] .root modalDracula() width 500px @@ -140,10 +140,10 @@ body[data-theme="Dracula"] .header background-color transparent border-color $ui-dark-borderColor - color $ui-Dracula-text-color + color $ui-dracula-text-color .control-folder-label - color $ui-Dracula-text-color + color $ui-dracula-text-color .control-folder-input border 1px solid $ui-input--create-folder-modal From 496090610f311c37c11e2ae045b00834fb4bc729 Mon Sep 17 00:00:00 2001 From: William Grant Date: Mon, 24 Sep 2018 17:20:01 +0200 Subject: [PATCH 25/90] updated tag color to cyan, fixed togglemodebutton styling --- browser/main/Detail/ToggleModeButton.styl | 2 +- browser/styles/index.styl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/browser/main/Detail/ToggleModeButton.styl b/browser/main/Detail/ToggleModeButton.styl index ddcd2cbd..7abdbdd9 100644 --- a/browser/main/Detail/ToggleModeButton.styl +++ b/browser/main/Detail/ToggleModeButton.styl @@ -66,7 +66,7 @@ body[data-theme="monokai"] body[data-theme="dracula"] .control-toggleModeButton - background-color #282a36 + background-color #44475a .active background-color #bd93f9 box-shadow 2px 0px 7px #222222 diff --git a/browser/styles/index.styl b/browser/styles/index.styl index 72a8c5b3..5c7ecb38 100644 --- a/browser/styles/index.styl +++ b/browser/styles/index.styl @@ -405,7 +405,7 @@ $ui-dracula-active-color = #bd93f9 $ui-dracula-borderColor = #44475a -$ui-dracula-tag-backgroundColor = #50fa7b +$ui-dracula-tag-backgroundColor = #8be9fd $ui-dracula-button-backgroundColor = #44475a $ui-dracula-button--active-color = #f8f8f2 From 686b9bc82ce732bebe81bdb0da57242b1bebb64f Mon Sep 17 00:00:00 2001 From: William Grant Date: Mon, 24 Sep 2018 17:46:31 +0200 Subject: [PATCH 26/90] cleanup duplicated code --- browser/components/RealtimeNotification.styl | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/browser/components/RealtimeNotification.styl b/browser/components/RealtimeNotification.styl index 203cc287..36330c48 100644 --- a/browser/components/RealtimeNotification.styl +++ b/browser/components/RealtimeNotification.styl @@ -53,16 +53,6 @@ body[data-theme="monokai"] &:hover color #5CB85C -body[data-theme="monokai"] - .notification-area - background-color none - - .notification-link - color $ui-monokai-text-color - border none - background-color $ui-monokai-button-backgroundColor - &:hover - color #5CB85C body[data-theme="dracula"] .notification-area background-color none From 504b6af3f6d7a654680409c4e5762c41603deb4e Mon Sep 17 00:00:00 2001 From: William Grant Date: Fri, 28 Sep 2018 17:58:30 +0200 Subject: [PATCH 27/90] fixed TodoListPercentage styling --- browser/components/TodoListPercentage.styl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/browser/components/TodoListPercentage.styl b/browser/components/TodoListPercentage.styl index af4d25ab..1aef0f4d 100644 --- a/browser/components/TodoListPercentage.styl +++ b/browser/components/TodoListPercentage.styl @@ -62,10 +62,10 @@ body[data-theme="monokai"] body[data-theme="dracula"] .percentageBar - background-color #50fa7b + background-color $ui-dracula-borderColor .progressBar - background-color: #44475a + background-color: $ui-dracula-active-color .percentageText - color #f8f8f2 \ No newline at end of file + color $ui-dracula-text-color \ No newline at end of file From 1246a677d13a443ac7630262b3a4b08b07875ca0 Mon Sep 17 00:00:00 2001 From: samherrington Date: Sat, 29 Sep 2018 15:50:32 -0500 Subject: [PATCH 28/90] Remove console.logs Using console in production is generally undesirable due to performance loss and security concerns. Errors were changed to console.error and console.logs were removed. --- browser/main/Detail/SnippetNoteDetail.js | 3 --- browser/main/Main.js | 1 - browser/main/NoteList/index.js | 3 --- browser/main/SideNav/index.js | 1 - browser/main/lib/AwsMobileAnalyticsConfig.js | 5 ++--- browser/main/lib/ConfigManager.js | 1 - browser/main/lib/dataApi/attachmentManagement.js | 1 - browser/main/lib/dataApi/renameStorage.js | 1 - browser/main/lib/dataApi/resolveStorageData.js | 3 +-- browser/main/lib/dataApi/resolveStorageNotes.js | 1 - browser/main/lib/dataApi/toggleStorage.js | 1 - browser/main/lib/eventEmitter.js | 1 - browser/main/lib/ipcClient.js | 5 ++--- browser/main/store.js | 1 - dev-scripts/dev.js | 2 +- lib/main-app.js | 2 +- 16 files changed, 7 insertions(+), 25 deletions(-) diff --git a/browser/main/Detail/SnippetNoteDetail.js b/browser/main/Detail/SnippetNoteDetail.js index fefba2ce..acf07caa 100644 --- a/browser/main/Detail/SnippetNoteDetail.js +++ b/browser/main/Detail/SnippetNoteDetail.js @@ -354,12 +354,10 @@ class SnippetNoteDetail extends React.Component { this.refs['code-' + this.state.snippetIndex].reload() if (this.visibleTabs.offsetWidth > this.allTabs.scrollWidth) { - console.log('no need for arrows') this.moveTabBarBy(0) } else { const lastTab = this.allTabs.lastChild if (lastTab.offsetLeft + lastTab.offsetWidth < this.visibleTabs.offsetWidth) { - console.log('need to scroll') const width = this.visibleTabs.offsetWidth const newLeft = lastTab.offsetLeft + lastTab.offsetWidth - width this.moveTabBarBy(newLeft > 0 ? -newLeft : 0) @@ -627,7 +625,6 @@ class SnippetNoteDetail extends React.Component { } focusEditor () { - console.log('code-' + this.state.snippetIndex) this.refs['code-' + this.state.snippetIndex].focus() } diff --git a/browser/main/Main.js b/browser/main/Main.js index 0f31a591..bb2d70eb 100644 --- a/browser/main/Main.js +++ b/browser/main/Main.js @@ -80,7 +80,6 @@ class Main extends React.Component { } }) .then(data => { - console.log(data) store.dispatch({ type: 'ADD_STORAGE', storage: data.storage, diff --git a/browser/main/NoteList/index.js b/browser/main/NoteList/index.js index 880f8479..c2e48456 100644 --- a/browser/main/NoteList/index.js +++ b/browser/main/NoteList/index.js @@ -56,7 +56,6 @@ class NoteList extends React.Component { super(props) this.selectNextNoteHandler = () => { - console.log('fired next') this.selectNextNote() } this.selectPriorNoteHandler = () => { @@ -616,7 +615,6 @@ class NoteList extends React.Component { .catch((err) => { console.error('Cannot Delete note: ' + err) }) - console.log('Notes were all deleted') } else { if (!confirmDeleteNote(confirmDeletion, false)) return @@ -636,7 +634,6 @@ class NoteList extends React.Component { }) }) AwsMobileAnalyticsConfig.recordDynamicCustomEvent('EDIT_NOTE') - console.log('Notes went to trash') }) .catch((err) => { console.error('Notes could not go to trash: ' + err) diff --git a/browser/main/SideNav/index.js b/browser/main/SideNav/index.js index 977a8fb5..f32d0878 100644 --- a/browser/main/SideNav/index.js +++ b/browser/main/SideNav/index.js @@ -247,7 +247,6 @@ class SideNav extends React.Component { .catch((err) => { console.error('Cannot Delete note: ' + err) }) - console.log('Trash emptied') } handleFilterButtonContextMenu (event) { diff --git a/browser/main/lib/AwsMobileAnalyticsConfig.js b/browser/main/lib/AwsMobileAnalyticsConfig.js index 1ef4f8da..b2e91544 100644 --- a/browser/main/lib/AwsMobileAnalyticsConfig.js +++ b/browser/main/lib/AwsMobileAnalyticsConfig.js @@ -45,7 +45,6 @@ function initAwsMobileAnalytics () { if (getSendEventCond()) return AWS.config.credentials.get((err) => { if (!err) { - console.log('Cognito Identity ID: ' + AWS.config.credentials.identityId) recordDynamicCustomEvent('APP_STARTED') recordStaticCustomEvent() } @@ -58,7 +57,7 @@ function recordDynamicCustomEvent (type, options = {}) { mobileAnalyticsClient.recordEvent(type, options) } catch (analyticsError) { if (analyticsError instanceof ReferenceError) { - console.log(analyticsError.name + ': ' + analyticsError.message) + return } } } @@ -71,7 +70,7 @@ function recordStaticCustomEvent () { }) } catch (analyticsError) { if (analyticsError instanceof ReferenceError) { - console.log(analyticsError.name + ': ' + analyticsError.message) + return } } } diff --git a/browser/main/lib/ConfigManager.js b/browser/main/lib/ConfigManager.js index 2c601b57..13c0f853 100644 --- a/browser/main/lib/ConfigManager.js +++ b/browser/main/lib/ConfigManager.js @@ -87,7 +87,6 @@ function validate (config) { } function _save (config) { - console.log(config) window.localStorage.setItem('config', JSON.stringify(config)) } diff --git a/browser/main/lib/dataApi/attachmentManagement.js b/browser/main/lib/dataApi/attachmentManagement.js index d1e0ab62..2bdb74db 100644 --- a/browser/main/lib/dataApi/attachmentManagement.js +++ b/browser/main/lib/dataApi/attachmentManagement.js @@ -402,7 +402,6 @@ function handleAttachmentLinkPaste (storageKey, noteKey, linkText) { return modifiedLinkText }) } else { - console.log('One if the parameters was null -> Do nothing..') return Promise.resolve(linkText) } } diff --git a/browser/main/lib/dataApi/renameStorage.js b/browser/main/lib/dataApi/renameStorage.js index 78242bed..3b806d1c 100644 --- a/browser/main/lib/dataApi/renameStorage.js +++ b/browser/main/lib/dataApi/renameStorage.js @@ -14,7 +14,6 @@ function renameStorage (key, name) { cachedStorageList = JSON.parse(localStorage.getItem('storages')) if (!_.isArray(cachedStorageList)) throw new Error('invalid storages') } catch (err) { - console.log('error got') console.error(err) return Promise.reject(err) } diff --git a/browser/main/lib/dataApi/resolveStorageData.js b/browser/main/lib/dataApi/resolveStorageData.js index 681a102e..2fef128c 100644 --- a/browser/main/lib/dataApi/resolveStorageData.js +++ b/browser/main/lib/dataApi/resolveStorageData.js @@ -32,12 +32,11 @@ function resolveStorageData (storageCache) { const version = parseInt(storage.version, 10) if (version >= 1) { if (version > 1) { - console.log('The repository version is newer than one of current app.') + return } return Promise.resolve(storage) } - console.log('Transform Legacy storage', storage.path) return migrateFromV6Storage(storage.path) .then(() => storage) } diff --git a/browser/main/lib/dataApi/resolveStorageNotes.js b/browser/main/lib/dataApi/resolveStorageNotes.js index fa3f19ae..6f776240 100644 --- a/browser/main/lib/dataApi/resolveStorageNotes.js +++ b/browser/main/lib/dataApi/resolveStorageNotes.js @@ -9,7 +9,6 @@ function resolveStorageNotes (storage) { notePathList = sander.readdirSync(notesDirPath) } catch (err) { if (err.code === 'ENOENT') { - console.log(notesDirPath, ' doesn\'t exist.') sander.mkdirSync(notesDirPath) } else { console.warn('Failed to find note dir', notesDirPath, err) diff --git a/browser/main/lib/dataApi/toggleStorage.js b/browser/main/lib/dataApi/toggleStorage.js index dbb625c3..246d85ef 100644 --- a/browser/main/lib/dataApi/toggleStorage.js +++ b/browser/main/lib/dataApi/toggleStorage.js @@ -12,7 +12,6 @@ function toggleStorage (key, isOpen) { cachedStorageList = JSON.parse(localStorage.getItem('storages')) if (!_.isArray(cachedStorageList)) throw new Error('invalid storages') } catch (err) { - console.log('error got') console.error(err) return Promise.reject(err) } diff --git a/browser/main/lib/eventEmitter.js b/browser/main/lib/eventEmitter.js index de08f078..1276545b 100644 --- a/browser/main/lib/eventEmitter.js +++ b/browser/main/lib/eventEmitter.js @@ -14,7 +14,6 @@ function once (name, listener) { } function emit (name, ...args) { - console.log(name) remote.getCurrentWindow().webContents.send(name, ...args) } diff --git a/browser/main/lib/ipcClient.js b/browser/main/lib/ipcClient.js index 0c916617..c06296b5 100644 --- a/browser/main/lib/ipcClient.js +++ b/browser/main/lib/ipcClient.js @@ -14,14 +14,13 @@ nodeIpc.connectTo( path.join(app.getPath('userData'), 'boostnote.service'), function () { nodeIpc.of.node.on('error', function (err) { - console.log(err) + console.error(err) }) nodeIpc.of.node.on('connect', function () { - console.log('Connected successfully') ipcRenderer.send('config-renew', {config: ConfigManager.get()}) }) nodeIpc.of.node.on('disconnect', function () { - console.log('disconnected') + return }) } ) diff --git a/browser/main/store.js b/browser/main/store.js index b8f13cc8..11ff2f3f 100644 --- a/browser/main/store.js +++ b/browser/main/store.js @@ -113,7 +113,6 @@ function data (state = defaultDataMap(), action) { // If storage chanced, origin key must be discarded if (originKey !== uniqueKey) { - console.log('diffrent storage') // From isStarred if (originNote.isStarred) { state.starredSet = new Set(state.starredSet) diff --git a/dev-scripts/dev.js b/dev-scripts/dev.js index 000a1bfd..d6968e7f 100644 --- a/dev-scripts/dev.js +++ b/dev-scripts/dev.js @@ -37,7 +37,7 @@ function startServer () { resolve() } else { if (!firstRun) { - console.log(stats.compilation.errors[0]) + return } else { firstRun = false reject(stats.compilation.errors[0]) diff --git a/lib/main-app.js b/lib/main-app.js index 1ab9f4ca..f25d07d2 100644 --- a/lib/main-app.js +++ b/lib/main-app.js @@ -59,7 +59,7 @@ updater.on('update-downloaded', (info) => { }) updater.autoUpdater.on('error', (err) => { - console.log(err) + console.error(err) }) ipc.on('update-app-confirm', function (event, msg) { From dd913279d775233be6c654706f1c2b8b5814e2e4 Mon Sep 17 00:00:00 2001 From: samherrington Date: Sat, 29 Sep 2018 15:57:02 -0500 Subject: [PATCH 29/90] Fixup for errors --- browser/main/lib/AwsMobileAnalyticsConfig.js | 4 ++-- browser/main/lib/dataApi/resolveStorageNotes.js | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/browser/main/lib/AwsMobileAnalyticsConfig.js b/browser/main/lib/AwsMobileAnalyticsConfig.js index b2e91544..e4a21a92 100644 --- a/browser/main/lib/AwsMobileAnalyticsConfig.js +++ b/browser/main/lib/AwsMobileAnalyticsConfig.js @@ -57,7 +57,7 @@ function recordDynamicCustomEvent (type, options = {}) { mobileAnalyticsClient.recordEvent(type, options) } catch (analyticsError) { if (analyticsError instanceof ReferenceError) { - return + console.error(analyticsError.name + ': ' + analyticsError.message) } } } @@ -70,7 +70,7 @@ function recordStaticCustomEvent () { }) } catch (analyticsError) { if (analyticsError instanceof ReferenceError) { - return + console.error(analyticsError.name + ': ' + analyticsError.message) } } } diff --git a/browser/main/lib/dataApi/resolveStorageNotes.js b/browser/main/lib/dataApi/resolveStorageNotes.js index 6f776240..9da27248 100644 --- a/browser/main/lib/dataApi/resolveStorageNotes.js +++ b/browser/main/lib/dataApi/resolveStorageNotes.js @@ -9,6 +9,7 @@ function resolveStorageNotes (storage) { notePathList = sander.readdirSync(notesDirPath) } catch (err) { if (err.code === 'ENOENT') { + console.error(notesDirPath, ' doesn\'t exist.') sander.mkdirSync(notesDirPath) } else { console.warn('Failed to find note dir', notesDirPath, err) From b29c0fe8cbab43e99edb863d7985228ef25e6f80 Mon Sep 17 00:00:00 2001 From: jacobherrington Date: Sat, 29 Sep 2018 23:17:19 -0500 Subject: [PATCH 30/90] Fix TypeError thrown on the Snippets page This commit protects from a TypeError that is consistently thrown on the Snippets page. --- browser/main/modals/PreferencesModal/SnippetTab.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/browser/main/modals/PreferencesModal/SnippetTab.js b/browser/main/modals/PreferencesModal/SnippetTab.js index e35ecd69..0e154c29 100644 --- a/browser/main/modals/PreferencesModal/SnippetTab.js +++ b/browser/main/modals/PreferencesModal/SnippetTab.js @@ -27,12 +27,14 @@ class SnippetTab extends React.Component { handleSnippetSelect (snippet) { const { currentSnippet } = this.state - if (currentSnippet === null || currentSnippet.id !== snippet.id) { - dataApi.fetchSnippet(snippet.id).then(changedSnippet => { - // notify the snippet editor to load the content of the new snippet - this.snippetEditor.onSnippetChanged(changedSnippet) - this.setState({currentSnippet: changedSnippet}) - }) + if (snippet !== null) { + if (currentSnippet === null || currentSnippet.id !== snippet.id) { + dataApi.fetchSnippet(snippet.id).then(changedSnippet => { + // notify the snippet editor to load the content of the new snippet + this.snippetEditor.onSnippetChanged(changedSnippet) + this.setState({currentSnippet: changedSnippet}) + }) + } } } From 818ee16e397700ac8ebe02a03596401048b16623 Mon Sep 17 00:00:00 2001 From: Baptiste Augrain Date: Sun, 30 Sep 2018 22:41:49 +0200 Subject: [PATCH 31/90] update codemirror --- package.json | 2 +- yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index f4e5f532..e27370c5 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "aws-sdk": "^2.48.0", "aws-sdk-mobile-analytics": "^0.9.2", "chart.js": "^2.7.2", - "codemirror": "^5.39.0", + "codemirror": "^5.40.2", "codemirror-mode-elixir": "^1.1.1", "electron-config": "^1.0.0", "electron-gh-releases": "^2.0.2", diff --git a/yarn.lock b/yarn.lock index 687bb6de..541cf4a8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1803,9 +1803,9 @@ codemirror@^5.18.2, codemirror@^5.20.2: version "5.38.0" resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.38.0.tgz#26a9551446e51dbdde36aabe60f72469724fd332" -codemirror@^5.39.0: - version "5.39.0" - resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.39.0.tgz#4654f7d2f7e525e04a62e72d9482348ccb37dce5" +codemirror@^5.40.2: + version "5.40.2" + resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.40.2.tgz#f4a41fee2d84e679543591b3680af259d903330b" coffee-script@^1.10.0, coffee-script@^1.12.4: version "1.12.7" From d365aaf270be134ab043f97e0b877529b52c7d3d Mon Sep 17 00:00:00 2001 From: Baptiste Augrain Date: Sun, 30 Sep 2018 23:21:48 +0200 Subject: [PATCH 32/90] fix graphical bugs --- browser/main/global.styl | 3 +++ browser/main/modals/PreferencesModal/SnippetList.js | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/browser/main/global.styl b/browser/main/global.styl index 815cff4e..5f1b14c9 100644 --- a/browser/main/global.styl +++ b/browser/main/global.styl @@ -18,6 +18,9 @@ body ::-webkit-scrollbar width 12px +::-webkit-scrollbar-corner + background-color: transparent; + ::-webkit-scrollbar-thumb background-color rgba(0, 0, 0, 0.15) diff --git a/browser/main/modals/PreferencesModal/SnippetList.js b/browser/main/modals/PreferencesModal/SnippetList.js index 512ae997..3790eb3f 100644 --- a/browser/main/modals/PreferencesModal/SnippetList.js +++ b/browser/main/modals/PreferencesModal/SnippetList.js @@ -55,7 +55,11 @@ class SnippetList extends React.Component { defineSnippetStyleName (snippet) { const { currentSnippet } = this.props - if (currentSnippet == null) return + + if (currentSnippet == null) { + return 'snippet-item' + } + if (currentSnippet.id === snippet.id) { return 'snippet-item-selected' } else { From 3e2a366dc6084ec99e7ba85009be1bda019a8781 Mon Sep 17 00:00:00 2001 From: jacobherrington Date: Sun, 30 Sep 2018 16:57:58 -0500 Subject: [PATCH 33/90] Add a Copy button the Snippets tab --- browser/main/modals/PreferencesModal/SnippetTab.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/browser/main/modals/PreferencesModal/SnippetTab.js b/browser/main/modals/PreferencesModal/SnippetTab.js index e35ecd69..f16bac7b 100644 --- a/browser/main/modals/PreferencesModal/SnippetTab.js +++ b/browser/main/modals/PreferencesModal/SnippetTab.js @@ -6,6 +6,7 @@ import i18n from 'browser/lib/i18n' import dataApi from 'browser/main/lib/dataApi' import SnippetList from './SnippetList' import eventEmitter from 'browser/main/lib/eventEmitter' +import copy from 'copy-to-clipboard' class SnippetTab extends React.Component { constructor (props) { @@ -54,6 +55,10 @@ class SnippetTab extends React.Component { } } + handleCopySnippet (e) { + copy(this.state.currentSnippet.content) + } + render () { const { config, storageKey } = this.props const { currentSnippet } = this.state @@ -70,6 +75,13 @@ class SnippetTab extends React.Component { onSnippetDeleted={this.handleDeleteSnippet.bind(this)} currentSnippet={currentSnippet} />
+
+
+ +
+
{i18n.__('Snippet name')}
From ca69bd69f27905b707c100fc24b755b15906d5f1 Mon Sep 17 00:00:00 2001 From: Sam Herrington <33494799+samherrington@users.noreply.github.com> Date: Sun, 30 Sep 2018 17:46:38 -0500 Subject: [PATCH 34/90] Remove unnecessary conditional logic In reference to PR feedback. --- browser/main/lib/dataApi/resolveStorageData.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/browser/main/lib/dataApi/resolveStorageData.js b/browser/main/lib/dataApi/resolveStorageData.js index 2fef128c..da41f3d0 100644 --- a/browser/main/lib/dataApi/resolveStorageData.js +++ b/browser/main/lib/dataApi/resolveStorageData.js @@ -31,9 +31,6 @@ function resolveStorageData (storageCache) { const version = parseInt(storage.version, 10) if (version >= 1) { - if (version > 1) { - return - } return Promise.resolve(storage) } From 4717e4fe3ffd427649df4f40d2e2b776c6ab6112 Mon Sep 17 00:00:00 2001 From: jacobherrington Date: Sun, 30 Sep 2018 20:17:10 -0500 Subject: [PATCH 35/90] Add an event for deletion hotkey --- browser/main/Detail/MarkdownNoteDetail.js | 5 +++++ browser/main/lib/shortcut.js | 3 +++ 2 files changed, 8 insertions(+) diff --git a/browser/main/Detail/MarkdownNoteDetail.js b/browser/main/Detail/MarkdownNoteDetail.js index e4493a80..0f182636 100755 --- a/browser/main/Detail/MarkdownNoteDetail.js +++ b/browser/main/Detail/MarkdownNoteDetail.js @@ -61,6 +61,7 @@ class MarkdownNoteDetail extends React.Component { const reversedType = this.state.editorType === 'SPLIT' ? 'EDITOR_PREVIEW' : 'SPLIT' this.handleSwitchMode(reversedType) }) + ee.on('hotkey:deletenote', this.handleDeleteNote.bind(this)) ee.on('code:generate-toc', this.generateToc) } @@ -293,6 +294,10 @@ class MarkdownNoteDetail extends React.Component { }) } + handleDeleteNote () { + this.handleTrashButtonClick() + } + renderEditor () { const { config, ignorePreviewPointerEvents } = this.props const { note } = this.state diff --git a/browser/main/lib/shortcut.js b/browser/main/lib/shortcut.js index a6f33196..93e33c9b 100644 --- a/browser/main/lib/shortcut.js +++ b/browser/main/lib/shortcut.js @@ -3,5 +3,8 @@ import ee from 'browser/main/lib/eventEmitter' module.exports = { 'toggleMode': () => { ee.emit('topbar:togglemodebutton') + }, + 'deleteNote': () => { + ee.emit('hotkey:deletenote') } } From 3f1fa44ee777d0d4d4fcb7f8bf248831b6e82c92 Mon Sep 17 00:00:00 2001 From: jacobherrington Date: Sun, 30 Sep 2018 20:19:22 -0500 Subject: [PATCH 36/90] Add a default hotkey for deleteNote --- browser/main/lib/ConfigManager.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/browser/main/lib/ConfigManager.js b/browser/main/lib/ConfigManager.js index 5ffb1bc7..6e4e9ebd 100644 --- a/browser/main/lib/ConfigManager.js +++ b/browser/main/lib/ConfigManager.js @@ -24,7 +24,8 @@ export const DEFAULT_CONFIG = { amaEnabled: true, hotkey: { toggleMain: OSX ? 'Command + Alt + L' : 'Super + Alt + E', - toggleMode: OSX ? 'Command + Option + M' : 'Ctrl + M' + toggleMode: OSX ? 'Command + Option + M' : 'Ctrl + M', + deleteNote: OSX ? 'Command + Backspace' : 'Command + Backspace' }, ui: { language: 'en', From db2c6c99f79a55fb84932d038083ee622c6c3120 Mon Sep 17 00:00:00 2001 From: jacobherrington Date: Sun, 30 Sep 2018 20:44:23 -0500 Subject: [PATCH 37/90] Change default hotkeys Setting the default hotkeys to be more consistent on OS X (using the Alt notation as opposed to the Option notation). --- browser/main/lib/ConfigManager.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/browser/main/lib/ConfigManager.js b/browser/main/lib/ConfigManager.js index 6e4e9ebd..42bf35c9 100644 --- a/browser/main/lib/ConfigManager.js +++ b/browser/main/lib/ConfigManager.js @@ -24,8 +24,8 @@ export const DEFAULT_CONFIG = { amaEnabled: true, hotkey: { toggleMain: OSX ? 'Command + Alt + L' : 'Super + Alt + E', - toggleMode: OSX ? 'Command + Option + M' : 'Ctrl + M', - deleteNote: OSX ? 'Command + Backspace' : 'Command + Backspace' + toggleMode: OSX ? 'Command + Alt + M' : 'Ctrl + M', + deleteNote: OSX ? 'Command + Alt + Backspace' : 'Ctrl + Alt + Backspace' }, ui: { language: 'en', From 80666fed1ac884bd909c016de2fab965aeeddde1 Mon Sep 17 00:00:00 2001 From: jacobherrington Date: Sun, 30 Sep 2018 20:58:56 -0500 Subject: [PATCH 38/90] Add UI to change deleteNote hotkey --- browser/main/modals/PreferencesModal/HotkeyTab.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/browser/main/modals/PreferencesModal/HotkeyTab.js b/browser/main/modals/PreferencesModal/HotkeyTab.js index 1c40a13a..9f964957 100644 --- a/browser/main/modals/PreferencesModal/HotkeyTab.js +++ b/browser/main/modals/PreferencesModal/HotkeyTab.js @@ -68,7 +68,8 @@ class HotkeyTab extends React.Component { const { config } = this.state config.hotkey = { toggleMain: this.refs.toggleMain.value, - toggleMode: this.refs.toggleMode.value + toggleMode: this.refs.toggleMode.value, + deleteNote: this.refs.deleteNote.value } this.setState({ config @@ -127,6 +128,17 @@ class HotkeyTab extends React.Component { />
+
+
{i18n.__('Delete Note')}
+
+ this.handleHotkeyChange(e)} + ref='deleteNote' + value={config.hotkey.deleteNote} + type='text' + /> +
+
+
+ +
) diff --git a/browser/components/MarkdownPreview.js b/browser/components/MarkdownPreview.js index e69f312e..47f30ecc 100755 --- a/browser/components/MarkdownPreview.js +++ b/browser/components/MarkdownPreview.js @@ -484,10 +484,6 @@ export default class MarkdownPreview extends React.Component { eventEmitter.on('export:save-md', this.saveAsMdHandler) eventEmitter.on('export:save-html', this.saveAsHtmlHandler) eventEmitter.on('print', this.printHandler) - eventEmitter.on('config-renew', () => { - this.markdown.updateConfig() - this.rewriteIframe() - }) } componentWillUnmount () { @@ -531,7 +527,8 @@ export default class MarkdownPreview extends React.Component { prevProps.smartQuotes !== this.props.smartQuotes || prevProps.sanitize !== this.props.sanitize || prevProps.smartArrows !== this.props.smartArrows || - prevProps.breaks !== this.props.breaks + prevProps.breaks !== this.props.breaks || + prevProps.lineThroughCheckbox !== this.props.lineThroughCheckbox ) { this.initMarkdown() this.rewriteIframe() diff --git a/browser/components/MarkdownSplitEditor.js b/browser/components/MarkdownSplitEditor.js index d714125a..208a29b4 100644 --- a/browser/components/MarkdownSplitEditor.js +++ b/browser/components/MarkdownSplitEditor.js @@ -192,6 +192,7 @@ class MarkdownSplitEditor extends React.Component { noteKey={noteKey} customCSS={config.preview.customCSS} allowCustomCSS={config.preview.allowCustomCSS} + lineThroughCheckbox={config.preview.lineThroughCheckbox} />
) From 3c404f36784548675f4569e0cb86c4a3c8163f27 Mon Sep 17 00:00:00 2001 From: Baptiste Augrain Date: Thu, 11 Oct 2018 15:09:26 +0200 Subject: [PATCH 67/90] remove unused method --- browser/lib/markdown.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/browser/lib/markdown.js b/browser/lib/markdown.js index 248dbb4b..49260740 100644 --- a/browser/lib/markdown.js +++ b/browser/lib/markdown.js @@ -21,7 +21,7 @@ function createGutter (str, firstLineNumber) { class Markdown { constructor (options = {}) { - let config = ConfigManager.get() + const config = ConfigManager.get() const defaultOptions = { typographer: config.preview.smartQuotes, linkify: true, @@ -265,9 +265,6 @@ class Markdown { } // FIXME We should not depend on global variable. window.md = this.md - this.updateConfig = () => { - config = ConfigManager.get() - } } render (content) { From ca038937e9cfab366a1af89f31b5ace8a77a6b81 Mon Sep 17 00:00:00 2001 From: jacob Date: Fri, 12 Oct 2018 22:10:35 -0500 Subject: [PATCH 68/90] Update ConfigManager.js --- browser/main/lib/ConfigManager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/main/lib/ConfigManager.js b/browser/main/lib/ConfigManager.js index 42bf35c9..7f8ae6fb 100644 --- a/browser/main/lib/ConfigManager.js +++ b/browser/main/lib/ConfigManager.js @@ -25,7 +25,7 @@ export const DEFAULT_CONFIG = { hotkey: { toggleMain: OSX ? 'Command + Alt + L' : 'Super + Alt + E', toggleMode: OSX ? 'Command + Alt + M' : 'Ctrl + M', - deleteNote: OSX ? 'Command + Alt + Backspace' : 'Ctrl + Alt + Backspace' + deleteNote: OSX ? 'Command + Shift + Backspace' : 'Ctrl + Shift + Backspace' }, ui: { language: 'en', From e536d203d22401f0ae7214b4efe75796aa4fe56d Mon Sep 17 00:00:00 2001 From: antogyn Date: Sat, 13 Oct 2018 14:21:46 +0200 Subject: [PATCH 69/90] feat(editor): add ability to jump to line --- browser/components/CodeEditor.js | 10 +++++++++- browser/components/MarkdownPreview.js | 9 +++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/browser/components/CodeEditor.js b/browser/components/CodeEditor.js index c36a50c1..9953f9bf 100644 --- a/browser/components/CodeEditor.js +++ b/browser/components/CodeEditor.js @@ -57,6 +57,7 @@ export default class CodeEditor extends React.Component { } this.searchHandler = (e, msg) => this.handleSearch(msg) this.searchState = null + this.scrollToLineHandeler = this.scrollToLine.bind(this) this.formatTable = () => this.handleFormatTable() this.editorActivityHandler = () => this.handleEditorActivity() @@ -125,6 +126,7 @@ export default class CodeEditor extends React.Component { componentDidMount () { const { rulers, enableRulers } = this.props const expandSnippet = this.expandSnippet.bind(this) + eventEmitter.on('line:jump', this.scrollToLineHandeler) const defaultSnippet = [ { @@ -475,7 +477,13 @@ export default class CodeEditor extends React.Component { moveCursorTo (row, col) {} - scrollToLine (num) {} + scrollToLine (event, num) { + const cursor = { + line: num, + ch: 1 + } + this.editor.setCursor(cursor) + } focus () { this.editor.focus() diff --git a/browser/components/MarkdownPreview.js b/browser/components/MarkdownPreview.js index e69f312e..dbb2acd7 100755 --- a/browser/components/MarkdownPreview.js +++ b/browser/components/MarkdownPreview.js @@ -860,6 +860,15 @@ export default class MarkdownPreview extends React.Component { return } + const regexIsLine = /^:line:[0-9]/ + if (regexIsLine.test(linkHash)) { + const numberPattern = /\d+/g + + const lineNumber = parseInt(linkHash.match(numberPattern)[0]) + eventEmitter.emit('line:jump', lineNumber) + return + } + // this will match the old link format storage.key-note.key // e.g. // 877f99c3268608328037-1c211eb7dcb463de6490 From 1da477d1d1992b5741dc4686e9a501ca857a90c5 Mon Sep 17 00:00:00 2001 From: Baptiste Augrain Date: Mon, 15 Oct 2018 08:09:50 +0200 Subject: [PATCH 70/90] add context menu to delete tag --- browser/components/TagListItem.js | 4 +- browser/main/Detail/MarkdownNoteDetail.js | 2 +- browser/main/Main.js | 2 +- browser/main/SideNav/index.js | 59 +++++++++++++++++++ .../TagListItem.snapshot.test.js.snap | 1 + 5 files changed, 64 insertions(+), 4 deletions(-) diff --git a/browser/components/TagListItem.js b/browser/components/TagListItem.js index 6cd50c9c..19f11791 100644 --- a/browser/components/TagListItem.js +++ b/browser/components/TagListItem.js @@ -14,8 +14,8 @@ import CSSModules from 'browser/lib/CSSModules' * @param {bool} isRelated */ -const TagListItem = ({name, handleClickTagListItem, handleClickNarrowToTag, isActive, isRelated, count}) => ( -
+const TagListItem = ({name, handleClickTagListItem, handleClickNarrowToTag, handleContextMenu, isActive, isRelated, count}) => ( +
handleContextMenu(e, name)}> {isRelated ?
this.handleSwitchMode(e)} editorType={editorType} /> From ff3026686ff7a8c8954d94527dbfb4538c9addcd Mon Sep 17 00:00:00 2001 From: Junyoung Choi Date: Fri, 19 Oct 2018 19:04:53 +0900 Subject: [PATCH 77/90] v0.11.10 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index be70464b..d39d6f37 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "boost", "productName": "Boostnote", - "version": "0.11.9", + "version": "0.11.10", "main": "index.js", "description": "Boostnote", "license": "GPL-3.0", From 5aaecfc0fe8a4ac76b62c669c27a159205b05271 Mon Sep 17 00:00:00 2001 From: Baptiste Augrain Date: Fri, 19 Oct 2018 14:06:21 +0200 Subject: [PATCH 78/90] fix color for even rows in table --- extra_scripts/codemirror/mode/bfm/bfm.css | 5 +-- extra_scripts/codemirror/mode/bfm/bfm.js | 3 ++ gruntfile.js | 44 ++++++++++++++++++++--- 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/extra_scripts/codemirror/mode/bfm/bfm.css b/extra_scripts/codemirror/mode/bfm/bfm.css index cb6fd638..f14d6f7c 100644 --- a/extra_scripts/codemirror/mode/bfm/bfm.css +++ b/extra_scripts/codemirror/mode/bfm/bfm.css @@ -34,11 +34,12 @@ .cm-s-rubyblue.CodeMirror .cm-table-row-even { background-color: rgb(41, 58, 73); } .cm-s-seti.CodeMirror .cm-table-row-even { background-color: rgb(40, 42, 43); } .cm-s-shadowfox.CodeMirror .cm-table-row-even { background-color: rgb(56, 56, 59); } -.cm-s-solarized.CodeMirror .cm-table-row-even { background-color: rgb(242, 242, 242); } .cm-s-the-matrix.CodeMirror .cm-table-row-even { background-color: rgb(0, 26, 0); } .cm-s-tomorrow-night-bright.CodeMirror .cm-table-row-even { background-color: rgb(23, 23, 23); } .cm-s-tomorrow-night-eighties.CodeMirror .cm-table-row-even { background-color: rgb(20, 20, 20); } .cm-s-twilight.CodeMirror .cm-table-row-even { background-color: rgb(43, 43, 43); } .cm-s-vibrant-ink.CodeMirror .cm-table-row-even { background-color: rgb(26, 26, 26); } .cm-s-xq-dark.CodeMirror .cm-table-row-even { background-color: rgb(34, 25, 53); } -.cm-s-yeti.CodeMirror .cm-table-row-even { background-color: rgb(235, 232, 230); } \ No newline at end of file +.cm-s-yeti.CodeMirror .cm-table-row-even { background-color: rgb(235, 232, 230); } +.cm-s-solarized.cm-s-dark .cm-table-row-even { background-color: rgb(13, 54, 64); } +.cm-s-solarized.cm-s-light .cm-table-row-even { background-color: rgb(245, 240, 222); } \ No newline at end of file diff --git a/extra_scripts/codemirror/mode/bfm/bfm.js b/extra_scripts/codemirror/mode/bfm/bfm.js index 1cd9e87c..baf65d18 100644 --- a/extra_scripts/codemirror/mode/bfm/bfm.js +++ b/extra_scripts/codemirror/mode/bfm/bfm.js @@ -54,6 +54,9 @@ stream.skipToEnd() return null + }, + blankLine(state) { + state.inTable = false } } diff --git a/gruntfile.js b/gruntfile.js index 651640fc..883e536c 100644 --- a/gruntfile.js +++ b/gruntfile.js @@ -289,9 +289,24 @@ module.exports = function (grunt) { const Color = require('color') const parseCSS = require('css').parse + function generateRule(selector, bgColor, fgColor) { + if (bgColor.isLight()) { + bgColor = bgColor.mix(fgColor, 0.05) + } else { + bgColor = bgColor.mix(fgColor, 0.1) + } + + if (selector && selector.length > 0) { + return `${selector} .cm-table-row-even { background-color: ${bgColor.rgb().string()}; }` + } + else { + return `.cm-table-row-even { background-color: ${bgColor.rgb().string()}; }` + } + } + const root = path.join(__dirname, 'node_modules/codemirror/theme/') - const colors = fs.readdirSync(root).map(file => { + const colors = fs.readdirSync(root).filter(file => file !== 'solarized.css').map(file => { const css = parseCSS(fs.readFileSync(path.join(root, file), 'utf8')) const rules = css.stylesheet.rules.filter(rule => rule.selectors && /\b\.CodeMirror$/.test(rule.selectors[0])) @@ -313,19 +328,38 @@ module.exports = function (grunt) { } }) - if (bgColor.isLight()) { + /* if (bgColor.isLight()) { bgColor = bgColor.mix(fgColor, 0.05) } else { bgColor = bgColor.mix(fgColor, 0.1) } - return `${rules[0].selectors[0]} .cm-table-row-even { background-color: ${bgColor.rgb().string()}; }` + return `${rules[0].selectors[0]} .cm-table-row-even { background-color: ${bgColor.rgb().string()}; }` */ + return generateRule(rules[0].selectors[0], bgColor, fgColor) } }).filter(value => !!value) - const defaultBgColor = Color('white').mix(Color('black'), 0.05) + //const defaultBgColor = Color('white').mix(Color('black'), 0.05) - fs.writeFileSync(path.join(__dirname, 'extra_scripts/codemirror/mode/bfm/bfm.css'), [`.cm-table-row-even { background-color: ${defaultBgColor.rgb().string()}; }`, ...colors].join('\n'), 'utf8') + // default + colors.unshift(generateRule(null, Color('white'), Color('black'))) + // solarized dark + colors.push(generateRule('.cm-s-solarized.cm-s-dark', Color('#002b36'), Color('#839496'))) + // solarized light + colors.push(generateRule('.cm-s-solarized.cm-s-light', Color('#fdf6e3'), Color('#657b83'))) + /* .cm-s-solarized.cm-s-dark { + color: #839496; + background-color: #002b36; + text-shadow: #002b36 0 1px; +} +.cm-s-solarized.cm-s-light { + background-color: #fdf6e3; + color: #657b83; + text-shadow: #eee8d5 0 1px; +} */ + + /* fs.writeFileSync(path.join(__dirname, 'extra_scripts/codemirror/mode/bfm/bfm.css'), [`.cm-table-row-even { background-color: ${defaultBgColor.rgb().string()}; }`, ...colors].join('\n'), 'utf8') */ + fs.writeFileSync(path.join(__dirname, 'extra_scripts/codemirror/mode/bfm/bfm.css'), colors.join('\n'), 'utf8') }) grunt.registerTask('default', ['build']) From 9d84fe77195a8ccb41b8043a66997af7eca6c01d Mon Sep 17 00:00:00 2001 From: Baptiste Augrain Date: Fri, 19 Oct 2018 14:09:13 +0200 Subject: [PATCH 79/90] fix lint errors --- gruntfile.js | 43 +++++++++++-------------------------------- 1 file changed, 11 insertions(+), 32 deletions(-) diff --git a/gruntfile.js b/gruntfile.js index 883e536c..ec3bbf79 100644 --- a/gruntfile.js +++ b/gruntfile.js @@ -289,19 +289,18 @@ module.exports = function (grunt) { const Color = require('color') const parseCSS = require('css').parse - function generateRule(selector, bgColor, fgColor) { + function generateRule (selector, bgColor, fgColor) { if (bgColor.isLight()) { - bgColor = bgColor.mix(fgColor, 0.05) - } else { - bgColor = bgColor.mix(fgColor, 0.1) - } + bgColor = bgColor.mix(fgColor, 0.05) + } else { + bgColor = bgColor.mix(fgColor, 0.1) + } - if (selector && selector.length > 0) { - return `${selector} .cm-table-row-even { background-color: ${bgColor.rgb().string()}; }` - } - else { - return `.cm-table-row-even { background-color: ${bgColor.rgb().string()}; }` - } + if (selector && selector.length > 0) { + return `${selector} .cm-table-row-even { background-color: ${bgColor.rgb().string()}; }` + } else { + return `.cm-table-row-even { background-color: ${bgColor.rgb().string()}; }` + } } const root = path.join(__dirname, 'node_modules/codemirror/theme/') @@ -319,7 +318,7 @@ module.exports = function (grunt) { bgColor = Color(declaration.value.split(' ')[0]) } else if (declaration.property === 'color') { const value = /^(.*?)(?:\s*!important)?$/.exec(declaration.value)[1] - let match = /^rgba\((.*?),\s*1\)$/.exec(value) + const match = /^rgba\((.*?),\s*1\)$/.exec(value) if (match) { fgColor = Color(`rgb(${match[1]})`) } else { @@ -328,37 +327,17 @@ module.exports = function (grunt) { } }) - /* if (bgColor.isLight()) { - bgColor = bgColor.mix(fgColor, 0.05) - } else { - bgColor = bgColor.mix(fgColor, 0.1) - } - - return `${rules[0].selectors[0]} .cm-table-row-even { background-color: ${bgColor.rgb().string()}; }` */ return generateRule(rules[0].selectors[0], bgColor, fgColor) } }).filter(value => !!value) - //const defaultBgColor = Color('white').mix(Color('black'), 0.05) - // default colors.unshift(generateRule(null, Color('white'), Color('black'))) // solarized dark colors.push(generateRule('.cm-s-solarized.cm-s-dark', Color('#002b36'), Color('#839496'))) // solarized light colors.push(generateRule('.cm-s-solarized.cm-s-light', Color('#fdf6e3'), Color('#657b83'))) - /* .cm-s-solarized.cm-s-dark { - color: #839496; - background-color: #002b36; - text-shadow: #002b36 0 1px; -} -.cm-s-solarized.cm-s-light { - background-color: #fdf6e3; - color: #657b83; - text-shadow: #eee8d5 0 1px; -} */ - /* fs.writeFileSync(path.join(__dirname, 'extra_scripts/codemirror/mode/bfm/bfm.css'), [`.cm-table-row-even { background-color: ${defaultBgColor.rgb().string()}; }`, ...colors].join('\n'), 'utf8') */ fs.writeFileSync(path.join(__dirname, 'extra_scripts/codemirror/mode/bfm/bfm.css'), colors.join('\n'), 'utf8') }) From 0e38f61c85031949aadcc45f4e83fbb50531806f Mon Sep 17 00:00:00 2001 From: David Nagle Date: Fri, 19 Oct 2018 10:59:37 -0700 Subject: [PATCH 80/90] Title will now be extracted from front matter if title: is present. --- browser/lib/findNoteTitle.js | 29 ++++++++++++++++++----------- tests/lib/find-title-test.js | 6 ++++-- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/browser/lib/findNoteTitle.js b/browser/lib/findNoteTitle.js index b954f172..f28e44de 100644 --- a/browser/lib/findNoteTitle.js +++ b/browser/lib/findNoteTitle.js @@ -6,6 +6,11 @@ export function findNoteTitle (value) { if (splitted[0] === '---') { let line = 0 while (++line < splitted.length) { + if (splitted[line].startsWith('title:')) { + title = splitted[line].substring(6).trim() + + break + } if (splitted[line] === '---') { splitted.splice(0, line + 1) @@ -14,17 +19,19 @@ export function findNoteTitle (value) { } } - splitted.some((line, index) => { - const trimmedLine = line.trim() - const trimmedNextLine = splitted[index + 1] === undefined ? '' : splitted[index + 1].trim() - if (trimmedLine.match('```')) { - isInsideCodeBlock = !isInsideCodeBlock - } - if (isInsideCodeBlock === false && (trimmedLine.match(/^# +/) || trimmedNextLine.match(/^=+$/))) { - title = trimmedLine - return true - } - }) + if (title === null) { + splitted.some((line, index) => { + const trimmedLine = line.trim() + const trimmedNextLine = splitted[index + 1] === undefined ? '' : splitted[index + 1].trim() + if (trimmedLine.match('```')) { + isInsideCodeBlock = !isInsideCodeBlock + } + if (isInsideCodeBlock === false && (trimmedLine.match(/^# +/) || trimmedNextLine.match(/^=+$/))) { + title = trimmedLine + return true + } + }) + } if (title === null) { title = '' diff --git a/tests/lib/find-title-test.js b/tests/lib/find-title-test.js index f587804c..1e9daa0f 100644 --- a/tests/lib/find-title-test.js +++ b/tests/lib/find-title-test.js @@ -15,7 +15,10 @@ test('findNoteTitle#find should return a correct title (string)', t => { ['====', '===='], ['```\n# hoge\n```', '```'], ['hoge', 'hoge'], - ['---\nlayout: test\n---\n # hoge', '# hoge'] + ['---\nlayout: test\n---\n # hoge', '# hoge'], + ['---\nlayout: test\ntitle: hoge hoge hoge \n---\n# fuga', 'hoge hoge hoge'], + ['---\ntitle:hoge\n---\n# fuga', 'hoge'], + ['title: fuga\n# hoge', '# hoge'] ] testCases.forEach(testCase => { @@ -23,4 +26,3 @@ test('findNoteTitle#find should return a correct title (string)', t => { t.is(findNoteTitle(input), expected, `Test for find() input: ${input} expected: ${expected}`) }) }) - From 73d1bdf84bf06e0f161a9dc8745fd557b0fa691f Mon Sep 17 00:00:00 2001 From: David Nagle Date: Fri, 19 Oct 2018 14:29:48 -0700 Subject: [PATCH 81/90] Prevent empty printed page with scroll-past-end --- browser/components/MarkdownPreview.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/browser/components/MarkdownPreview.js b/browser/components/MarkdownPreview.js index e69f312e..749bd43f 100755 --- a/browser/components/MarkdownPreview.js +++ b/browser/components/MarkdownPreview.js @@ -88,6 +88,11 @@ body { font-size: ${fontSize}px; ${scrollPastEnd && 'padding-bottom: 90vh;'} } +@media print { + body { + padding-bottom: initial; + } +} code { font-family: '${codeBlockFontFamily.join("','")}'; background-color: rgba(0,0,0,0.04); From 3272033c632a4e7386d5901606b915aee6f81fd5 Mon Sep 17 00:00:00 2001 From: David Nagle Date: Fri, 19 Oct 2018 13:41:32 -0700 Subject: [PATCH 82/90] Added preferences to support toggling front matter title extraction on/off and to customize what field is used for the title. --- browser/lib/findNoteTitle.js | 6 +-- browser/main/Detail/MarkdownNoteDetail.js | 2 +- browser/main/Detail/SnippetNoteDetail.js | 2 +- browser/main/lib/ConfigManager.js | 4 +- browser/main/modals/PreferencesModal/UiTab.js | 29 ++++++++++++- tests/lib/find-title-test.js | 42 ++++++++++++++++++- 6 files changed, 76 insertions(+), 9 deletions(-) diff --git a/browser/lib/findNoteTitle.js b/browser/lib/findNoteTitle.js index f28e44de..912c3bdd 100644 --- a/browser/lib/findNoteTitle.js +++ b/browser/lib/findNoteTitle.js @@ -1,4 +1,4 @@ -export function findNoteTitle (value) { +export function findNoteTitle (value, enableFrontMatterTitle, frontMatterTitleField = 'title') { const splitted = value.split('\n') let title = null let isInsideCodeBlock = false @@ -6,8 +6,8 @@ export function findNoteTitle (value) { if (splitted[0] === '---') { let line = 0 while (++line < splitted.length) { - if (splitted[line].startsWith('title:')) { - title = splitted[line].substring(6).trim() + if (enableFrontMatterTitle && splitted[line].startsWith(frontMatterTitleField + ':')) { + title = splitted[line].substring(frontMatterTitleField.length + 1).trim() break } diff --git a/browser/main/Detail/MarkdownNoteDetail.js b/browser/main/Detail/MarkdownNoteDetail.js index e4493a80..fe98c8bf 100755 --- a/browser/main/Detail/MarkdownNoteDetail.js +++ b/browser/main/Detail/MarkdownNoteDetail.js @@ -91,7 +91,7 @@ class MarkdownNoteDetail extends React.Component { handleUpdateContent () { const { note } = this.state note.content = this.refs.content.value - note.title = markdown.strip(striptags(findNoteTitle(note.content))) + note.title = markdown.strip(striptags(findNoteTitle(note.content, this.props.config.editor.enableFrontMatterTitle, this.props.config.editor.frontMatterTitleField))) this.updateNote(note) } diff --git a/browser/main/Detail/SnippetNoteDetail.js b/browser/main/Detail/SnippetNoteDetail.js index 9356a02c..65d5dfd3 100644 --- a/browser/main/Detail/SnippetNoteDetail.js +++ b/browser/main/Detail/SnippetNoteDetail.js @@ -112,7 +112,7 @@ class SnippetNoteDetail extends React.Component { if (this.refs.tags) note.tags = this.refs.tags.value note.description = this.refs.description.value note.updatedAt = new Date() - note.title = findNoteTitle(note.description) + note.title = findNoteTitle(note.description, false) this.setState({ note diff --git a/browser/main/lib/ConfigManager.js b/browser/main/lib/ConfigManager.js index 1727deb8..33cab7aa 100644 --- a/browser/main/lib/ConfigManager.js +++ b/browser/main/lib/ConfigManager.js @@ -47,7 +47,9 @@ export const DEFAULT_CONFIG = { scrollPastEnd: false, type: 'SPLIT', fetchUrlTitle: true, - enableTableEditor: false + enableTableEditor: false, + enableFrontMatterTitle: true, + frontMatterTitleField: 'title' }, preview: { fontSize: '14', diff --git a/browser/main/modals/PreferencesModal/UiTab.js b/browser/main/modals/PreferencesModal/UiTab.js index 97f3877c..638fab90 100644 --- a/browser/main/modals/PreferencesModal/UiTab.js +++ b/browser/main/modals/PreferencesModal/UiTab.js @@ -89,7 +89,9 @@ class UiTab extends React.Component { snippetDefaultLanguage: this.refs.editorSnippetDefaultLanguage.value, scrollPastEnd: this.refs.scrollPastEnd.checked, fetchUrlTitle: this.refs.editorFetchUrlTitle.checked, - enableTableEditor: this.refs.enableTableEditor.checked + enableTableEditor: this.refs.enableTableEditor.checked, + enableFrontMatterTitle: this.refs.enableFrontMatterTitle.checked, + frontMatterTitleField: this.refs.frontMatterTitleField.value }, preview: { fontSize: this.refs.previewFontSize.value, @@ -428,6 +430,31 @@ class UiTab extends React.Component {
+
+
+ {i18n.__('Front matter title field')} +
+
+ this.handleUIChange(e)} + type='text' + /> +
+
+ +
+ +
+
+
+ +