diff --git a/public/build/bundle.css b/public/build/bundle.css index d27c727b..fcfce7e7 100644 --- a/public/build/bundle.css +++ b/public/build/bundle.css @@ -1,1244 +1,3 @@ -/*! normalize.css v5.0.0 | MIT License | github.com/necolas/normalize.css */ - -/** - * 1. Change the default font family in all browsers (opinionated). - * 2. Correct the line height in all browsers. - * 3. Prevent adjustments of font size after orientation changes in - * IE on Windows Phone and in iOS. - */ - -/* Document - ========================================================================== */ - -html { - font-family: sans-serif; /* 1 */ - line-height: 1.15; /* 2 */ - -ms-text-size-adjust: 100%; /* 3 */ - -webkit-text-size-adjust: 100%; /* 3 */ -} - -/* Sections - ========================================================================== */ - -/** - * Remove the margin in all browsers (opinionated). - */ - -body { - margin: 0; -} - -/** - * Add the correct display in IE 9-. - */ - -article, -aside, -footer, -header, -nav, -section { - display: block; -} - -/** - * Correct the font size and margin on `h1` elements within `section` and - * `article` contexts in Chrome, Firefox, and Safari. - */ - -h1 { - font-size: 2em; - margin: 0.67em 0; -} - -/* Grouping content - ========================================================================== */ - -/** - * Add the correct display in IE 9-. - * 1. Add the correct display in IE. - */ - -figcaption, -figure, -main { /* 1 */ - display: block; -} - -/** - * Add the correct margin in IE 8. - */ - -figure { - margin: 1em 40px; -} - -/** - * 1. Add the correct box sizing in Firefox. - * 2. Show the overflow in Edge and IE. - */ - -hr { - box-sizing: content-box; /* 1 */ - height: 0; /* 1 */ - overflow: visible; /* 2 */ -} - -/** - * 1. Correct the inheritance and scaling of font size in all browsers. - * 2. Correct the odd `em` font sizing in all browsers. - */ - -pre { - font-family: monospace, monospace; /* 1 */ - font-size: 1em; /* 2 */ -} - -/* Text-level semantics - ========================================================================== */ - -/** - * 1. Remove the gray background on active links in IE 10. - * 2. Remove gaps in links underline in iOS 8+ and Safari 8+. - */ - -a { - background-color: transparent; /* 1 */ - -webkit-text-decoration-skip: objects; /* 2 */ -} - -/** - * Remove the outline on focused links when they are also active or hovered - * in all browsers (opinionated). - */ - -a:active, -a:hover { - outline-width: 0; -} - -/** - * 1. Remove the bottom border in Firefox 39-. - * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. - */ - -abbr[title] { - border-bottom: none; /* 1 */ - text-decoration: underline; /* 2 */ - text-decoration: underline dotted; /* 2 */ -} - -/** - * Prevent the duplicate application of `bolder` by the next rule in Safari 6. - */ - -b, -strong { - font-weight: inherit; -} - -/** - * Add the correct font weight in Chrome, Edge, and Safari. - */ - -b, -strong { - font-weight: bolder; -} - -/** - * 1. Correct the inheritance and scaling of font size in all browsers. - * 2. Correct the odd `em` font sizing in all browsers. - */ - -code, -kbd, -samp { - font-family: monospace, monospace; /* 1 */ - font-size: 1em; /* 2 */ -} - -/** - * Add the correct font style in Android 4.3-. - */ - -dfn { - font-style: italic; -} - -/** - * Add the correct background and color in IE 9-. - */ - -mark { - background-color: #ff0; - color: #000; -} - -/** - * Add the correct font size in all browsers. - */ - -small { - font-size: 80%; -} - -/** - * Prevent `sub` and `sup` elements from affecting the line height in - * all browsers. - */ - -sub, -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} - -sub { - bottom: -0.25em; -} - -sup { - top: -0.5em; -} - -/* Embedded content - ========================================================================== */ - -/** - * Add the correct display in IE 9-. - */ - -audio, -video { - display: inline-block; -} - -/** - * Add the correct display in iOS 4-7. - */ - -audio:not([controls]) { - display: none; - height: 0; -} - -/** - * Remove the border on images inside links in IE 10-. - */ - -img { - border-style: none; -} - -/** - * Hide the overflow in IE. - */ - -svg:not(:root) { - overflow: hidden; -} - -/* Forms - ========================================================================== */ - -/** - * 1. Change the font styles in all browsers (opinionated). - * 2. Remove the margin in Firefox and Safari. - */ - -button, -input, -optgroup, -select, -textarea { - font-family: sans-serif; /* 1 */ - font-size: 100%; /* 1 */ - line-height: 1.15; /* 1 */ - margin: 0; /* 2 */ -} - -/** - * Show the overflow in IE. - * 1. Show the overflow in Edge. - */ - -button, -input { /* 1 */ - overflow: visible; -} - -/** - * Remove the inheritance of text transform in Edge, Firefox, and IE. - * 1. Remove the inheritance of text transform in Firefox. - */ - -button, -select { /* 1 */ - text-transform: none; -} - -/** - * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video` - * controls in Android 4. - * 2. Correct the inability to style clickable types in iOS and Safari. - */ - -button, -html [type="button"], -[type="reset"], -[type="submit"] { - -webkit-appearance: button; /* 2 */ -} - -/** - * Remove the inner border and padding in Firefox. - */ - -button::-moz-focus-inner, -[type="button"]::-moz-focus-inner, -[type="reset"]::-moz-focus-inner, -[type="submit"]::-moz-focus-inner { - border-style: none; - padding: 0; -} - -/** - * Restore the focus styles unset by the previous rule. - */ - -button:-moz-focusring, -[type="button"]:-moz-focusring, -[type="reset"]:-moz-focusring, -[type="submit"]:-moz-focusring { - outline: 1px dotted ButtonText; -} - -/** - * Change the border, margin, and padding in all browsers (opinionated). - */ - -fieldset { - border: 1px solid #c0c0c0; - margin: 0 2px; - padding: 0.35em 0.625em 0.75em; -} - -/** - * 1. Correct the text wrapping in Edge and IE. - * 2. Correct the color inheritance from `fieldset` elements in IE. - * 3. Remove the padding so developers are not caught out when they zero out - * `fieldset` elements in all browsers. - */ - -legend { - box-sizing: border-box; /* 1 */ - color: inherit; /* 2 */ - display: table; /* 1 */ - max-width: 100%; /* 1 */ - padding: 0; /* 3 */ - white-space: normal; /* 1 */ -} - -/** - * 1. Add the correct display in IE 9-. - * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera. - */ - -progress { - display: inline-block; /* 1 */ - vertical-align: baseline; /* 2 */ -} - -/** - * Remove the default vertical scrollbar in IE. - */ - -textarea { - overflow: auto; -} - -/** - * 1. Add the correct box sizing in IE 10-. - * 2. Remove the padding in IE 10-. - */ - -[type="checkbox"], -[type="radio"] { - box-sizing: border-box; /* 1 */ - padding: 0; /* 2 */ -} - -/** - * Correct the cursor style of increment and decrement buttons in Chrome. - */ - -[type="number"]::-webkit-inner-spin-button, -[type="number"]::-webkit-outer-spin-button { - height: auto; -} - -/** - * 1. Correct the odd appearance in Chrome and Safari. - * 2. Correct the outline style in Safari. - */ - -[type="search"] { - -webkit-appearance: textfield; /* 1 */ - outline-offset: -2px; /* 2 */ -} - -/** - * Remove the inner padding and cancel buttons in Chrome and Safari on macOS. - */ - -[type="search"]::-webkit-search-cancel-button, -[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; -} - -/** - * 1. Correct the inability to style clickable types in iOS and Safari. - * 2. Change font properties to `inherit` in Safari. - */ - -::-webkit-file-upload-button { - -webkit-appearance: button; /* 1 */ - font: inherit; /* 2 */ -} - -/* Interactive - ========================================================================== */ - -/* - * Add the correct display in IE 9-. - * 1. Add the correct display in Edge, IE, and Firefox. - */ - -details, /* 1 */ -menu { - display: block; -} - -/* - * Add the correct display in all browsers. - */ - -summary { - display: list-item; -} - -/* Scripting - ========================================================================== */ - -/** - * Add the correct display in IE 9-. - */ - -canvas { - display: inline-block; -} - -/** - * Add the correct display in IE. - */ - -template { - display: none; -} - -/* Hidden - ========================================================================== */ - -/** - * Add the correct display in IE 10-. - */ - -[hidden] { - display: none; -} - -:root { - /** Aside */ - - /** - * Clearfix - * - * usage: @apply --clearfix; - */ -} - -.aside { - position: fixed; - left: 0; - top: 0; - bottom: 0; - width: 200px; - padding: 40px 15px 30px; - background: #292b37; - overflow: hidden; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - -webkit-app-region: drag; - color: #bac3db; - font-size: 13.7px; - letter-spacing: 0.3px; - - -} - -.aside__header { - position: relative; - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-orient: horizontal; - -webkit-box-direction: normal; - -ms-flex-direction: row; - flex-direction: row; - -webkit-box-pack: justify; - -ms-flex-pack: justify; - justify-content: space-between; - margin-bottom: 15px; - - } - -.aside__header-left { - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-orient: vertical; - -webkit-box-direction: normal; - -ms-flex-direction: column; - flex-direction: column; - font-size: 18px; - font-weight: 600; - color: #fff; - } - -.aside__header-avatar { - width: 37px; - height: 37px; - color: #3D3F4D; - cursor: pointer; - transition: all 50ms ease; - transition-delay: 100ms; - will-change: color; - - } - -.aside__header-avatar-inner { - color: #A2A8BD; - transition: color 50ms ease; - transition-delay: 100ms; - will-change: color; - } - -.aside__header-avatar:hover { - color: #3C93F7; -} - -.aside__header-avatar:hover .aside__header-avatar-inner { - color: #FFF; -} - -/** - * Authorization panel - * ========================= - */ - -.aside__authorization { - position: absolute; - top: calc(100% + 12px); - right: 0; - left: 0; - padding: 20px 25px; - font-size: 13.1px; - color: #000; - text-align: center; - border-radius: 3px; - background-color: #F5F9FE; - will-change: opacity, transform; - opacity: 0; - visibility: hidden; - -webkit-transform: translateY(7px); - transform: translateY(7px); - transition: all 70ms ease; - transition-delay: 150ms; - cursor: default; - z-index: 2 - } - -.aside__authorization::before { - content:''; - position: absolute; - top: -7px; - left: 173.5px; - width: 0; - height: 0; - border-style: solid; - border-width: 0 8px 8px 8px; - border-color: transparent transparent #F5F9FE transparent; -} - -.aside__authorization-title { - line-height: 1.4em; - letter-spacing: 0.0284em; -} - -.aside__header-avatar--filled { - cursor: default; - } - -.aside__header-avatar:not(.aside__header-avatar--filled):hover .aside__authorization { - -webkit-transform: none; - transform: none; - opacity: 1; - visibility: visible; - } - -.aside__header-avatar .aside__user-photo { - display: none; - width: 37px; - height: 37px; - border-radius: 50%; - background-size: cover; - } - -.aside__header-avatar--filled .aside__user-photo { - display: inline-block; - } - -.aside__header-avatar--filled svg { - display: none; - } - -/** - * Section title such as Folders or Notes - * ============================ - */ - -.aside__section-title { - margin-bottom: 10px; - color: rgba(186, 195, 219, 0.5); - font-size: 11.7px; - letter-spacing: 0.72px; - text-transform: uppercase - } - -.aside__section-title:not(:first-of-type) { - margin-top: 30px; -} - -.aside__section-settings { - margin: 24px 0; - } - -.aside .add-note-button { - display: block; - padding: 10px 13px; - border: 1.3px dashed rgba(130, 156, 176, 0.42); - border-radius: 3px; - color: #63758c; - line-height: 1em; - margin-bottom: 15px; - font-size: 15px; - cursor: pointer; - } - -.aside .add-note-button svg { - margin-top: -1px; - float: right; - } - -.aside .add-note-button:hover { - border-color: rgba(77,120,190,0.72); - color: #5ba2ff; -} - -/** - * Add folder button and input - * ============================ - */ - -.aside__input, - .aside__add-button { - padding: 8px 0; - margin: 10px 0 0; - color: rgba(186, 195, 219, 0.5); - } - -/** - * Aside input field - * Such as New Folder or Invite collaborator - */ - -.aside__input { - border: 0; - border-bottom: 2px #4c525a solid; - } - -.aside__input input { - border: none; - background: transparent; - outline: none; - color: #fff; - padding-right: 5px; - width: 90%; - letter-spacing: inherit - } - -.aside__input input::-webkit-input-placeholder { - color: rgba(186, 195, 219, 0.5); -} - -.aside__input input:-ms-input-placeholder { - color: rgba(186, 195, 219, 0.5); -} - -.aside__input input::placeholder { - color: rgba(186, 195, 219, 0.5); -} - -.aside__input input:focus + svg { - color: #fff; -} - -.aside__input svg { - float: right; - display: inline-block; - height: 0.8em; - margin-top: 0.3em; - } - -/** - * Add something button - */ - -.aside__add-button { - cursor: pointer; - } - -.aside__add-button svg { - width: 0.9em; - height: 0.9em; - margin-right: 0.5em; - margin-top: -3px; - vertical-align: middle; - } - -.aside__add-button:hover { - color: #fff; -} - -/** - * Swiper with 2 sections - */ - -.aside-swiper { - display: -webkit-box; - display: -ms-flexbox; - display: flex; - width: calc(200% + 15px); - height: 100%; - transition: -webkit-transform 150ms ease-in; - transition: transform 150ms ease-in; - transition: transform 150ms ease-in, -webkit-transform 150ms ease-in; - will-change: transform; -} - -.aside-swiper__left, - .aside-swiper__right { - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-orient: vertical; - -webkit-box-direction: normal; - -ms-flex-direction: column; - flex-direction: column; - width: 100%; - max-width: 200px; - position: relative; - } - -.aside-swiper__left { - transition: opacity 200ms ease; - will-change: opacity; - } - -.aside-swiper__right { - margin-left: 15px; - } - -.aside-swiper--toggled { - -webkit-transform: translateX(-215px); - transform: translateX(-215px); - } - -.aside-swiper--toggled .aside-swiper__left { - opacity: 0.2; - } - -.authorization-button { - display: inline-block; - margin-top: 15px; - cursor: pointer; - color: #496A84; -} - -.authorization-button svg { - margin-right: 8px; - } - -.authorization-button:hover { - color: #1A2630; - cursor: pointer; -} - -/** - * Scrollable zone - */ - -.aside__scrollable { - position: relative; - -webkit-box-flex: 2; - -ms-flex: 2 100%; - flex: 2 100%; - overflow-y: hidden; - overflow-x: hidden -} - -.aside__scrollable::before, - .aside__scrollable::after { - content: ''; - height: 15px; - left: 0; - right: 0; - position: absolute; - z-index: 2; -} - -.aside__scrollable::before { - top: 0; - background: linear-gradient(to bottom, rgba(41,43,55,1) 0%,rgba(41,43,55,0) 90%); - opacity: 0; -} - -.aside__scrollable--scrolled::before { - opacity: 1; -} - -.aside__scrollable::after { - bottom: 0; - background: linear-gradient(to bottom, rgba(41,43,55,0) 0%,rgba(41,43,55,1) 90%); -} - -.aside__scrollable-content { - height: 100%; - overflow-y: auto; - margin-right: -12px; - padding-right: 12px; -} - -.aside__scrollable-content::after { - display: block; - content: ''; - height: 15px; -} - -.content { - -webkit-box-flex: 1; - -ms-flex-positive: 1; - flex-grow: 1; -} - -.note-title { - display: block; - width: 100%; - min-height: 50px; - box-sizing: border-box; - overflow-y: hidden; - max-width: 600px; - margin: 0 auto 10px; - border: 0; - font-size: 48px; - font-weight: 800; - outline: none; - resize: none; - font-family: 'PT Serif'; - padding: 0 - -} - -.note-title::-webkit-input-placeholder { - color: #818BA1; - opacity: 0.7; - transition: opacity 200ms ease; -} - -.note-title:-ms-input-placeholder { - color: #818BA1; - opacity: 0.7; - transition: opacity 200ms ease; -} - -.note-title::placeholder { - color: #818BA1; - opacity: 0.7; - transition: opacity 200ms ease; -} - -.note-title:focus::-webkit-input-placeholder { - opacity: 0.1; -} - -.note-title:focus:-ms-input-placeholder { - opacity: 0.1; -} - -.note-title:focus::placeholder { - opacity: 0.1; -} - -.editor { - padding: 100px; - margin-left: 230px; - margin-top: 50px; - font-size: 17px; - color: #1A1A1A; - line-height: 1.5em; -} - -.ce-redactor { - min-height: 150px !important; -} - -@media (max-width: 1000px){ - .ce-block__content, - .ce-toolbar__content { - padding: 0; - } -} - -.header { - position: fixed; - left: 0; - right: 0; - top: 0; - height: 25px; - z-index: 3; - background: #fff; - margin-left: 230px; - padding: 10px 30px; - border-bottom: 1px solid #f3f3f4; - font-size: 14px; - line-height: 25px; - color: #828698; -} - -.note-date, -.share-button { - margin-right: 15px; -} - -/*cursor: pointer;*/ - -.note-date svg, .share-button svg { - margin-right: 0.8em; - margin-top: -0.3em; - color: #85899b; - } - -.delete-note-button { - float: right; - cursor: pointer; - z-index: 10 - -} - -.delete-note-button:hover { - color: rgb(92, 96, 112); -} - -.save-indicator { - opacity: 0; - color: #587bbf; - transition: opacity 0.3s ease -} - -.save-indicator.saved { - opacity: 1; -} - -.notes-list { - position: relative; - /*bottom: 15px;*/ - /*left: 15px;*/ - /*right: 15px;*/ - /*top: 120px;*/ - - /*&::before,*/ - /*&::after {*/ - /*content: '';*/ - /*height: 15px;*/ - /*left: 0;*/ - /*right: 0;*/ - /*position: absolute;*/ - /*z-index: 2;*/ - /*!*background: red;*!*/ - /*}*/ - - /*&::before {*/ -} - -/*}*/ - -.notes-list u { - margin: 1.15em 0; - } - -/*background: linear-gradient(to bottom, rgba(41,43,55,0) 0%,rgba(41,43,55,1) 100%);*/ - -.notes-list__scroll { - position: absolute; - overflow-y: auto; - top: 0; - bottom: 0; - right: 0; - left: 0; - padding-right: 15px; - } - -/*bottom: 0;*/ - -.notes-list__content { - list-style: none; - padding: 0; - margin: 0; - } - -/*&::after {*/ - -.notes-list li { - text-decoration: none; - line-height: 1.45em; - cursor: pointer; - word-wrap: break-word - - } - -/*}*/ - -.notes-list li:not(:last-of-type) { - margin-bottom: 0.75em; -} - -/*background: linear-gradient(to bottom, rgba(41,43,55,1) 0%,rgba(41,43,55,0) 100%);*/ - -.notes-list li:hover { - color: #fff; -} - -/*top: 0;*/ - -.notes-list--loading::before, - .notes-list--loading::after { - content: ''; - background: rgba(186, 195, 219, 0.2); - height: 6px; - display: block; - border-radius: 5px; - margin: 7px 0 15px; - width: 65%; -} - -.folder-header::after { - content: " "; - display: table; - clear: both; -} - -.folder-header { - position: relative; - margin-bottom: 17px; - font-size: 14.8px; - cursor: pointer; - color: #bac3db; - padding-left: 25px; -} - -.folder-header__close { - position: absolute; - left: 0; - top: 43%; - -webkit-transform: translateY(-50%); - transform: translateY(-50%); -} - -.folder-header__close svg { - height: 15px; - fill: #dee6fc; - } - -.folder-header__name { - color: #dee6fc; -} - -.folder-header__settings { - color: rgba(186, 195, 219, 0.5); - margin-top: 3px; - cursor: pointer; -} - -.folder-header__settings:hover { - color: #bac3db; -} - -.folder-settings { - background: #292b37; - position: absolute; - top: calc(100% + 17px); /* 17 is the header margin */ - left: 0; - right: 0; - z-index: 2; - display: none; - padding: 10px 0; -} - -.folder-settings__close { - position: absolute; - right: 0; - top: 3px; - cursor: pointer; - } - -.folder-settings__close svg { - opacity: 0.2; - } - -.folder-settings__close:hover svg { - opacity: 1; -} - -.folder-settings__delete { - margin-top: 15px; - font-size: 14.6px; - } - -.folder-settings__delete svg { - margin-right: 10px; - vertical-align: text-bottom; - } - -.folder-settings__delete:hover { - color: #fff;/*svg { - fill: #fff; - } */ -} - -/** - * Modifier added to the - */ - -/** - * Open panel - */ - -.folder-settings-opened .folder-settings { - display: block; - } - -/** - * Hide menu content - */ - -.folder-settings-opened .aside-swiper__right .aside__scrollable { - visibility: hidden; - } - -.status-bar { - margin-top: 2px; - font-size: 13.2px; - letter-spacing: 0.038em; - font-weight: normal; - color: rgba(222, 230, 252, 0.5); - transition: color 250ms cubic-bezier(0.32,-0.01, 0, 0.99); -} - -.status-bar--blinked{ - color: #dee6fc - } - -.status-bar--loading::after { - content: '...'; - display: inline-block; - -webkit-animation: loading 1000ms infinite; - animation: loading 1000ms infinite; - overflow: hidden; - vertical-align: text-bottom; -} - -@-webkit-keyframes loading { - 0% { - width: 0; - } - 100% { - width: 12px; - } -} - -@keyframes loading { - 0% { - width: 0; - } - 100% { - width: 12px; - } -} - -body { - height: 100vh; - margin: 0; - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - background: #fff; -} - -.drag-bar { - position: absolute; - width: 100%; - height: 35px; - top: 0; - left: 0; - z-index: 1; - -webkit-app-region: drag; -} - -/** -* SVG icons styles -*/ - -svg { - fill: currentColor; - vertical-align: middle; - max-height: 100%; -} - -.clearfix::after { - content: ''; - display: table; - clear: 'both'; -} - -.hide { - display: none !important; -} - -/*# sourceMappingURL=bundle.css.map*/ \ No newline at end of file +/*! normalize.css v5.0.0 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit;font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{display:inline-block;vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details,menu{display:block}summary{display:list-item}canvas{display:inline-block}[hidden],template{display:none}.aside{position:fixed;left:0;top:0;bottom:0;width:200px;padding:40px 15px 30px;background:#292b37;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-app-region:drag;color:#bac3db;font-size:13.7px;letter-spacing:.3px}.aside__header{position:relative;-webkit-box-orient:horizontal;-ms-flex-direction:row;flex-direction:row;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;margin-bottom:15px}.aside__header,.aside__header-left{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-direction:normal}.aside__header-left{-webkit-box-orient:vertical;-ms-flex-direction:column;flex-direction:column;font-size:18px;font-weight:600;color:#fff}.aside__header-avatar{width:37px;height:37px;color:#3d3f4d;cursor:pointer;transition:all 50ms ease;transition-delay:.1s;will-change:color}.aside__header-avatar-inner{color:#a2a8bd;transition:color 50ms ease;transition-delay:.1s;will-change:color}.aside__header-avatar:hover{color:#3c93f7}.aside__header-avatar:hover .aside__header-avatar-inner{color:#fff}.aside__authorization{position:absolute;top:calc(100% + 12px);right:0;left:0;padding:20px 25px;font-size:13.1px;color:#000;text-align:center;border-radius:3px;background-color:#f5f9fe;will-change:opacity,transform;opacity:0;visibility:hidden;-webkit-transform:translateY(7px);transform:translateY(7px);transition:all 70ms ease;transition-delay:.15s;cursor:default;z-index:2}.aside__authorization:before{content:"";position:absolute;top:-7px;left:173.5px;width:0;height:0;border-style:solid;border-width:0 8px 8px;border-color:transparent transparent #f5f9fe}.aside__authorization-title{line-height:1.4em;letter-spacing:.0284em}.aside__header-avatar--filled{cursor:default}.aside__header-avatar:not(.aside__header-avatar--filled):hover .aside__authorization{-webkit-transform:none;transform:none;opacity:1;visibility:visible}.aside__header-avatar .aside__user-photo{display:none;width:37px;height:37px;border-radius:50%;background-size:cover}.aside__header-avatar--filled .aside__user-photo{display:inline-block}.aside__header-avatar--filled svg{display:none}.aside__section-title{margin-bottom:10px;color:rgba(186,195,219,.5);font-size:11.7px;letter-spacing:.72px;text-transform:uppercase}.aside__section-title:not(:first-of-type){margin-top:30px}.aside__section-settings{margin:24px 0}.aside .add-note-button{display:block;padding:10px 13px;border:1.3px dashed rgba(130,156,176,.42);border-radius:3px;color:#63758c;line-height:1em;margin-bottom:15px;font-size:15px;cursor:pointer}.aside .add-note-button svg{margin-top:-1px;float:right}.aside .add-note-button:hover{border-color:rgba(77,120,190,.72);color:#5ba2ff}.aside__add-button,.aside__input{padding:8px 0;margin:10px 0 0;color:rgba(186,195,219,.5)}.aside__input{border:0;border-bottom:2px solid #4c525a}.aside__input input{border:none;background:transparent;outline:none;color:#fff;padding-right:5px;width:90%;letter-spacing:inherit}.aside__input input::-webkit-input-placeholder{color:rgba(186,195,219,.5)}.aside__input input:-ms-input-placeholder{color:rgba(186,195,219,.5)}.aside__input input::placeholder{color:rgba(186,195,219,.5)}.aside__input input:focus+svg{color:#fff}.aside__input svg{float:right;display:inline-block;height:.8em;margin-top:.3em}.aside__add-button{cursor:pointer}.aside__add-button svg{width:.9em;height:.9em;margin-right:.5em;margin-top:-3px;vertical-align:middle}.aside__add-button:hover{color:#fff}.aside-swiper{display:-webkit-box;display:-ms-flexbox;display:flex;width:calc(200% + 15px);height:100%;transition:-webkit-transform .15s ease-in;transition:transform .15s ease-in;transition:transform .15s ease-in,-webkit-transform .15s ease-in;will-change:transform}.aside-swiper__left,.aside-swiper__right{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;width:100%;max-width:200px;position:relative}.aside-swiper__left{transition:opacity .2s ease;will-change:opacity}.aside-swiper__right{margin-left:15px}.aside-swiper--toggled{-webkit-transform:translateX(-215px);transform:translateX(-215px)}.aside-swiper--toggled .aside-swiper__left{opacity:.2}.authorization-button{display:inline-block;margin-top:15px;cursor:pointer;color:#496a84}.authorization-button svg{margin-right:8px}.authorization-button:hover{color:#1a2630;cursor:pointer}.aside__scrollable{position:relative;-webkit-box-flex:2;-ms-flex:2 100%;flex:2 100%;overflow-y:hidden;overflow-x:hidden}.aside__scrollable:after,.aside__scrollable:before{content:"";height:15px;left:0;right:0;position:absolute;z-index:2}.aside__scrollable:before{top:0;background:linear-gradient(180deg,#292b37 0,rgba(41,43,55,0) 90%);opacity:0}.aside__scrollable--scrolled:before{opacity:1}.aside__scrollable:after{bottom:0;background:linear-gradient(180deg,rgba(41,43,55,0) 0,#292b37 90%)}.aside__scrollable-content{height:100%;overflow-y:auto;margin-right:-12px;padding-right:12px}.aside__scrollable-content:after{display:block;content:"";height:15px}.content{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.note-title{display:block;width:100%;min-height:50px;box-sizing:border-box;overflow-y:hidden;max-width:600px;margin:0 auto 10px;border:0;font-size:48px;font-weight:800;outline:none;resize:none;font-family:PT Serif;padding:0}.note-title::-webkit-input-placeholder{color:#818ba1;opacity:.7;transition:opacity .2s ease}.note-title:-ms-input-placeholder{color:#818ba1;opacity:.7;transition:opacity .2s ease}.note-title::placeholder{color:#818ba1;opacity:.7;transition:opacity .2s ease}.note-title:focus::-webkit-input-placeholder{opacity:.1}.note-title:focus:-ms-input-placeholder{opacity:.1}.note-title:focus::placeholder{opacity:.1}.editor{padding:100px;margin-left:230px;margin-top:50px;font-size:17px;color:#1a1a1a;line-height:1.5em}.ce-redactor{min-height:150px!important}@media (max-width:1000px){.ce-block__content,.ce-toolbar__content{padding:0}}.header{position:fixed;left:0;right:0;top:0;height:25px;z-index:3;background:#fff;margin-left:230px;padding:10px 30px;border-bottom:1px solid #f3f3f4;font-size:14px;line-height:25px;color:#828698}.note-date,.share-button{margin-right:15px}.note-date svg,.share-button svg{margin-right:.8em;margin-top:-.3em;color:#85899b}.delete-note-button{float:right;cursor:pointer;z-index:10}.delete-note-button:hover{color:#5c6070}.save-indicator{opacity:0;color:#587bbf;transition:opacity .3s ease}.save-indicator.saved{opacity:1}.notes-list{position:relative + /*!*background: red;*!*/}.notes-list u{margin:1.15em 0}.notes-list__scroll{position:absolute;overflow-y:auto;top:0;bottom:0;right:0;left:0;padding-right:15px}.notes-list__content{list-style:none;padding:0;margin:0}.notes-list li{text-decoration:none;line-height:1.45em;cursor:pointer;word-wrap:break-word}.notes-list li:not(:last-of-type){margin-bottom:.75em}.notes-list li:hover{color:#fff}.notes-list--loading:after,.notes-list--loading:before{content:"";background:rgba(186,195,219,.2);height:6px;display:block;border-radius:5px;margin:7px 0 15px;width:65%}.folder-header:after{content:" ";display:table;clear:both}.folder-header{position:relative;margin-bottom:17px;font-size:14.8px;cursor:pointer;color:#bac3db;padding-left:25px}.folder-header__close{position:absolute;left:0;top:43%;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.folder-header__close svg{height:15px;fill:#dee6fc}.folder-header__name{color:#dee6fc}.folder-header__settings{color:rgba(186,195,219,.5);margin-top:3px;cursor:pointer}.folder-header__settings:hover{color:#bac3db}.folder-settings{background:#292b37;position:absolute;top:calc(100% + 17px);left:0;right:0;z-index:2;display:none;padding:10px 0}.folder-settings__close{position:absolute;right:0;top:3px;cursor:pointer}.folder-settings__close svg{opacity:.2}.folder-settings__close:hover svg{opacity:1}.folder-settings__delete{margin-top:15px;font-size:14.6px}.folder-settings__delete svg{margin-right:10px;vertical-align:text-bottom}.folder-settings__delete:hover{color:#fff}.folder-settings-opened .folder-settings{display:block}.folder-settings-opened .aside-swiper__right .aside__scrollable{visibility:hidden}.status-bar{margin-top:2px;font-size:13.2px;letter-spacing:.038em;font-weight:400;color:rgba(222,230,252,.5);transition:color .25s cubic-bezier(.32,-.01,0,.99)}.status-bar--blinked{color:#dee6fc}.status-bar--loading:after{content:"...";display:inline-block;-webkit-animation:loading 1s infinite;animation:loading 1s infinite;overflow:hidden;vertical-align:text-bottom}@-webkit-keyframes loading{0%{width:0}to{width:12px}}@keyframes loading{0%{width:0}to{width:12px}}body{height:100vh;margin:0;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;background:#fff}.drag-bar{position:absolute;width:100%;height:35px;top:0;left:0;z-index:1;-webkit-app-region:drag}svg{fill:currentColor;vertical-align:middle;max-height:100%}.clearfix:after{content:"";display:table;clear:"both"}.hide{display:none!important} +/*# sourceMappingURL=bundle.css.map*/ diff --git a/public/build/bundle.js b/public/build/bundle.js index 81963b4f..430c3ec3 100644 --- a/public/build/bundle.js +++ b/public/build/bundle.js @@ -1,2762 +1 @@ -var codex = codex || {}; codex["notes"] = -/******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // identity function for calling harmony imports with the correct context -/******/ __webpack_require__.i = function(value) { return value; }; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { -/******/ configurable: false, -/******/ enumerable: true, -/******/ get: getter -/******/ }); -/******/ } -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 10); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -/** -* DOM manipulations methods -*/ -var DOM = function () { - function DOM() { - _classCallCheck(this, DOM); - } - - _createClass(DOM, null, [{ - key: 'make', - - /** - * Helper for making Elements with classname and attributes - * @param {string} tagName - new Element tag name - * @param {array|string} classNames - list or name of CSS classname(s) - * @param {Object} attributes - any attributes - * @return {Element} - */ - value: function make(tagName, classNames, attributes) { - var el = document.createElement(tagName); - - if (Array.isArray(classNames)) { - var _el$classList; - - (_el$classList = el.classList).add.apply(_el$classList, _toConsumableArray(classNames)); - } else if (classNames) { - el.classList.add(classNames); - } - - for (var attrName in attributes) { - el[attrName] = attributes[attrName]; - } - - return el; - } - - /** - * Append one or several elements to the parent - * - * @param {Element} parent - where to append - * @param {Element|Element[]} - element ore elements list - */ - - }, { - key: 'append', - value: function append(parent, elements) { - if (Array.isArray(elements)) { - elements.forEach(function (el) { - return parent.appendChild(el); - }); - } else { - parent.appendChild(elements); - } - } - - /** - /** - * Replaces node with - * @param {Element} nodeToReplace - * @param {Element} replaceWith - */ - - }, { - key: 'replace', - value: function replace(nodeToReplace, replaceWith) { - return nodeToReplace.parentNode.replaceChild(replaceWith, nodeToReplace); - } - - /** - * getElementById alias - * @param {String} elementId - */ - - }, { - key: 'get', - value: function get(elementId) { - return document.getElementById(elementId); - } - - /** - * Loads static resourse: CSS or JS - * @param {string} type - CSS|JS - * @param {string} path - resource path - * @param {string} inctanceName - unique name of resource - * @return Promise - */ - - }, { - key: 'loadResource', - value: function loadResource(type, path, instanceName) { - /** - * Imported resource ID prefix - * @type {String} - */ - var resourcePrefix = 'cdx-resourse'; - - return new Promise(function (resolve, reject) { - if (!type || !['JS', 'CSS'].includes(type)) { - reject('Unexpected resource type passed. \xABCSS\xBB or \xABJS\xBB expected, \xAB' + type + '\xBB passed'); - } - - var node = void 0; - - /** Script is already loaded */ - if (!instanceName) { - reject('Instance name is missed'); - } else if (document.getElementById(resourcePrefix + '-' + type.toLowerCase() + '-' + instanceName)) { - resolve(path); - } - - if (type === 'JS') { - node = document.createElement('script'); - node.async = true; - node.defer = true; - node.charset = 'utf-8'; - } else { - node = document.createElement('link'); - node.rel = 'stylesheet'; - } - - node.id = resourcePrefix + '-' + type.toLowerCase() + '-' + instanceName; - - var timerLabel = 'Resource loading ' + type + ' ' + instanceName; - - console.time(timerLabel); - - node.onload = function () { - console.timeEnd(timerLabel); - resolve(path); - }; - - node.onerror = function () { - console.timeEnd(timerLabel); - reject(path); - }; - - if (type === 'JS') { - node.src = path; - } else { - node.href = path; - } - - document.head.appendChild(node); - }); - } - - /** - * Inserts one element after another - * @param {Element} newNode - * @param {Element} referenceNode - */ - - }, { - key: 'after', - value: function after(newNode, referenceNode) { - referenceNode.insertAdjacentElement('afterEnd', newNode); - } - }]); - - return DOM; -}(); - -exports.default = DOM; - -/***/ }), -/* 1 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var remote = __webpack_require__(3).remote; - -/** - * - */ - -var Dialog = function () { - - /** - * - */ - function Dialog() { - _classCallCheck(this, Dialog); - } - - _createClass(Dialog, null, [{ - key: 'confirm', - - - /** - * - * @returns {boolean} - */ - value: function confirm(text) { - var browserWindow = remote.getCurrentWindow(); - - browserWindow.setSheetOffset(30, browserWindow.width / 2); - - var choice = remote.dialog.showMessageBox(browserWindow, { - type: 'question', - buttons: ['Yes', 'No'], - title: 'Confirm', - message: text - }); - - if (choice === 0) { - return true; - } else { - return false; - } - } - - /** - * Shows error notification - * - * @returns {boolean} - */ - - }, { - key: 'error', - value: function error(text) { - var browserWindow = remote.getCurrentWindow(); - - browserWindow.setSheetOffset(30, browserWindow.width / 2); - - remote.dialog.showMessageBox(browserWindow, { - type: 'error', - title: 'Wow. Something goes wrong.', - message: text - }); - } - }]); - - return Dialog; -}(); - -exports.default = Dialog; - -/***/ }), -/* 2 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var $ = __webpack_require__(0).default; -var AutoResizer = __webpack_require__(12).default; -var Dialog = __webpack_require__(1).default; -var Shortcut = __webpack_require__(15).default; - -/** - * @typedef {Object} NoteData - * @property {String} _id — Note's id - * @property {String} title — Note's title - * @property {String} authorId — Note's Author id - * @property {String} folderId - Note's Folder id - * @property {String} content - JSON with Note's body - * @property {Number} dtModify - timestamp of last modification - * @property {Number} dtCreate - timestamp of Note creation - * @property {Boolean} isRemoved - Note's removed state - * @property {String|null} editorVersion - used CodeX Editor version - */ - -/** - * Note section module - * - * @typedef {Note} Note - * @property {Element} deleteButton - * @property {Element} titleEl - * @property {Element} dateEl - * @property {Timer} showSavedIndicatorTimer - * @property {ShortCut[]} shortcut - */ - -var Note = function () { - - /** - * @constructor - */ - function Note() { - _classCallCheck(this, Note); - - this.deleteButton = $.get('delete-button'); - - this.titleEl = document.getElementById('note-title'); - this.dateEl = document.getElementById('note-date'); - - this.showSavedIndicatorTimer = null; - - // when we are creating new note - if (!this.autoresizedTitle) { - this.autoresizedTitle = new AutoResizer([this.titleEl]); - } - - this.shortcuts = []; - } - - /** - * Send note data to backend - * @static - */ - - - _createClass(Note, [{ - key: 'save', - value: function save() { - var _this = this; - - this.deleteButton.classList.remove('hide'); - - /** - * If folder is opened, pass id. Otherwise pass false - */ - var folderId = codex.notes.aside.currentFolder ? codex.notes.aside.currentFolder.id : null; - - codex.editor.saver.save().then(function (noteData) { - _this.validate(noteData); - return noteData; - }).then(function (noteData) { - var note = { - data: noteData, - title: _this.titleEl.value.trim(), - folderId: folderId - }; - - var saveIndicator = document.getElementById('save-indicator'); - - if (_this.showSavedIndicatorTimer) { - window.clearTimeout(_this.showSavedIndicatorTimer); - } - - saveIndicator.classList.add('saved'); - - _this.showSavedIndicatorTimer = window.setTimeout(function () { - saveIndicator.classList.remove('saved'); - }, 500); - - window.ipcRenderer.send('note - save', { note: note }); - }).catch(function (err) { - console.log('Error while saving note: ', err); - }); - } - - /** - * Validate Note data before saving - * @param {object} noteData - * @throws {Error} - */ - - }, { - key: 'validate', - value: function validate(noteData) { - if (!noteData.items.length) { - throw Error('Article is empty'); - } - } - - /** - * Add Note to the menu by Aside.addMenuItem method - * - * @param {object} data - * @param {object} data.note - * @param {number} data.note.folderId - * @param {number} data.note._id - * @param {string} data.note.title - * @param {Boolean} data.isRootFolder - true if Note included in the Root Folder - */ - - }, { - key: 'addToMenu', - value: function addToMenu(_ref) { - var note = _ref.note, - isRootFolder = _ref.isRootFolder; - - codex.editor.state.blocks.id = note._id; - codex.notes.aside.addMenuItem(note, isRootFolder); - } - - /** - * Render the Note - * @param {NoteData} note - */ - - }, { - key: 'render', - value: function render(note) { - codex.editor.content.clear(true); - this.titleEl.value = note.title; - - /** - * We store all times in a Seconds to correspond server-format - * @type {Date} - */ - var dtModify = new Date(note.dtModify * 1000); - - this.dateEl.textContent = dtModify.toLocaleDateString('en-US', { - day: 'numeric', - month: 'short', - hour: 'numeric', - minute: 'numeric', - hour12: false - }); - codex.editor.content.load({ - id: note._id, - items: JSON.parse(note.content), - time: note.dtModify, - version: note.editorVersion - }); - this.deleteButton.classList.remove('hide'); - - /** - * if we are trying to render new note but we have an Autoresizer instance - * then we need to clear it before we create new one - */ - if (this.autoresizedTitle) { - this.autoresizedTitle.destroy(); - } - - this.autoresizedTitle = new AutoResizer([this.titleEl]); - - /** - * create new CMD+A shortcut - * bind it on current rendered Note - */ - var shortcut = new Shortcut({ - name: 'CMD+A', - on: codex.editor.nodes.redactor, - callback: function callback(event) { - event.preventDefault(); - event.stopImmediatePropagation(); - - var range = document.createRange(), - selection = window.getSelection(); - - range.selectNodeContents(codex.editor.nodes.redactor); - selection.removeAllRanges(); - selection.addRange(range); - } - }); - - this.shortcuts.push(shortcut); - } - - /** - * Clears editor - */ - - }, { - key: 'clear', - value: function clear() { - codex.editor.content.clear(true); - this.titleEl.value = ''; - this.dateEl.textContent = ''; - codex.editor.ui.addInitialBlock(); - this.deleteButton.classList.add('hide'); - - // destroy autoresizer - this.autoresizedTitle.destroy(); - - // destroy all shortcuts on note - this.shortcuts.forEach(function (shortcut) { - shortcut.remove(); - }); - } - - /** - * Set focus to the Editor - */ - - }, { - key: 'delete', - - - /** - * Delete article - */ - value: function _delete() { - var id = codex.editor.state.blocks.id; - - if (!id) { - return; - } - - if (Dialog.confirm('Are you sure you want to delete this note?')) { - if (!window.ipcRenderer.sendSync('note - delete', { id: id })) { - return false; - } - - codex.notes.aside.removeMenuItem(id); - this.clear(); - } - } - - /** - * Title input keydowns - * @description By ENTER, sets focus on editor - * @param {Element} titleElement - title block - * @param {Event} event - keydown event - */ - - }, { - key: 'titleKeydownHandler', - value: function titleKeydownHandler(titleElement, event) { - if (event.keyCode == 13) { - event.preventDefault(); - - Note.focusEditor(); - } - } - }], [{ - key: 'focusEditor', - value: function focusEditor() { - window.setTimeout(function () { - var editor = document.querySelector('.ce-redactor'); - - editor.click(); - }, 10); - } - }]); - - return Note; -}(); - -exports.default = Note; - -/***/ }), -/* 3 */ -/***/ (function(module, exports) { - -module.exports = require("electron"); - -/***/ }), -/* 4 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _folder = __webpack_require__(14); - -var _folder2 = _interopRequireDefault(_folder); - -var _note = __webpack_require__(2); - -var _note2 = _interopRequireDefault(_note); - -var _folderSettings = __webpack_require__(13); - -var _folderSettings2 = _interopRequireDefault(_folderSettings); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var AsideSwiper = __webpack_require__(11).default; -var $ = __webpack_require__(0).default; - -/** - * Maximum chars at the menu title - * @type {Number} - */ -var menuItemTitleMaxLength = 68; - -/** - * Aside column module - * - * @property {object} this.CSS classnames dictionary - * @property {AsideSwiper} this.swiper AsideSwiper instance - * @property {Folder} this.currentFolder Opened folder instance - * @property {Folder} this.previouslyOpenedFolder See docs in {@link Aside#constructor} - * @property {Element} this.newFolderButton New folder button - * @property {Element} this.newFolderField New folder form field - * @property {FolderSettings} this.folderSettings Folder Settings Panel instance - */ - -var Aside = function () { - - /** - * @constructor - */ - function Aside() { - var _this = this; - - _classCallCheck(this, Aside); - - /** - * Make CSS dictionary - * @type {Object} - */ - this.CSS = { - notesMenuLoading: 'notes-list--loading' - }; - - /** - * Find notes list holder - * @type {Element} - */ - var notesMenu = document.querySelector('[name="js-notes-menu"]'), - foldersMenu = document.querySelector('[name="js-folders-menu"]'); - - /** - * Module for hide/show folder sections - * @type {AsideSwiper} - */ - this.swiper = new AsideSwiper({ - opened: function opened() { - return _this.folderOpened(); - }, - closed: function closed() { - return _this.folderClosed(); - } - }); - - /** - * Current opened folder. - * @type {Folder} - */ - this.currentFolder = null; - - /** - * Save previously opened folder id. - * Usecase: - * - Folder opened by click in menu (and saved in {@link Aside#currentFolder}) - * - Folder closed by swipe-left on Aside (this.currentFolder = null) - * - User makes swipe-right to open Folder back, but we have not its ID - * - So we use previouslyOpenedFolder to construct this.currentFolder again - */ - this.previouslyOpenedFolder = null; - - /** - * Show preloader - */ - notesMenu.classList.add(this.CSS.notesMenuLoading); - foldersMenu.classList.add(this.CSS.notesMenuLoading); - - /** - * Emit message to load list - */ - this.loadNotes(); - this.loadFolders(); - - /** - * Update folder list - */ - window.ipcRenderer.on('update folders list', function (event, _ref) { - var userFolders = _ref.userFolders; - - foldersMenu.classList.remove(_this.CSS.notesMenuLoading); - foldersMenu.innerHTML = ''; - userFolders.forEach(function (folder) { - return _this.addFolder(folder); - }); - }); - - /** - * Update notes list - */ - window.ipcRenderer.on('notes list - update', function (event, _ref2) { - var notes = _ref2.notes, - isRootFolder = _ref2.isRootFolder; - - notesMenu.classList.remove(_this.CSS.notesMenuLoading); - notes.forEach(function (note) { - return _this.addMenuItem(note, isRootFolder); - }); - }); - - /** - * Activate new note button - */ - var newNoteButtons = document.querySelectorAll('[name="js-new-note-button"]'); - - newNoteButtons.forEach(function (button) { - button.addEventListener('click', function () { - return _this.newNoteButtonClicked(button); - }); - }); - - /** - * Activate new folder button - */ - this.newFolderButton = document.querySelector('[name="js-new-folder-button"]'); - this.newFolderField = document.querySelector('[name="js-new-folder-field"]'); - - var newFolderInput = this.newFolderField.querySelector('input'); - - this.newFolderButton.addEventListener('click', function (event) { - return _this.newFolderButtonClicked(event); - }); - newFolderInput.addEventListener('keydown', function (event) { - return _this.newFolderInputFilled(event); - }); - - /** - * Activate folders Back button - */ - var folderCloseToggler = $.get('folder-close-zone'); - - folderCloseToggler.addEventListener('click', function () { - _this.closeFolder(); - }); - - this.activateScrollableGradient(); - - /** - * Active 'Folder Settings' panel - */ - this.folderSettings = new _folderSettings2.default(); - } - - /** - * Loads notes list from the server - * - * Can be used async with subscribtion - * on window.ipcRenderer.on('notes list - update', (event, {notes, folder}) => {}) - * - * or synchronously like loadNotes().then( notes => {}) - * - * @param {string|null} folderId - * @returns {.[]} - */ - - - _createClass(Aside, [{ - key: 'loadNotes', - value: function loadNotes() { - var folderId = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; - - return new Promise(function (resolve) { - var response = window.ipcRenderer.sendSync('notes list - load', folderId); - /** - * @var {object} response - * @var {array} response.notes - * @var {object} response.folder - * @var {number} response.folder.id - * @var {string} response.folder.title - * @var {Boolean} response.isRootFolder - */ - - resolve(response); - }).catch(function (error) { - console.log('Error while loading notes: ', error); - }); - } - - /** - * Loads folders list - */ - - }, { - key: 'loadFolders', - value: function loadFolders() { - window.ipcRenderer.send('folders list - load'); - } - - /** - * New note button click handler - * @this {Aside} - */ - - }, { - key: 'newNoteButtonClicked', - value: function newNoteButtonClicked() { - _note2.default.focusEditor(); - - codex.notes.note.clear(); - } - - /** - * New folder button click handler - * @param {MouseEvent} event - */ - - }, { - key: 'newFolderButtonClicked', - value: function newFolderButtonClicked(event) { - var button = event.target, - input = this.newFolderField.querySelector('input'); - - button.classList.add('hide'); - this.newFolderField.classList.remove('hide'); - - input.focus(); - } - - /** - * New Folder input keydown handler - * @param {KeyboardEvent} event - */ - - }, { - key: 'newFolderInputFilled', - value: function newFolderInputFilled(event) { - if (event.key !== 'Enter') { - return; - } - - var input = event.target, - folderTitle = input.value.trim(); - - if (!folderTitle) { - return; - } - - /** - * Save Folder - * @type {object} - */ - var createdFolder = window.ipcRenderer.sendSync('folder - create', folderTitle); - - /** - * Add saved folder to the menu - */ - this.addFolder(createdFolder); - - input.value = ''; - - this.newFolderField.classList.add('hide'); - this.newFolderButton.classList.remove('hide'); - } - - /** - * - * Add a Note to the left menu - * - * @param {object} noteData - * @param {number} noteData._id - * @param {string} noteData.title - * @param {number} noteData.folderId - * - * @param {Boolean} isRootFolder - true if Note is included to the Root Folder - */ - - }, { - key: 'addMenuItem', - value: function addMenuItem(noteData, isRootFolder) { - var _this2 = this; - - if (!noteData.title) { - console.warn('Can not add Note to the Aside because it has no title', noteData); - return; - } - - var notesMenu = void 0; - - if (isRootFolder) { - notesMenu = document.querySelector('[name="js-notes-menu"]'); - } else if (this.currentFolder && noteData.folderId === this.currentFolder._id) { - notesMenu = document.querySelector('[name="js-folder-notes-menu"]'); - } else { - console.log('Note added to closed folder: %o', noteData.folderId); - return; - } - - /** - * If we already have this item, update title - */ - var existingNote = notesMenu.querySelector('[data-id="' + noteData._id + '"]'); - - if (existingNote) { - existingNote.textContent = this.createMenuItemTitle(noteData.title); - return; - } - - var item = this.makeMenuItem(noteData.title, { id: noteData._id }); - - notesMenu.insertAdjacentElement('afterbegin', item); - - item.addEventListener('click', function (event) { - return _this2.menuItemClicked(event); - }); - } - - /** - * Add new item to the folders list - * - * @param {object} folder - * @param {string} folder.title - * @param {number} folder._id - */ - - }, { - key: 'addFolder', - value: function addFolder(folder) { - var _this3 = this; - - if (!folder.title) { - console.warn('Can not add Folder to the Aside because it has no title', folder); - return; - } - var foldersMenu = document.querySelector('[name="js-folders-menu"]'); - var item = this.makeMenuItem(folder.title, { folderId: folder._id }); - - foldersMenu.insertAdjacentElement('afterbegin', item); - - item.addEventListener('click', function (event) { - return _this3.folderClicked(event.target); - }); - } - - /** - * Makes aside menu item - * @param {String} title - item title - * @param {object} dataset - data to store in dataset - * @return {Element} - */ - - }, { - key: 'makeMenuItem', - value: function makeMenuItem(title, dataset) { - title = this.createMenuItemTitle(title); - - var item = $.make('li', null, { - textContent: title - }); - - for (var key in dataset) { - item.dataset[key] = dataset[key]; - } - - return item; - } - - /** - * Creates aside menu item title - * @param {String} title - * @return {String} - */ - - }, { - key: 'createMenuItemTitle', - value: function createMenuItemTitle(title) { - if (title.length > menuItemTitleMaxLength) { - title = title.substring(0, menuItemTitleMaxLength) + '…'; - } - - return title; - } - - /** - * Remove item from menu - * - * @param itemId - */ - - }, { - key: 'removeMenuItem', - value: function removeMenuItem(itemId) { - var notesMenu = document.querySelectorAll('[name="js-notes-menu"], [name="js-folder-notes-menu"]'); - - notesMenu.forEach(function (menu) { - var existingNote = menu.querySelector('[data-id="' + itemId + '"]'); - - if (existingNote) existingNote.remove(); - }); - } - - /** - * Remove folder from menu by ID - * @param folderId - folder ID - */ - - }, { - key: 'removeFolderFromMenu', - value: function removeFolderFromMenu(folderId) { - var foldersMenu = document.querySelector('[name="js-folders-menu"]'); - - if (!foldersMenu) { - return false; - } - - var folderItem = foldersMenu.querySelector('[data-folder-id="' + folderId + '"]'); - - if (folderItem) { - folderItem.remove(); - } - } - - /** - * Updates Folder's title in menu - * - * @param {MongoId} folderId - folder ID - * @param {String} title - new title - */ - - }, { - key: 'updateFolderTitleInMenu', - value: function updateFolderTitleInMenu(folderId, title) { - var foldersMenu = document.querySelector('[name="js-folders-menu"]'); - - if (!foldersMenu) { - return false; - } - - var folderItem = foldersMenu.querySelector('[data-folder-id="' + folderId + '"]'); - - if (folderItem) { - folderItem.textContent = title; - } - } - - /** - * Note in aside menu click listener - * @param {MouseEvent} event - */ - - }, { - key: 'menuItemClicked', - value: function menuItemClicked(event) { - var menuItem = event.target, - id = menuItem.dataset.id; - - var noteData = window.ipcRenderer.sendSync('note - get', { id: id }); - - codex.notes.note.render(noteData); - - /** - * Scroll to top - */ - var editorView = document.querySelector('[name="editor-view"]'); - - editorView.scrollIntoView(); - } - - /** - * Fired after swipe-right - */ - - }, { - key: 'folderOpened', - value: function folderOpened() { - /** - * Restore current folder after closing - */ - if (!this.currentFolder && this.previouslyOpenedFolder) { - this.currentFolder = new _folder2.default(this.previouslyOpenedFolder); - } - - console.assert(this.currentFolder, 'Folder opened but does not initialized'); - - codex.notes.note.clear(); - } - - /** - * Fired after swipe-left - */ - - }, { - key: 'folderClosed', - value: function folderClosed() { - if (this.currentFolder) { - this.previouslyOpenedFolder = this.currentFolder.id; - } - - this.currentFolder = null; - } - - /** - * Folder menu item clicked handler - * @param {Element} item - clicked folder button - */ - - }, { - key: 'folderClicked', - value: function folderClicked(item) { - var folderId = item.dataset.folderId; - - /** - * Load folder - */ - this.currentFolder = new _folder2.default(folderId, item.textContent); - - /** - * Open folder section - */ - this.swiper.open(); - } - - /** - * Closes opened folder - */ - - }, { - key: 'closeFolder', - value: function closeFolder() { - this.swiper.close(); - } - - /** - * Shows fade-out gradient at the top of scrollable zone - * Uses by scroll to prevent overlaying first block (NOTES, FOLDERS headings) with gradient when block is not scrolled - */ - - }, { - key: 'activateScrollableGradient', - value: function activateScrollableGradient() { - /** - * Scroll top offset to show gradient - * @type {Number} - */ - var minimumDistance = 5; - - /** - * Modificatior that will be added to the wrapper on scroll - * @type {String} - */ - var scrolledModificator = 'aside__scrollable--scrolled'; - - /** - * Scrollable zoners - * @type {Element[]} - */ - var scrollableZones = document.querySelectorAll('[name="js-scrollable"]'); - - var addClassOnScroll = function addClassOnScroll(event) { - var scrollableContent = event.target, - scrollableWrapper = event.target.parentNode; - - if (scrollableContent.scrollTop > minimumDistance) { - scrollableWrapper.classList.add(scrolledModificator); - } else { - scrollableWrapper.classList.remove(scrolledModificator); - } - }; - - scrollableZones.forEach(function (zone) { - zone.addEventListener('scroll', addClassOnScroll); - }); - } - }]); - - return Aside; -}(); - -exports.default = Aside; - -/***/ }), -/* 5 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -/** - * @module ConnectionObserver - * - * Detects Online and Offline statuses and update state in the Aside - * - * @typedef {ConnectionObserver} ConnectionObserver - */ -var ConnectionObserver = function () { - /** - * @constructor - */ - function ConnectionObserver() { - var _this = this; - - _classCallCheck(this, ConnectionObserver); - - if (window.navigator.onLine) { - this.online(); - } else { - this.offline(); - } - - window.addEventListener('online', function () { - _this.online(); - }); - window.addEventListener('offline', function () { - _this.offline(); - }); - } - - /** - * Fired when the Application goes Online - */ - - - _createClass(ConnectionObserver, [{ - key: 'online', - value: function online() { - codex.notes.statusBar.text = 'Syncing'; - codex.notes.statusBar.loading = true; - - this.sync().then(function () { - codex.notes.statusBar.text = 'All saved'; - codex.notes.statusBar.loading = false; - }); - } - - /** - * Send sync event - * @return {Promise} - updates from the Cloud - */ - - }, { - key: 'sync', - value: function sync() { - return new Promise(function (resolve) { - console.time('Syncing...'); - window.ipcRenderer.send('user - sync'); - window.ipcRenderer.once('sync finished', function (event, returnedData) { - console.timeEnd('Syncing...'); - resolve(returnedData); - }); - }); - } - - /** - * Fired when the Application goes Offline - */ - - }, { - key: 'offline', - value: function offline() { - codex.notes.statusBar.text = 'Offline'; - - this.reconnect(); - } - - /** - * Start reconnection process - */ - - }, { - key: 'reconnect', - value: function reconnect() { - codex.notes.statusBar.text = 'Reconnection'; - codex.notes.statusBar.loading = true; - } - }]); - - return ConnectionObserver; -}(); - -exports.default = ConnectionObserver; - -/***/ }), -/* 6 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var $ = __webpack_require__(0).default; - -/** - * CodeX Editor module - */ - -var Editor = function () { - - /** - * @constructor - * @property {String} path - CodeX Editor library path - * @property {Array} plugins - plugins names - * @property {TimerId} autosaveTimer - autosave debounce timer - */ - function Editor() { - var _this = this; - - _classCallCheck(this, Editor); - - this.path = '../../public/codex.editor/'; - this.plugins = ['paragraph', 'header']; - - this.autosaveTimer = null; - - this.loadEditor().then(function () { - return _this.loadPlugins(); - }).then(function () { - return _this.init(); - }); - } - - /** - * Loads CodeX Editor sources - * @return {Promise} - */ - - - _createClass(Editor, [{ - key: 'loadEditor', - value: function loadEditor() { - return Promise.all([$.loadResource('JS', this.path + 'codex-editor.js', 'codex-editor'), $.loadResource('CSS', this.path + 'codex-editor.css', 'codex-editor')]).catch(function (err) { - return console.warn('Cannot load Codex Editor sources: ', err); - }).then(function () { - return console.log('CodeX Editor loaded'); - }); - } - - /** - * Loads CodeX Editor plugins - * @return {Promise} - */ - - }, { - key: 'loadPlugins', - value: function loadPlugins() { - var _this2 = this; - - var pluginsQuery = []; - - this.plugins.forEach(function (name) { - pluginsQuery.push.apply(pluginsQuery, [$.loadResource('JS', _this2.path + 'plugins/' + name + '/' + name + '.js', name), $.loadResource('CSS', _this2.path + 'plugins/' + name + '/' + name + '.css', name)]); - }); - - return Promise.all(pluginsQuery).catch(function (err) { - return console.warn('Cannot load plugin: ', err); - }).then(function () { - return console.log('Plugins loaded'); - }); - } - - /** - * Init CodeX Editor - * @return {[type]} [description] - */ - - }, { - key: 'init', - value: function init() { - var _this3 = this; - - var config = { - holderId: 'codex-editor', - initialBlockPlugin: 'paragraph', - hideToolbar: false, - placeholder: 'Your story', - tools: {} - }; - - this.plugins.forEach(function (name) { - if (!window[name]) { - console.warn('Plugin ' + name + ' does not ready'); - return; - } - - config.tools[name] = { - type: name, - iconClassname: 'ce-icon-' + name, - render: window[name].render, - validate: window[name].validate, - save: window[name].save, - destroy: window[name].destroy, - makeSettings: window[name].makeSettings - }; - }); - - if (config.tools.paragraph) { - config.tools.paragraph.allowedToPaste = true; - config.tools.paragraph.showInlineToolbar = true; - config.tools.paragraph.allowRenderOnPaste = true; - } - - if (config.tools.header) { - config.tools.header.displayInToolbox = true; - } - - codex.editor.start(config); - - window.setTimeout(function () { - _this3.enableAutosave(); - }, 500); - } - - /** - * Keyup event on editor zone fires timeout to autosave note - */ - - }, { - key: 'autosave', - value: function autosave() { - if (this.autosaveTimer) window.clearTimeout(this.autosaveTimer); - - this.autosaveTimer = window.setTimeout(function () { - codex.notes.note.save(); - }, 500); - } - - /** - * Add keyup listener to editor zone - */ - - }, { - key: 'enableAutosave', - value: function enableAutosave() { - var noteTitle = document.getElementById('note-title'); - - noteTitle.addEventListener('keyup', this.autosave.bind(this)); - codex.editor.nodes.redactor.addEventListener('keyup', this.autosave.bind(this)); - } - - /** - * Remove keyup listener to editor zone - */ - - }, { - key: 'disableAutosave', - value: function disableAutosave() { - codex.editor.nodes.redactor.removeEventListener('keyup', this.autosave.bind(this)); - } - }]); - - return Editor; -}(); - -exports.default = Editor; - -/***/ }), -/* 7 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _dom = __webpack_require__(0); - -var _dom2 = _interopRequireDefault(_dom); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -/** - * @module StatusBar - * @description Module for working with Aside Status Bar - * - * @typedef {StatusBar} StatusBar - * @property {Element} statusBar - Status Bar Element - */ -var StatusBar = function () { - - /** - * @constructor - * Find status bar Element, init all stuff - */ - function StatusBar() { - _classCallCheck(this, StatusBar); - - this.statusBar = _dom2.default.get('status-bar'); - } - - /** - * CSS class names - */ - - - _createClass(StatusBar, [{ - key: 'text', - - - /** - * Update text in the Status Bar - * @param {string} statusText - new text - */ - set: function set(statusText) { - var _this = this; - - this.statusBar.textContent = statusText; - - this.statusBar.classList.add(StatusBar.CSS.blinked); - window.setTimeout(function () { - _this.statusBar.classList.remove(StatusBar.CSS.blinked); - }, 400); - } - - /** - * Status Bar text getter - */ - , - get: function get() { - return this.statusBar.textContent; - } - - /** - * Set loading state - * @param {boolean} state - true|false - */ - - }, { - key: 'loading', - set: function set(state) { - this.statusBar.classList.toggle(StatusBar.CSS.loading, state); - } - }], [{ - key: 'CSS', - get: function get() { - return { - blinked: 'status-bar--blinked', - loading: 'status-bar--loading' - }; - } - }]); - - return StatusBar; -}(); - -exports.default = StatusBar; - -/***/ }), -/* 8 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /** - * DOM helper - */ - - -var _dom = __webpack_require__(0); - -var _dom2 = _interopRequireDefault(_dom); - -var _dialog = __webpack_require__(1); - -var _dialog2 = _interopRequireDefault(_dialog); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -/** - * @class User - * @classdesc Authentication methods and user object - * - * @typedef {User} User - * @property {Element} authButton - button 'Login with Google' - */ -var User = function () { - - /** - * @constructor - */ - function User() { - var _this = this; - - _classCallCheck(this, User); - - this.authButton = document.getElementById('js-auth-button'); - - var userData = window.ipcRenderer.sendSync('user - get'); - - this.fillUserPanel(userData); - - this.authButton.addEventListener('click', function () { - _this.showAuth(); - }); - } - - /** - * Opens auth popup - */ - - - _createClass(User, [{ - key: 'showAuth', - value: function showAuth() { - var authResponse = window.ipcRenderer.sendSync('auth - google auth'); - - if (authResponse && authResponse.token) { - this.fillUserPanel(authResponse); - window.ipcRenderer.send('user - sync'); - } else { - _dialog2.default.error('Authentication failed. Please, try again.'); - } - } - - /** - * Fills user panel - * @param {Object} user - * @param {String} user.id - * @param {String} user.name - * @param {String} user.photo - */ - - }, { - key: 'fillUserPanel', - value: function fillUserPanel(user) { - if (!user.name) return; - - var userPanel = _dom2.default.get('user-panel'), - photo = _dom2.default.get('user-photo'); - - userPanel.classList.add('aside__header-avatar--filled'); - photo.style.backgroundImage = 'url(' + user.photo + ')'; - } - }]); - - return User; -}(); - -exports.default = User; - -/***/ }), -/* 9 */ -/***/ (function(module, exports) { - -// removed by extract-text-webpack-plugin - -/***/ }), -/* 10 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -/** - * Load libraries - */ - -var _user = __webpack_require__(8); - -var _user2 = _interopRequireDefault(_user); - -var _statusBar = __webpack_require__(7); - -var _statusBar2 = _interopRequireDefault(_statusBar); - -var _connectionObserver = __webpack_require__(5); - -var _connectionObserver2 = _interopRequireDefault(_connectionObserver); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var electron = __webpack_require__(3); -var Editor = __webpack_require__(6).default; - -/** - * Load components - */ -var Aside = __webpack_require__(4).default; -var Note = __webpack_require__(2).default; - -/** - * Save render proccess to the ipdRender global propery - */ -window.ipcRenderer = electron.ipcRenderer; - -/** - * Disable zoom - */ -electron.webFrame.setZoomLevelLimits(1, 1); - -/** - * Load CSS - */ -__webpack_require__(9); - -/** - * Document ready callback - */ -var documentReady = function documentReady() { - /** - * Initiate modules - * @type {Aside} - */ - codex.notes.editor = new Editor(); - codex.notes.aside = new Aside(); - codex.notes.note = new Note(); - codex.notes.user = new _user2.default(); - codex.notes.statusBar = new _statusBar2.default(); - codex.notes.connectionObserver = new _connectionObserver2.default(); - - /** - * New note saving handler - */ - window.ipcRenderer.on('note saved', function (event, response) { - codex.notes.note.addToMenu(response); - }); -}; - -var openExternalLink = function openExternalLink(event) { - if (event.target.tagName !== 'A' || !event.target.href) { - return; - } - - if (!event.target.closest('.editor')) { - electron.shell.openExternal(event.target.href); - return; - } - - if (event.metaKey || event.ctrlKey) { - electron.shell.openExternal(event.target.href); - } -}; - -/** - * Application - */ -module.exports = function () { - document.addEventListener('DOMContentLoaded', documentReady, false); - document.addEventListener('click', openExternalLink); - - /** - * Allow access modules with codex.notes[module] - */ - return {}; -}(); - -/***/ }), -/* 11 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var SwipeDetector = __webpack_require__(16).default; - -/** - * Aside swiper class - * @property {object} CSS dictionary - */ - -var AsideSwiper = function () { - - /** - * @constructor - * @param {Function} opened - opening callback - * @param {Function} closed - closing callback - */ - function AsideSwiper(_ref) { - var _this = this; - - var opened = _ref.opened, - closed = _ref.closed; - - _classCallCheck(this, AsideSwiper); - - this.CSS = { - wrapper: 'aside-swiper', - toggled: 'aside-swiper--toggled', - left: 'aside-swiper__left', - right: 'aside-swiper__right' - }; - - this.wrapper = document.querySelector('.' + this.CSS.wrapper); - this.left = this.wrapper.querySelector('.' + this.CSS.left); - this.right = this.wrapper.querySelector('.' + this.CSS.right); - - this.opened = opened || function () {}; - this.closed = closed || function () {}; - - /** - * Allow to open/close by two-fingers swipe left/right - */ - new SwipeDetector(this.wrapper, function (directionRight) { - if (directionRight) { - _this.open(); - } else { - _this.close(); - } - }); - } - - /** - * Swipe left menu, shows folder section - */ - - - _createClass(AsideSwiper, [{ - key: 'open', - value: function open() { - this.wrapper.classList.add(this.CSS.toggled); - this.opened(); - } - - /** - * Toggle off folder section - */ - - }, { - key: 'close', - value: function close() { - this.wrapper.classList.remove(this.CSS.toggled); - this.closed(); - } - }]); - - return AsideSwiper; -}(); - -exports.default = AsideSwiper; - -/***/ }), -/* 12 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -/** - * Autoresizer module - * Expands dynamically height of textareas - */ - -/** - * @property elements - array of elements - * @property {Function} addResizer - adds listeners - * @property {Function} removeResizer - removes listeners - * @property {Function} destroy - removes all elements and handlers - */ -var Autoresizer = function () { - - /** - * adds autoresize handler - * @param elements - elements that needs to expand - */ - function Autoresizer(elements) { - _classCallCheck(this, Autoresizer); - - this.elements = elements || []; - - for (var i = 0; i < this.elements.length; i++) { - this.addResizer(this.elements[i]); - } - } - - /** - * autoresizer for textareas - * @param {Element} el - element we want to expand - */ - - - _createClass(Autoresizer, [{ - key: 'addResizer', - value: function addResizer(el) { - if (el.value.trim()) { - el.style.height = el.scrollHeight + 'px'; - } else { - el.style.height = 'auto'; - } - - el.addEventListener('keydown', this.enterKeyPressed, false); - el.addEventListener('input', this.resize.bind(this, el), false); - } - - /** - * Prevent enter key pressing - * @param event - */ - - }, { - key: 'enterKeyPressed', - value: function enterKeyPressed(event) { - if (event.keyCode === 13) { - event.preventDefault(); - } - } - - /** - * Resize input - * @param el - */ - - }, { - key: 'resize', - value: function resize(el) { - el.style.height = 'auto'; - el.style.height = el.scrollHeight + 'px'; - } - - /** - * removes handlers from element - * @param {Element} el - element we want to clear from resizer - */ - - }, { - key: 'removeResizer', - value: function removeResizer(el) { - el.removeEventListener('keydown', this.enterKeyPressed); - el.removeEventListener('input', this.resize); - } - - /** - * Destroyer function. Clears all elements - */ - - }, { - key: 'destroy', - value: function destroy() { - for (var i = 0; i < this.elements.length; i++) { - this.removeResizer(this.elements[i]); - this.elements[i].style.height = 'auto'; - } - - this.elements = []; - } - }]); - - return Autoresizer; -}(); - -exports.default = Autoresizer; - -/***/ }), -/* 13 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var Dialog = __webpack_require__(1).default; -var $ = __webpack_require__(0).default; -var Validate = __webpack_require__(17).default; - -/** - * Folder Settings panel module - * - * @property {Boolean} opened - state - */ - -var FolderSettings = function () { - - /** - * @constructor - */ - function FolderSettings() { - var _this = this; - - _classCallCheck(this, FolderSettings); - - this.toggler = $.get('js-folder-settings-toggler'); - this.closeButton = $.get('js-close-folder'); - this.removeFolderButton = $.get('js-delete-folder'); - this.folderTitleInput = document.getElementsByName('folder-title')[0]; - this.newMemberInput = document.getElementsByName('new-member')[0]; - this.membersList = $.get('js-members-list'); - - this.toggler.addEventListener('click', function () { - _this.toggle(); - }); - - this.closeButton.addEventListener('click', function () { - _this.close(); - }); - - this.removeFolderButton.addEventListener('click', function () { - _this.removeFolderClicked(); - }); - - this.folderTitleInput.addEventListener('keydown', function (event) { - return _this.changeTitleKeydown(event); - }); - this.newMemberInput.addEventListener('keydown', function (event) { - return _this.inviteMemberKeydown(event); - }); - } - - /** - * CSS dictionary - */ - - - _createClass(FolderSettings, [{ - key: 'open', - - - /** - * Open panel and change state - */ - value: function open() { - document.body.classList.add(FolderSettings.CSS.panelOpenedModifier); - this.opened = true; - - /** - * Fill Folder's title input - */ - this.folderTitleInput.value = codex.notes.aside.currentFolder.title || ''; - } - - /** - * Close panel and change state - */ - - }, { - key: 'close', - value: function close() { - document.body.classList.remove(FolderSettings.CSS.panelOpenedModifier); - this.opened = false; - } - - /** - * Shows/hide this.panel - */ - - }, { - key: 'toggle', - value: function toggle() { - if (this.opened) { - this.close(); - } else { - this.open(); - } - } - - /** - * Handler for Remove Folder Button - */ - - }, { - key: 'removeFolderClicked', - value: function removeFolderClicked() { - console.assert(codex.notes.aside.currentFolder, 'Cannot remove Folder because it is not open'); - - var result = codex.notes.aside.currentFolder.delete(); - - if (result) { - this.close(); - codex.notes.aside.closeFolder(); - } - } - - /** - * Handler for Change Title input - * @param {KeyboardEvent} event - keydowns - */ - - }, { - key: 'changeTitleKeydown', - value: function changeTitleKeydown(event) { - if (event.key !== 'Enter') { - return; - } - - var input = event.target, - title = input.value.trim(), - id = codex.notes.aside.currentFolder._id; - - if (!title) { - return; - } - - /** - * Send request for renaming - * @type {object} - */ - var result = window.ipcRenderer.sendSync('folder - change title', { id: id, title: title }); - - if (!result) { - Dialog.error('Folder renaming failed. Please, try again.'); - return false; - } - - /** - * Update title in the: - * - folder header - * - aside menu - */ - codex.notes.aside.currentFolder.title = title; - - /** - * Close folder settings - */ - this.close(); - } - - /** - * Handler for New Member input - * @param {KeyboardEvent} event - keydowns - */ - - }, { - key: 'inviteMemberKeydown', - value: function inviteMemberKeydown(event) { - if (event.key !== 'Enter') { - return; - } - - var input = event.target, - email = input.value.trim(), - id = codex.notes.aside.currentFolder._id; - - if (!email || !Validate.email(email)) { - return; - } - - /** - * Send request for adding new collaborator - * @type {object} - */ - var result = window.ipcRenderer.sendSync('folder - collaborator add', { id: id, email: email }); - - if (!result) { - Dialog.error('Error while adding a collaborator to the folder'); - return false; - } - - // Clear input field - input.value = ''; - - // Add item to list of Collaborators - var newMemberItem = $.make('P', [], { - innerHTML: email - }); - - $.append(this.membersList, newMemberItem); - } - }], [{ - key: 'CSS', - get: function get() { - return { - panelOpenedModifier: 'folder-settings-opened' - }; - } - }]); - - return FolderSettings; -}(); - -exports.default = FolderSettings; - -/***/ }), -/* 14 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var $ = __webpack_require__(0).default; -var Dialog = __webpack_require__(1).default; - -/** - * Folders methods - * - * @typedef {Folder} Folder - * @property {Number} id - Folder's id - * @property {string} title - Folder's title - * @property {Array} notes - Notes list - * @property {Element} notesListWrapper - Notes list holder - */ - -var Folder = function () { - - /** - * Folder methods - * - * @param {Number} id - Folder's id - * @param {string} title - Folder's title - */ - function Folder(id, title) { - var _this = this; - - _classCallCheck(this, Folder); - - this._id = id; - this._title = title; - - this.folderTitleElement = $.get('js-folder-title'); - - /** - * Load actual Folder's data - * @type {Object} - */ - var folderData = window.ipcRenderer.sendSync('folder - get', this._id); - - this.title = folderData.title; - - codex.notes.aside.loadNotes(id).then(function (_ref) { - var notes = _ref.notes; - - _this.notes = notes; - }).then(function () { - return _this.clearNotesList(); - }); - - this.notesListWrapper = document.querySelector('[name="js-folder-notes-menu"]'); - } - - /** - * Folder id getter - */ - - - _createClass(Folder, [{ - key: 'fillHeader', - - - /** - * Fills folder header block - */ - value: function fillHeader() { - this.folderTitleElement.textContent = this._title; - } - - /** - * Clear list if there is no one note - */ - - }, { - key: 'clearNotesList', - value: function clearNotesList() { - this.notesListWrapper.innerHTML = ''; - } - - /** - * Delete folder - */ - - }, { - key: 'delete', - value: function _delete() { - if (Dialog.confirm('Are you sure you want to delete this folder?')) { - if (window.ipcRenderer.sendSync('folder - delete', this._id)) { - codex.notes.aside.removeFolderFromMenu(this._id); - codex.notes.note.clear(); - return true; - } - } - - Dialog.error('Folder removing failed'); - return false; - } - }, { - key: 'id', - get: function get() { - return this._id; - } - - /** - * Folder title getter - */ - - }, { - key: 'title', - get: function get() { - return this._title; - } - - /** - * Folder title setter - * @param {String} newTitle - */ - , - set: function set(newTitle) { - this._title = newTitle; - - /** - * Update in the Header - */ - this.fillHeader(); - - /** - * Update in the Aside menu - */ - codex.notes.aside.updateFolderTitleInMenu(this._id, this._title); - } - }]); - - return Folder; -}(); - -exports.default = Folder; - -/***/ }), -/* 15 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -/** - * CodeX Note ShortCuts class - * Handles keyDowns on Note. - * - * Used to create shortcuts on element - */ - -/** - * List of key codes - */ -var keyCodes = { - '0': 48, - '1': 49, - '2': 50, - '3': 51, - '4': 52, - '5': 53, - '6': 54, - '7': 55, - '8': 56, - '9': 57, - 'A': 65, - 'B': 66, - 'C': 67, - 'D': 68, - 'E': 69, - 'F': 70, - 'G': 71, - 'H': 72, - 'I': 73, - 'J': 74, - 'K': 75, - 'L': 76, - 'M': 77, - 'N': 78, - 'O': 79, - 'P': 80, - 'Q': 81, - 'R': 82, - 'S': 83, - 'T': 84, - 'U': 85, - 'V': 86, - 'W': 87, - 'X': 88, - 'Y': 89, - 'Z': 90, - 'BACKSPACE': 8, - 'ENTER': 13, - 'ESCAPE': 27, - 'LEFT': 37, - 'UP': 38, - 'RIGHT': 39, - 'DOWN': 40, - 'INSERT': 45, - 'DELETE': 46 -}; - -var supportedCommands = { - 'CMD': ['CMD', 'CONTROL', 'COMMAND', 'WINDOWS', 'CTRL'], - 'SHIFT': ['SHIFT'], - 'ALT': ['ALT', 'OPTION'] -}; - -/** - * @class ShortCuts - * @classdesc Callback will be fired with two params: - * - event: standard keyDown param - * - target: element which registered on shortcut creation - * - * @typedef {ShortCut} ShortCut - * @property {String} name - shortcut name - * @property {Element} on - element that passed on shortcut creation - * @property {Function} callback - custom user function - */ - -var ShortCut = function () { - - /** - * Create new shortcut - * @param {ShortCut} shortcut - * @constructor - */ - function ShortCut(shortcut) { - var _this = this; - - _classCallCheck(this, ShortCut); - - this.commands = {}; - this.keys = {}; - - this.parseShortcutName(shortcut.name); - - this.element = shortcut.on; - this.callback = shortcut.callback; - - this.executeShortcut = function (event) { - _this.execute(event); - }; - this.element.addEventListener('keydown', this.executeShortcut, false); - } - - /** - * parses string to get shortcut commands in uppercase - * @param {String} shortcut - * - * @return {Array} keys - */ - - - _createClass(ShortCut, [{ - key: 'parseShortcutName', - value: function parseShortcutName(shortcut) { - shortcut = shortcut.split('+'); - - for (var key = 0; key < shortcut.length; key++) { - shortcut[key] = shortcut[key].toUpperCase(); - - if (shortcut[key].length > 1) { - for (var command in supportedCommands) { - if (supportedCommands[command].includes(shortcut[key])) { - this.commands[command] = true; - } - } - } else { - this.keys[shortcut[key]] = true; - } - } - } - - /** - * Check all passed commands and keys before firing callback - * @param event - */ - - }, { - key: 'execute', - value: function execute(event) { - var cmdKey = event.ctrlKey || event.metaKey, - shiftKey = event.shiftKey, - altKey = event.altKey, - passed = { - 'CMD': cmdKey, - 'SHIFT': shiftKey, - 'ALT': altKey - }; - - var command = void 0, - allCommandsPassed = true; - - for (command in this.commands) { - allCommandsPassed = allCommandsPassed && passed[command]; - } - - var key = void 0, - allKeysPassed = true; - - for (key in this.keys) { - allKeysPassed = allKeysPassed && event.keyCode === keyCodes[key]; - } - - if (allCommandsPassed && allKeysPassed) { - this.callback.call(null, event); - } - } - - /** - * Destroy shortcut: remove listener from element - */ - - }, { - key: 'remove', - value: function remove() { - this.element.removeEventListener('keydown', this.executeShortcut); - } - }]); - - return ShortCut; -}(); - -exports.default = ShortCut; - -/***/ }), -/* 16 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -/** - * Two fingers swipe detection class - */ -var SwipeDetector = function () { - - /** - * @constructor - * - * @param {Element} el - Element to handle swipe - * @param {Function} callback - Callback for swipe event. Accepts {Boolean} directionRight parameter - * - * - * @property {Element} el - * @property {Function} callback - * @property {Boolean} swiped - Flag user to detect horisontal swipe by mousewheel - * @property {Timer} wheelTimeout - Timer for detect swipe - */ - function SwipeDetector(el, callback) { - var _this = this; - - _classCallCheck(this, SwipeDetector); - - this.el = el; - this.callback = callback; - this.swiped = false; - this.wheelTimeout = null; - - this.el.addEventListener('mousewheel', function (event) { - _this.detectSwipe(event); - }); - } - - /** - * Detects two-fingers swipe and fires callback - * @fires this.callback - * @param {WheelEvent} event - mouse wheel - */ - - - _createClass(SwipeDetector, [{ - key: 'detectSwipe', - value: function detectSwipe(event) { - var _this2 = this; - - /** - * Detect horisontal scroll - * @type {Boolean} - */ - var isHorisontal = event.wheelDeltaY === 0; - - /** - * Dont fire swipe event on small scrolls - * @type {Boolean} - */ - var minimumDistance = 30; - var swipeEnoughLong = event.wheelDeltaX > minimumDistance || event.wheelDeltaX < -1 * minimumDistance; - - if (isHorisontal && swipeEnoughLong) { - if (!this.swiped) { - this.swiped = true; - - /** - * Pass directionRight parameter. True for right swipe, false for left swipe - */ - this.callback(event.deltaX > 0); - - this.wheelTimeout = window.setTimeout(function () { - _this2.swiped = false; - }, 1000); - } - } - } - }]); - - return SwipeDetector; -}(); - -exports.default = SwipeDetector; - -/***/ }), -/* 17 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -/** - * Validate module - */ -var Validate = function () { - function Validate() { - _classCallCheck(this, Validate); - } - - _createClass(Validate, null, [{ - key: "email", - - - /** - * Check for email validness - * - * @param {string} email - * @return {boolean} - */ - value: function email(_email) { - var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; - - return re.test(_email); - } - }]); - - return Validate; -}(); - -exports.default = Validate; - -/***/ }) -/******/ ]); -//# sourceMappingURL=bundle.js.map \ No newline at end of file +var codex=codex||{};codex.notes=function(e){function t(o){if(n[o])return n[o].exports;var r=n[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,t),r.l=!0,r.exports}var n={};return t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:o})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=11)}([function(e,t,n){"use strict";function o(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t0&&void 0!==arguments[0]?arguments[0]:null;return new Promise(function(t){t(window.ipcRenderer.sendSync("notes list - load",e))}).catch(function(e){console.log("Error while loading notes: ",e)})}},{key:"loadFolders",value:function(){window.ipcRenderer.send("folders list - load")}},{key:"newNoteButtonClicked",value:function(){u.default.focusEditor(),codex.notes.note.clear()}},{key:"newFolderButtonClicked",value:function(e){var t=e.target,n=this.newFolderField.querySelector("input");t.classList.add("hide"),this.newFolderField.classList.remove("hide"),n.focus()}},{key:"newFolderInputFilled",value:function(e){if("Enter"===e.key){var t=e.target,n=t.value.trim();if(n){var o=window.ipcRenderer.sendSync("folder - create",n);this.addFolder(o),t.value="",this.newFolderField.classList.add("hide"),this.newFolderButton.classList.remove("hide")}}}},{key:"addMenuItem",value:function(e,t){var n=this;if(!e.title)return void console.warn("Can not add Note to the Aside because it has no title",e);var o=void 0;if(t)o=document.querySelector('[name="js-notes-menu"]');else{if(!this.currentFolder||e.folderId!==this.currentFolder._id)return void console.log("Note added to closed folder: %o",e.folderId);o=document.querySelector('[name="js-folder-notes-menu"]')}var r=o.querySelector('[data-id="'+e._id+'"]');if(r)return void(r.textContent=this.createMenuItemTitle(e.title));var i=this.makeMenuItem(e.title,{id:e._id});o.insertAdjacentElement("afterbegin",i),i.addEventListener("click",function(e){return n.menuItemClicked(e)})}},{key:"addFolder",value:function(e){var t=this;if(!e.title)return void console.warn("Can not add Folder to the Aside because it has no title",e);var n=document.querySelector('[name="js-folders-menu"]'),o=this.makeMenuItem(e.title,{folderId:e._id});n.insertAdjacentElement("afterbegin",o),o.addEventListener("click",function(e){return t.folderClicked(e.target)})}},{key:"makeMenuItem",value:function(e,t){e=this.createMenuItemTitle(e);var n=h.make("li",null,{textContent:e});for(var o in t)n.dataset[o]=t[o];return n}},{key:"createMenuItemTitle",value:function(e){return e.length>68&&(e=e.substring(0,68)+"…"),e}},{key:"removeMenuItem",value:function(e){document.querySelectorAll('[name="js-notes-menu"], [name="js-folder-notes-menu"]').forEach(function(t){var n=t.querySelector('[data-id="'+e+'"]');n&&n.remove()})}},{key:"removeFolderFromMenu",value:function(e){var t=document.querySelector('[name="js-folders-menu"]');if(!t)return!1;var n=t.querySelector('[data-folder-id="'+e+'"]');n&&n.remove()}},{key:"updateFolderTitleInMenu",value:function(e,t){var n=document.querySelector('[name="js-folders-menu"]');if(!n)return!1;var o=n.querySelector('[data-folder-id="'+e+'"]');o&&(o.textContent=t)}},{key:"menuItemClicked",value:function(e){var t=e.target,n=t.dataset.id,o=window.ipcRenderer.sendSync("note - get",{id:n});codex.notes.note.render(o),document.querySelector('[name="editor-view"]').scrollIntoView()}},{key:"folderOpened",value:function(){!this.currentFolder&&this.previouslyOpenedFolder&&(this.currentFolder=new s.default(this.previouslyOpenedFolder)),console.assert(this.currentFolder,"Folder opened but does not initialized"),codex.notes.note.clear()}},{key:"folderClosed",value:function(){this.currentFolder&&(this.previouslyOpenedFolder=this.currentFolder.id),this.currentFolder=null}},{key:"folderClicked",value:function(e){var t=e.dataset.folderId;this.currentFolder=new s.default(t,e.textContent),this.swiper.open()}},{key:"closeFolder",value:function(){this.swiper.close()}},{key:"activateScrollableGradient",value:function(){var e=function(e){var t=e.target,n=e.target.parentNode;t.scrollTop>5?n.classList.add("aside__scrollable--scrolled"):n.classList.remove("aside__scrollable--scrolled")};document.querySelectorAll('[name="js-scrollable"]').forEach(function(t){t.addEventListener("scroll",e)})}}]),e}();t.default=v},function(e,t,n){"use strict";function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n1)for(var n in a)a[n].includes(e[t])&&(this.commands[n]=!0);else this.keys[e[t]]=!0}},{key:"execute",value:function(e){var t=e.ctrlKey||e.metaKey,n=e.shiftKey,o=e.altKey,r={CMD:t,SHIFT:n,ALT:o},a=void 0,s=!0;for(a in this.commands)s=s&&r[a];var l=void 0,u=!0;for(l in this.keys)u=u&&e.keyCode===i[l];s&&u&&this.callback.call(null,e)}},{key:"remove",value:function(){this.element.removeEventListener("keydown",this.executeShortcut)}}]),e}();t.default=s},function(e,t,n){"use strict";function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n30||e.wheelDeltaX<-30;n&&o&&(this.swiped||(this.swiped=!0,this.callback(e.deltaX>0),this.wheelTimeout=window.setTimeout(function(){t.swiped=!1},1e3)))}}]),e}();t.default=i},function(e,t,n){"use strict";function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(e)}}]),e}();t.default=i}]); diff --git a/public/javascripts/app.js b/public/javascripts/app.js index 2d794acb..10428cad 100644 --- a/public/javascripts/app.js +++ b/public/javascripts/app.js @@ -12,6 +12,7 @@ const Editor = require('./editor').default; */ const Aside = require('./aside').default; const Note = require('./note').default; +const Searcher = require('./searcher').default; import User from './user'; import StatusBar from './status-bar'; @@ -46,6 +47,7 @@ let documentReady = () => { codex.notes.user = new User(); codex.notes.statusBar = new StatusBar(); codex.notes.connectionObserver = new ConnectionObserver(); + codex.notes.searcher = new Searcher(); /** * New note saving handler diff --git a/public/javascripts/searcher.js b/public/javascripts/searcher.js new file mode 100644 index 00000000..3c935057 --- /dev/null +++ b/public/javascripts/searcher.js @@ -0,0 +1,26 @@ +/** + * Class for searching through notes + */ +export default class Searcher { + + /** + * @constructor + */ + constructor() { + this.DOM = { + parent: null, + serchField: null + }; + + this.dataset = null; + } + + /** + * Set data where search will be done + * @param {Array} data - array to set + */ + set data( data ) { + this.dataset = data; + } + +}