diff --git a/Gruntfile.js b/Gruntfile.js index 01020118a..197c493ce 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -86,7 +86,6 @@ module.exports = function(grunt) { 'vendor/assets/bower_components/angular-ui-router/release/angular-ui-router.js', 'vendor/assets/bower_components/lodash/dist/lodash.min.js', 'vendor/assets/bower_components/restangular/dist/restangular.js', - 'vendor/assets/bower_components/marked/lib/marked.js', 'vendor/assets/javascripts/crypto/*.js' ], dest: 'vendor/assets/javascripts/lib.js', diff --git a/app/assets/javascripts/app/frontend/controllers/editor.js b/app/assets/javascripts/app/frontend/controllers/editor.js index 8aee7ed7f..20e1ab420 100644 --- a/app/assets/javascripts/app/frontend/controllers/editor.js +++ b/app/assets/javascripts/app/frontend/controllers/editor.js @@ -16,50 +16,9 @@ angular.module('app.frontend') link:function(scope, elem, attrs, ctrl) { - /** - * Insert 4 spaces when a tab key is pressed, - * only used when inside of the text editor. - * If the shift key is pressed first, this event is - * not fired. - */ - var handleTab = function (event) { - if (!event.shiftKey && event.which == 9) { - event.preventDefault(); - var start = this.selectionStart; - var end = this.selectionEnd; - var spaces = " "; - - // Insert 4 spaces - this.value = this.value.substring(0, start) - + spaces + this.value.substring(end); - - // Place cursor 4 spaces away from where - // the tab key was pressed - this.selectionStart = this.selectionEnd = start + 4; - } - } - var handler = function(event) { if (event.ctrlKey || event.metaKey) { switch (String.fromCharCode(event.which).toLowerCase()) { - case 's': - event.preventDefault(); - $timeout(function(){ - ctrl.saveNote(event); - }); - break; - case 'e': - event.preventDefault(); - $timeout(function(){ - ctrl.clickedEditNote(); - }) - break; - case 'm': - event.preventDefault(); - $timeout(function(){ - ctrl.toggleMarkdown(); - }) - break; case 'o': event.preventDefault(); $timeout(function(){ @@ -71,9 +30,6 @@ angular.module('app.frontend') }; window.addEventListener('keydown', handler); - var element = document.getElementById("note-text-editor"); - element.addEventListener('keydown', handleTab); - scope.$on('$destroy', function(){ window.removeEventListener('keydown', handler); }) @@ -88,14 +44,34 @@ angular.module('app.frontend') } } }) - .controller('EditorCtrl', function ($sce, $timeout, authManager, markdownRenderer, $rootScope, extensionManager, syncManager) { + .controller('EditorCtrl', function ($sce, $timeout, authManager, $rootScope, extensionManager, syncManager, modelManager) { + + window.addEventListener("message", function(){ + console.log("App received message:", event); + if(event.data.status) { + this.postNoteToExternalEditor(); + } else { + var id = event.data.id; + var text = event.data.text; + if(this.note.uuid == id) { + this.note.text = text; + this.changesMade(); + } + } + }.bind(this), false); this.setNote = function(note, oldNote) { - this.editorMode = 'edit'; this.showExtensions = false; this.showMenu = false; this.loadTagsString(); + if(note.editorUrl) { + this.customEditor = this.editorForUrl(note.editorUrl); + this.postNoteToExternalEditor(); + } else { + this.customEditor = null; + } + if(note.safeText().length == 0 && note.dummy) { this.focusTitle(100); } @@ -109,19 +85,38 @@ angular.module('app.frontend') } } - this.hasAvailableExtensions = function() { - return extensionManager.extensionsInContextOfItem(this.note).length > 0; + this.selectedEditor = function(editor) { + this.showEditorMenu = false; + if(editor.default) { + this.customEditor = null; + } else { + this.customEditor = editor; + } + this.note.editorUrl = editor.url; + }.bind(this) + + this.editorForUrl = function(url) { + var editors = modelManager.itemsForContentType("SN|Editor"); + return editors.filter(function(editor){return editor.url == url})[0]; } - this.onPreviewDoubleClick = function() { - this.editorMode = 'edit'; - this.focusEditor(100); + this.postNoteToExternalEditor = function() { + var externalEditorElement = document.getElementById("editor-iframe"); + if(externalEditorElement) { + externalEditorElement.contentWindow.postMessage({text: this.note.text, id: this.note.uuid}, '*'); + } + } + + this.hasAvailableExtensions = function() { + return extensionManager.extensionsInContextOfItem(this.note).length > 0; } this.focusEditor = function(delay) { setTimeout(function(){ var element = document.getElementById("note-text-editor"); - element.focus(); + if(element) { + element.focus(); + } }, delay) } @@ -135,10 +130,6 @@ angular.module('app.frontend') this.showMenu = false; } - this.renderedContent = function() { - return markdownRenderer.renderHtml(markdownRenderer.renderedContentForText(this.note.safeText())); - } - var statusTimeout; this.saveNote = function($event) { @@ -198,7 +189,6 @@ angular.module('app.frontend') } this.onContentFocus = function() { - this.showSampler = false; $rootScope.$broadcast("editorFocused"); } @@ -209,12 +199,7 @@ angular.module('app.frontend') this.toggleFullScreen = function() { this.fullscreen = !this.fullscreen; if(this.fullscreen) { - if(this.editorMode == 'edit') { - // refocus - this.focusEditor(0); - } - } else { - + this.focusEditor(0); } } @@ -222,15 +207,6 @@ angular.module('app.frontend') this.showMenu = false; } - this.toggleMarkdown = function() { - if(this.editorMode == 'preview') { - this.editorMode = 'edit'; - this.focusEditor(0); - } else { - this.editorMode = 'preview'; - } - } - this.deleteNote = function() { if(confirm("Are you sure you want to delete this note?")) { this.remove()(this.note); @@ -238,11 +214,6 @@ angular.module('app.frontend') } } - this.clickedEditNote = function() { - this.editorMode = 'edit'; - this.focusEditor(100); - } - /* Tags */ this.loadTagsString = function() { diff --git a/app/assets/javascripts/app/frontend/models/app/editor.js b/app/assets/javascripts/app/frontend/models/app/editor.js new file mode 100644 index 000000000..2b823d3a5 --- /dev/null +++ b/app/assets/javascripts/app/frontend/models/app/editor.js @@ -0,0 +1,30 @@ +class Editor extends Item { + + constructor(json_obj) { + super(json_obj); + } + + mapContentToLocalProperties(contentObject) { + super.mapContentToLocalProperties(contentObject) + this.url = contentObject.url; + this.name = contentObject.name; + } + + structureParams() { + var params = { + url: this.url, + name: this.name + }; + + _.merge(params, super.structureParams()); + return params; + } + + toJSON() { + return {uuid: this.uuid} + } + + get content_type() { + return "SN|Editor"; + } +} diff --git a/app/assets/javascripts/app/frontend/models/local/itemParams.js b/app/assets/javascripts/app/frontend/models/local/itemParams.js index 396a51bd1..22d7405ce 100644 --- a/app/assets/javascripts/app/frontend/models/local/itemParams.js +++ b/app/assets/javascripts/app/frontend/models/local/itemParams.js @@ -16,7 +16,7 @@ class ItemParams { } paramsForLocalStorage() { - this.additionalFields = ["updated_at", "dirty"]; + this.additionalFields = ["updated_at", "dirty", "editorUrl"]; this.forExportFile = true; return this.__params(); } diff --git a/app/assets/javascripts/app/services/directives/views/editorMenu.js b/app/assets/javascripts/app/services/directives/views/editorMenu.js new file mode 100644 index 000000000..63aab1e70 --- /dev/null +++ b/app/assets/javascripts/app/services/directives/views/editorMenu.js @@ -0,0 +1,73 @@ +class EditorMenu { + + constructor() { + this.restrict = "E"; + this.templateUrl = "frontend/directives/editor-menu.html"; + this.scope = { + callback: "&", + selectedEditor: "=" + }; + } + + controller($scope, modelManager, extensionManager, syncManager) { + 'ngInject'; + + $scope.formData = {}; + + let editorContentType = "SN|Editor"; + + let defaultEditor = { + default: true, + name: "Plain" + } + + $scope.sysEditors = [defaultEditor]; + $scope.editors = modelManager.itemsForContentType(editorContentType); + + $scope.editorForUrl = function(url) { + return $scope.editors.filter(function(editor){return editor.url == url})[0]; + } + + $scope.selectEditor = function(editor) { + $scope.callback()(editor); + } + + $scope.deleteEditor = function(editor) { + if(confirm("Are you sure you want to delete this editor?")) { + modelManager.setItemToBeDeleted(editor); + syncManager.sync(); + _.pull($scope.editors, editor); + } + } + + $scope.submitNewEditorRequest = function() { + var editor = createEditor($scope.formData.url); + modelManager.addItem(editor); + editor.setDirty(true); + syncManager.sync(); + $scope.editors.push(editor); + $scope.formData = {}; + } + + function createEditor(url) { + var name = getParameterByName("name", url); + return modelManager.createItem({ + content_type: editorContentType, + url: url, + name: name + }) + } + + function getParameterByName(name, url) { + name = name.replace(/[\[\]]/g, "\\$&"); + var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"), + results = regex.exec(url); + if (!results) return null; + if (!results[2]) return ''; + return decodeURIComponent(results[2].replace(/\+/g, " ")); + } + } + +} + +angular.module('app.frontend').directive('editorMenu', () => new EditorMenu); diff --git a/app/assets/javascripts/app/services/filters/startFrom.js b/app/assets/javascripts/app/services/filters/startFrom.js index 2ebd72e42..3cf824c4c 100644 --- a/app/assets/javascripts/app/services/filters/startFrom.js +++ b/app/assets/javascripts/app/services/filters/startFrom.js @@ -1,4 +1,3 @@ -// Start from filter angular.module('app.frontend').filter('startFrom', function() { return function(input, start) { return input.slice(start); diff --git a/app/assets/javascripts/app/services/filters/trusted.js b/app/assets/javascripts/app/services/filters/trusted.js new file mode 100644 index 000000000..7bb57b301 --- /dev/null +++ b/app/assets/javascripts/app/services/filters/trusted.js @@ -0,0 +1,5 @@ +angular.module('app.frontend').filter('trusted', ['$sce', function ($sce) { + return function(url) { + return $sce.trustAsResourceUrl(url); + }; +}]); diff --git a/app/assets/javascripts/app/services/markdownRenderer.js b/app/assets/javascripts/app/services/markdownRenderer.js deleted file mode 100644 index b6fd7a749..000000000 --- a/app/assets/javascripts/app/services/markdownRenderer.js +++ /dev/null @@ -1,21 +0,0 @@ -angular.module('app.frontend') - .service('markdownRenderer', function ($sce) { - - marked.setOptions({ - breaks: true, - sanitize: true - }); - - this.renderedContentForText = function(text) { - if(!text || text.length == 0) { - return ""; - } - return marked(text); - } - - this.renderHtml = function(html_code) { - return $sce.trustAsHtml(html_code); - }; - - - }); diff --git a/app/assets/javascripts/app/services/modelManager.js b/app/assets/javascripts/app/services/modelManager.js index ab8ca7f44..9a26cfa14 100644 --- a/app/assets/javascripts/app/services/modelManager.js +++ b/app/assets/javascripts/app/services/modelManager.js @@ -8,7 +8,7 @@ class ModelManager { this.itemChangeObservers = []; this.items = []; this._extensions = []; - this.acceptableContentTypes = ["Note", "Tag", "Extension"]; + this.acceptableContentTypes = ["Note", "Tag", "Extension", "SN|Editor"]; } get allItems() { @@ -121,6 +121,8 @@ class ModelManager { item = new Tag(json_obj); } else if(json_obj.content_type == "Extension") { item = new Extension(json_obj); + } else if(json_obj.content_type == "SN|Editor") { + item = new Editor(json_obj); } else { item = new Item(json_obj); } diff --git a/app/assets/stylesheets/app/_directives.scss b/app/assets/stylesheets/app/_directives.scss deleted file mode 100644 index 8d5f28cc5..000000000 --- a/app/assets/stylesheets/app/_directives.scss +++ /dev/null @@ -1,99 +0,0 @@ -.extension-render-modal { - position: fixed; - margin-left: auto; - margin-right: auto; - left: 0; - right: 0; - top: 0; - bottom: 0; - z-index: 10000; - width: 100vw; - height: 100vh; - background-color: rgba(gray, 0.3); - - .content { - box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); - background-color: white; - width: 700px; - height: 500px; - margin: auto; - padding: 25px; - position: absolute; - top: 0; left: 0; bottom: 0; right: 0; - overflow-y: scroll; - } -} - -.dropdown-menu.contextual-menu { - overflow-y: scroll; - max-height: 85vh; - - .extension { - - &:not(:first-child) { - margin-top: 18px; - } - - .ext-header { - background-color: #ededed; - border-bottom: 1px solid #d3d3d3; - padding-top: 12px; - padding-left: 10px; - padding-bottom: 10px; - position: relative; - - > .name { - font-size: 14px; - } - - > .access { - font-size: 12px; - opacity: 0.5; - font-weight: normal; - margin-top: 2px; - } - - > .loading { - position: absolute; - height: 15px; - width: 15px; - right: 10px; - top: 20px; - } - } - - ul { - margin-top: 0px; - margin-bottom: 0px; - list-style:none; - padding-left:0; - - li { - cursor: pointer; - height: auto; - - &.action { - padding: 10px; - border-bottom: 1px solid rgba(black, 0.1); - background-color: rgba(white, 0.9); - - &:hover { - background-color: rgba(gray, 0.05); - } - - > .name { - font-weight: bold; - font-size: 14px; - } - - > .desc { - font-weight: normal; - opacity: 0.5; - margin-top: 1px; - font-size: 12px; - } - } - } - } - } -} diff --git a/app/assets/stylesheets/app/_editor.scss b/app/assets/stylesheets/app/_editor.scss index 3815f46a0..c122eac3a 100644 --- a/app/assets/stylesheets/app/_editor.scss +++ b/app/assets/stylesheets/app/_editor.scss @@ -13,19 +13,17 @@ .section-title-bar { border-bottom: none !important; - &.fullscreen { - opacity: 0.0; - -webkit-transition: all 300ms ease-in-out; - -moz-transition: all 300ms ease-in-out; - -ms-transition: all 300ms ease-in-out; - -o-transition: all 300ms ease-in-out; - transition: all 300ms ease-in-out; - - &:hover { - opacity: 1.0; - } - - // z-index: -1; + // &.fullscreen { + // opacity: 0.0; + // -webkit-transition: all 300ms ease-in-out; + // -moz-transition: all 300ms ease-in-out; + // -ms-transition: all 300ms ease-in-out; + // -o-transition: all 300ms ease-in-out; + // transition: all 300ms ease-in-out; + // + // &:hover { + // opacity: 1.0; + // } } } @@ -44,6 +42,10 @@ width: 100%; padding-right: 10px; + &.fullscreen { + position: relative; + } + > .title { font-size: 18px; font-weight: bold; @@ -93,15 +95,6 @@ } } - .fullscreen-ghost-bar { - - position: absolute; - width: 20%; - height: 200px; - z-index: 100; - } - - .editor-content { max-height: 100%; @@ -119,19 +112,6 @@ padding-top: 0px; } - .sampler-container { - margin-top: 10px; - padding: 15px; - padding-top: 17px; - font-size: 17px; - // opacity: 0.5; - } - - .sampler { - // opacity: 0.5; - color: rgba(black, 0.3); - } - .editable { font-family: monospace; max-height: 100%; @@ -147,44 +127,9 @@ &.fullscreen { padding: 85px 10%; max-width: 1200px; - display: inline-block;; + display: inline-block; } } - - .preview { - // font-family: monospace; - max-height: 100%; - height: 100%; - line-height: 23px; - overflow-y: scroll; - padding: 0px 15px; - text-align: left; - - &.fullscreen { - padding: 85px 10%; - max-width: 1200px; - display: inline-block;; - } - } - } -} - - -.markdown { - margin-left: 15px; - float: right; - text-align: right; - right: 0; -} - -ol { - list-style-type: decimal; - list-style-position: inside; - -webkit-margin-before: 1em; - -webkit-margin-after: 1em; - -webkit-margin-start: 0px; - -webkit-margin-end: 0px; - -webkit-padding-start: 0px; } .nav-tabs { diff --git a/app/assets/stylesheets/app/_extensions.scss b/app/assets/stylesheets/app/_extensions.scss new file mode 100644 index 000000000..1958abff2 --- /dev/null +++ b/app/assets/stylesheets/app/_extensions.scss @@ -0,0 +1,111 @@ +.extension-render-modal { + position: fixed; + margin-left: auto; + margin-right: auto; + left: 0; + right: 0; + top: 0; + bottom: 0; + z-index: 10000; + width: 100vw; + height: 100vh; + background-color: rgba(gray, 0.3); + + .content { + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + background-color: white; + width: 700px; + height: 500px; + margin: auto; + padding: 25px; + position: absolute; + top: 0; left: 0; bottom: 0; right: 0; + overflow-y: scroll; + } +} + +.menu-section-footer { + background-color: #ededed; + border-top: 1px solid #d3d3d3; + position: relative; + padding: 10px; +} + +.menu-section-header { + background-color: #ededed; + border-bottom: 1px solid #d3d3d3; + position: relative; + padding-top: 12px; + padding-left: 10px; + padding-bottom: 10px; + + + > .title { + font-size: 14px; + } + + > .subtitle { + font-size: 12px; + opacity: 0.5; + font-weight: normal; + margin-top: 2px; + } + + > .loading { + position: absolute; + height: 15px; + width: 15px; + right: 10px; + top: 20px; + } +} + +.dropdown-menu.editor-menu { + overflow-y: scroll; + max-height: 85vh; + + &:not(:first-child) { + margin-top: 18px; + } + + ul { + margin-top: 0px; + margin-bottom: 0px; + list-style:none; + padding-left:0; + + li { + cursor: pointer; + height: auto; + + &.menu-item { + padding: 10px; + border-bottom: 1px solid rgba(black, 0.1); + background-color: rgba(white, 0.9); + + &:hover { + background-color: rgba(gray, 0.05); + } + + &.nonactive { + cursor: default; + &:hover { + background-color: rgba(white, 0.9) !important; + } + } + + .menu-item-title { + font-weight: bold; + font-size: 14px; + } + + .menu-item-subtitle { + font-weight: normal; + opacity: 0.5; + margin-top: 1px; + font-size: 12px; + } + } + } + } +} diff --git a/app/assets/stylesheets/app/_fonts.scss b/app/assets/stylesheets/app/_fonts.scss deleted file mode 100644 index 2d5708715..000000000 --- a/app/assets/stylesheets/app/_fonts.scss +++ /dev/null @@ -1,92 +0,0 @@ -@font-face { - font-family: ProximaNova; - src: font-url('ProximaNova/ProximaNova-Regular.eot'); - src: local('☺'), - font-url('ProximaNova/ProximaNova-Regular.woff') format('woff'), - font-url('ProximaNova/ProximaNova-Regular.ttf') format('truetype'), - font-url('ProximaNova/ProximaNova-Regular.svg') format('svg'); -} - -@font-face { - font-family: ProximaNova; - font-style: italic; - src: font-url('ProximaNova/ProximaNova-Regular-Italic.eot'); - src: local('☺'), - font-url('ProximaNova/ProximaNova-Regular-Italic.woff') format('woff'), - font-url('ProximaNova/ProximaNova-Regular-Italic.ttf') format('truetype'), - font-url('ProximaNova/ProximaNova-Regular-Italic.svg') format('svg'); -} - -@font-face { - font-family: ProximaNova; - font-weight: 600; - src: font-url('ProximaNova/ProximaNova-Semibold.eot'); - src: local('☺'), - font-url('ProximaNova/ProximaNova-Semibold.woff') format('woff'), - font-url('ProximaNova/ProximaNova-Semibold.ttf') format('truetype'), - font-url('ProximaNova/ProximaNova-Semibold.svg') format('svg'); -} - -@font-face { - font-family: ProximaNova; - font-weight: 600; - font-style: italic; - src: font-url('ProximaNova/ProximaNova-Semibold-Italic.eot'); - src: local('☺'), - font-url('ProximaNova/ProximaNova-Semibold-Italic.woff') format('woff'), - font-url('ProximaNova/ProximaNova-Semibold-Italic.ttf') format('truetype'), - font-url('ProximaNova/ProximaNova-Semibold-Italic.svg') format('svg'); -} - -@font-face { - font-family: ProximaNova; - font-weight: bold; - src: font-url('ProximaNova/ProximaNova-Bold.eot'); - src: local('☺'), - font-url('ProximaNova/ProximaNova-Bold.woff') format('woff'), - font-url('ProximaNova/ProximaNova-Bold.ttf') format('truetype'), - font-url('ProximaNova/ProximaNova-Bold.svg') format('svg'); -} - -@font-face { - font-family: ProximaNova; - font-weight: bold; - font-style: italic; - src: font-url('ProximaNova/ProximaNova-Bold-Italic.eot'); - src: local('☺'), - font-url('ProximaNova/ProximaNova-Bold-Italic.woff') format('woff'), - font-url('ProximaNova/ProximaNova-Bold-Italic.ttf') format('truetype'), - font-url('ProximaNova/ProximaNova-Bold-Italic.svg') format('svg'); -} - - -@font-face { - font-family: ProximaNova; - font-weight: 100; - src: font-url('fonts/ProximaNova-Thin.eot'); - src: local('☺'), - font-url('ProximaNova/ProximaNova-Thin.woff') format('woff'), - font-url('ProximaNova/ProximaNova-Thin.ttf') format('truetype'), - font-url('ProximaNova/ProximaNova-Thin.svg') format('svg'); -} - -@font-face { - font-family: ProximaNova; - font-weight: 100; - font-style: italic; - src: font-url('fonts/ProximaNova-Thin-Italic.eot'); - src: local('☺'), - font-url('ProximaNova/ProximaNova-Thin-Italic.woff') format('woff'), - font-url('ProximaNova/ProximaNova-Thin-Italic.ttf') format('truetype'), - font-url('ProximaNova/ProximaNova-Thin-Italic.svg') format('svg'); -} - -@font-face { - font-family: ProximaNova; - font-weight: 900; - src: font-url('ProximaNova/ProximaNova-Extrabold.eot'); - src: local('☺'), - font-url('ProximaNova/ProximaNova-Extrabold.woff') format('woff'), - font-url('ProximaNova/ProximaNova-Extrabold.ttf') format('truetype'), - font-url('ProximaNova/ProximaNova-Extrabold.svg') format('svg'); -} diff --git a/app/assets/stylesheets/app/_header.scss b/app/assets/stylesheets/app/_header.scss index 1df8ef09a..fdeb83a11 100644 --- a/app/assets/stylesheets/app/_header.scss +++ b/app/assets/stylesheets/app/_header.scss @@ -1,145 +1,3 @@ -.pull-left { - float: left !important; -} - -.pull-right { - float: right !important; -} - -.mt-1 { - margin-top: 1px !important; -} - -.mt-2 { - margin-top: 2px !important; -} - -.mt-5 { - margin-top: 5px !important; -} - -.mt-10 { - margin-top: 10px !important; -} - -.mt-15 { - margin-top: 15px !important; -} - -.mt-25 { - margin-top: 25px !important; -} - -.mb-0 { - margin-bottom: 0px !important; -} - -.mb-5 { - margin-bottom: 5px !important; -} - -.mb-10 { - margin-bottom: 10px !important; -} - -.mr-5 { - margin-right: 5px; -} - -.faded { - opacity: 0.5; -} - -.center-align { - text-align: center !important; -} - -.center { - margin-left: auto !important; - margin-right: auto !important; -} - -.block { - display: block !important; -} - -.wrap { - word-wrap: break-word; -} - -.one-line-overflow { - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; -} - -.small-v-space { - height: 6px; - display: block; -} - -.medium-v-space { - height: 12px; - display: block; -} - -.large-v-space { - height: 24px; - display: block; -} - -.small-padding { - padding: 5px !important; -} - -.medium-padding { - padding: 10px !important; -} - -.pb-4 { - padding-bottom: 4px !important; -} - -.pb-6 { - padding-bottom: 6px !important; -} - -.pb-10 { - padding-bottom: 10px !important; -} - -.large-padding { - padding: 22px !important; -} - -.red { - color: red !important; -} - -.blue { - color: $blue-color; -} - -.bold { - font-weight: bold !important; -} - -.italic { - font-style: italic !important; -} - -.normal { - font-weight: normal !important; -} - -.small { - font-size: 10px !important; -} - -.inline { - display: inline-block; -} - .fake-link { font-weight: bold; cursor: pointer; diff --git a/app/assets/stylesheets/app/_main.scss b/app/assets/stylesheets/app/_main.scss index b71e01bac..65b5a2a9c 100644 --- a/app/assets/stylesheets/app/_main.scss +++ b/app/assets/stylesheets/app/_main.scss @@ -29,10 +29,6 @@ $blue-color: #086dd6; } } -[ng\:cloak], [ng-cloak], .ng-cloak { - display: none !important; -} - html, body { font-family: -apple-system, BlinkMacSystemFont, @@ -72,19 +68,6 @@ a { } } -pre { - padding: 16px; - overflow: auto; - line-height: 1.45; - background-color: #f7f7f7; - border-radius: 3px; -} - -code { - word-wrap: break-word; - line-height: 1.45; -} - p { overflow: auto; } diff --git a/app/assets/stylesheets/app/_mostrap.scss b/app/assets/stylesheets/app/_mostrap.scss index 7b540f5b0..2776256a1 100644 --- a/app/assets/stylesheets/app/_mostrap.scss +++ b/app/assets/stylesheets/app/_mostrap.scss @@ -7,15 +7,11 @@ $screen-xs: 480px !default; //** Deprecated `$screen-xs-min` as of v3.2.0 $screen-xs-min: $screen-xs !default; -//** Deprecated `$screen-phone` as of v3.0.1 -$screen-phone: $screen-xs-min !default; // Small screen / tablet //** Deprecated `$screen-sm` as of v3.0.1 $screen-sm: 768px !default; $screen-sm-min: $screen-sm !default; -//** Deprecated `$screen-tablet` as of v3.0.1 -$screen-tablet: $screen-sm-min !default; // Medium screen / desktop //** Deprecated `$screen-md` as of v3.0.1 @@ -67,111 +63,6 @@ $screen-md-max: ($screen-lg-min - 1) !default; *:focus {outline:0;} -.navbar { - min-height: 0px !important; - background-color: white; - height: 80px; - margin-bottom: 0px; - padding-top: 10px; - border-radius: 0px; -} -@media (min-width: 768px) { - .navbar { - border-radius: 4px; - } -} - -.navbar { - position: relative; - min-height: 50px; - margin-bottom: 20px; - border: 1px solid transparent; -} - -@media (min-width: 768px) { - .navbar-header { - float: left; - } -} - -.container > .navbar-header, .container > .navbar-collapse, .container-fluid > .navbar-header, .container-fluid > .navbar-collapse { - margin-right: 0; - margin-left: 0; -} - -@media (min-width: 768px) { - .navbar > .container .navbar-brand, .navbar > .container-fluid .navbar-brand { - // margin-left: -15px; - } -} - -.navbar-brand { - float: left; - padding: 15px 15px; - font-size: 18px; - line-height: 20px; - height: 50px; -} - -@media (min-width: 768px) { - .container > .navbar-header, .container > .navbar-collapse, .container-fluid > .navbar-header, .container-fluid > .navbar-collapse { - // margin-right: 0; - // margin-left: 0; - } -} - -.container > .navbar-header, .container > .navbar-collapse, .container-fluid > .navbar-header, .container-fluid > .navbar-collapse { - // margin-right: -15px; - // margin-left: -15px; -} - -@media (min-width: 768px) { - .navbar-collapse.collapse { - display: block !important; - height: auto !important; - padding-bottom: 0; - overflow: visible !important; - } -} -@media (min-width: 768px) { - .navbar-collapse { - width: auto; - border-top: 0; - box-shadow: none; - } -} - -.navbar-collapse { - overflow-x: visible; - padding-right: 15px; - padding-left: 15px; - border-top: 1px solid transparent; - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); - -webkit-overflow-scrolling: touch; -} - -.collapse { - display: none; -} - -@media (min-width: 768px) { - .navbar-right { - float: right !important; - // margin-right: -15px; - } -} -@media (min-width: 768px) { - .navbar-text { - float: left; - margin-left: 15px; - margin-right: 15px; - } -} -.navbar-text { - margin-top: 15px; - margin-bottom: 15px; -} - .dropup, .dropdown { position: relative; } @@ -232,10 +123,6 @@ button:focus {outline:0;} right: 0; } -.open > .dropdown-menu { - display: block; -} - .btn { display: inline-block; margin-bottom: 0; @@ -262,23 +149,6 @@ button:focus {outline:0;} width: 100%; } -// ul, menu, dir { -// display: block; -// list-style-type: disc; -// -webkit-margin-before: 1em; -// -webkit-margin-after: 1em; -// -webkit-margin-start: 0px; -// -webkit-margin-end: 0px; -// -webkit-padding-start: 40px; -// } - -.dropdown-menu .divider { - height: 1px; - margin: 9px 0; - overflow: hidden; - background-color: #e5e5e5; -} - .panel { position: absolute; right: 0px; @@ -290,59 +160,35 @@ button:focus {outline:0;} background-color: white; } -.panel-top { - bottom: 0px; -} - -.panel-left { - left: -50px; -} - .panel-right { left: 0px; } -.panel-centered { - position: relative; - width: 400px; - margin: 0 auto; - padding: 10px; - text-align: center; -} - .panel-body { padding: 15px; } .form-control { - display: block; - width: 100%; - height: 34px; - padding: 6px 12px; - font-size: 14px; - line-height: 1.42857; - color: #555555; - background-color: #fff; - background-image: none; - border: 1px solid #ccc; - border-radius: 4px; - box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); - -webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; - transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; + display: block; + width: 100%; + height: 34px; + padding: 6px 12px; + font-size: 14px; + line-height: 1.42857; + color: #555555; + background-color: #fff; + background-image: none; + border: 1px solid #ccc; + border-radius: 4px; + box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); + -webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; + transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; } input, button, select, textarea { - font-family: inherit; - font-size: inherit; - line-height: inherit; -} - -.has-feedback { - position: relative; -} - -.form-tag { - margin-bottom: 15px; + font-family: inherit; + font-size: inherit; + line-height: inherit; } .checkbox { @@ -352,63 +198,3 @@ input, button, select, textarea { margin-right: auto; margin-bottom: 10px; } - -.btn-link { - background-color: transparent; - -webkit-box-shadow: none; - box-shadow: none; - text-decoration: none; -} - -.btn-link:hover, .btn-link:focus { - color: #23527c; - text-decoration: underline; - background-color: transparent; -} - -.animated { - -webkit-animation-duration: 1s; - animation-duration: 1s; - -webkit-animation-fill-mode: both; - animation-fill-mode: both; -} - -.animated-fast { - -webkit-animation-duration: 0.5s; - animation-duration: 0.5s; - -webkit-animation-fill-mode: both; - animation-fill-mode: both; -} - -.fadeInDown { - -webkit-animation-name: fadeInDown; - animation-name: fadeInDown; -} - -.fadeIn { - -webkit-animation-name: fadeIn; - animation-name: fadeIn; -} - -@keyframes fadeIn { - 0% { - opacity: 0; - } - - 100% { - opacity: 1; - } -} - -@keyframes fadeInDown { - 0% { - opacity: 0; - -webkit-transform: translate3d(0,-100%,0); - transform: translate3d(0,-100%,0); - } - 100% { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} diff --git a/app/assets/stylesheets/app/_standard.scss b/app/assets/stylesheets/app/_standard.scss new file mode 100644 index 000000000..bf5e098b1 --- /dev/null +++ b/app/assets/stylesheets/app/_standard.scss @@ -0,0 +1,269 @@ +.pull-left { + float: left !important; +} + +.pull-right { + float: right !important; +} + +.mt-1 { + margin-top: 1px !important; +} + +.mt-2 { + margin-top: 2px !important; +} + +.mt-5 { + margin-top: 5px !important; +} + +.mt-10 { + margin-top: 10px !important; +} + +.mt-15 { + margin-top: 15px !important; +} + +.mt-20 { + margin-top: 20px !important; +} + +.mt-25 { + margin-top: 25px !important; +} + +.mt-50 { + margin-top: 50px !important; +} + +.mt-100 { + margin-top: 100px !important; +} + +.mb-0 { + margin-bottom: 0px !important; +} + +.mb-5 { + margin-bottom: 5px !important; +} + +.mb-10 { + margin-bottom: 10px !important; +} + +.mr-5 { + margin-right: 5px; +} + +.mr-10 { + margin-right: 10px; +} + +.mr-20 { + margin-right: 20px; +} + +.pb-0 { + padding-bottom: 0px !important; +} + +.faded { + opacity: 0.5; +} + +.center-align { + text-align: center !important; +} + +.center { + margin-left: auto !important; + margin-right: auto !important; +} + +.block { + display: block !important; +} + +.wrap { + word-wrap: break-word; +} + +.one-line-overflow { + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; +} + +.small-v-space { + height: 6px; + display: block; +} + +.medium-v-space { + height: 12px; + display: block; +} + +.large-v-space { + height: 24px; + display: block; +} + +.small-padding { + padding: 5px !important; +} + +.medium-padding { + padding: 10px !important; +} + +.pb-4 { + padding-bottom: 4px !important; +} + +.pb-6 { + padding-bottom: 6px !important; +} + +.pb-10 { + padding-bottom: 10px !important; +} + +.large-padding { + padding: 22px !important; +} + +.red { + color: red !important; +} + +.bold { + font-weight: bold !important; +} + +.normal { + font-weight: normal !important; +} + +.small { + font-size: 10px !important; +} + +.medium { + font-size: 14px !important; +} + +.inline { + display: inline-block; + + &.top { + vertical-align: top; + } + + &.middle { + vertical-align: middle; + } +} + +button { + cursor: pointer; +} + +input.form-control { + margin-bottom: 10px; + border-radius: 0px; + min-height: 39px; + font-size: 14px; + padding-left: 6px; +} + +button { + border: none; + + @mixin wide-button() { + font-weight: bold; + text-align: center; + padding: 10px; + font-size: 16px; + // min-width: 200px; + + &:hover { + text-decoration: underline; + } + } + + &.black { + @include wide-button(); + background-color: black; + color: white; + } + + &.white { + @include wide-button(); + background-color: white; + color: black; + border: 1px solid rgba(gray, 0.2); + } +} + + +.gray-bg { + background-color: #f6f6f6; + border: 1px solid #f2f2f2; +} + +.white-bg { + background-color: white; + border: 1px solid rgba(gray, 0.2); +} + +.col-container { + // white-space: nowrap; +} + +@mixin col() { + display: inline-block; + vertical-align: top; + white-space: normal; +} + +.col-10 { + width: 10%; + @include col(); +} + +.col-15 { + width: 15%; + @include col(); +} + +.col-20 { + width: 20%; + @include col(); +} + +.col-45 { + width: 45%; + @include col(); +} + +.col-50 { + width: 50%; + @include col(); +} + +.col-80 { + width: 80%; + @include col(); +} + +.relative { + position: relative !important; +} + +.absolute { + position: absolute !important; +} diff --git a/app/assets/stylesheets/frontend.css.scss b/app/assets/stylesheets/frontend.css.scss index bfe290297..904cb614a 100644 --- a/app/assets/stylesheets/frontend.css.scss +++ b/app/assets/stylesheets/frontend.css.scss @@ -1,5 +1,6 @@ $dark-gray: #2e2e2e; +@import "app/standard"; @import "app/mostrap"; @import "app/main"; @import "app/common"; @@ -7,41 +8,4 @@ $dark-gray: #2e2e2e; @import "app/tags"; @import "app/notes"; @import "app/editor"; -@import "app/directives"; - -@font-face { - font-family: 'icomoon'; - src: url('icomoon/icomoon.eot'); - src: url('icomoon/icomoon.eot') format('embedded-opentype'), - url('icomoon/icomoon.ttf') format('truetype'), - url('icomoon/icomoon.woff') format('woff'), - url('icomoon/icomoon.svg') format('svg'); - font-weight: normal; - font-style: normal; -} - -[class^="icon-"], [class*=" icon-"] { - /* use !important to prevent issues with browser extensions that change fonts */ - font-family: 'icomoon' !important; - speak: none; - font-style: normal; - font-weight: normal; - font-variant: normal; - text-transform: none; - // line-height: 1; - - /* Better Font Rendering =========== */ - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - - line-height: 10px; -} - -.inline-icon { - display: inline-block; - margin-left: 2px; -} - -.icon-markdown:before { - content: "\e901"; -} +@import "app/extensions"; diff --git a/app/assets/templates/frontend/directives/contextual-menu.html.haml b/app/assets/templates/frontend/directives/contextual-menu.html.haml index 725b56474..6fbfaa9aa 100644 --- a/app/assets/templates/frontend/directives/contextual-menu.html.haml +++ b/app/assets/templates/frontend/directives/contextual-menu.html.haml @@ -1,21 +1,21 @@ -%ul.dropdown-menu.dropdown-menu-left.nt-dropdown-menu.dark.contextual-menu +%ul.dropdown-menu.dropdown-menu-left.nt-dropdown-menu.dark.editor-menu .extension{"ng-repeat" => "extension in extensions"} - .ext-header - .name {{extension.name}} - .access + .menu-section-header + .title {{extension.name}} + .subtitle Can access your data %strong {{accessTypeForExtension(extension)}} .spinner.loading{"ng-if" => "extension.loading"} %ul - %li.action{"ng-repeat" => "action in extension.actionsWithContextForItem(item)", "ng-click" => "executeAction(action, extension)"} - .name {{action.label}} - .desc {{action.desc}} + %li.menu-item{"ng-repeat" => "action in extension.actionsWithContextForItem(item)", "ng-click" => "executeAction(action, extension)"} + .menu-item-title {{action.label}} + .menu-item-subtitle {{action.desc}} %div{"ng-if" => "action.showNestedActions"} %ul.mt-10 - %li.action.white-bg{"ng-repeat" => "subaction in action.subactions", "ng-click" => "executeAction(subaction, extension); $event.stopPropagation()", "style" => "margin-top: -1px;"} - .name {{subaction.label}} - .desc {{subaction.desc}} + %li.menu-item.white-bg{"ng-repeat" => "subaction in action.subactions", "ng-click" => "executeAction(subaction, extension); $event.stopPropagation()", "style" => "margin-top: -1px;"} + .menu-item-title {{subaction.label}} + .menu-item-subtitle {{subaction.desc}} %span{"ng-if" => "subaction.running"} .spinner{"style" => "margin-top: 3px;"} diff --git a/app/assets/templates/frontend/directives/editor-menu.html.haml b/app/assets/templates/frontend/directives/editor-menu.html.haml new file mode 100644 index 000000000..f7509a45c --- /dev/null +++ b/app/assets/templates/frontend/directives/editor-menu.html.haml @@ -0,0 +1,23 @@ +%ul.dropdown-menu.dropdown-menu-left.nt-dropdown-menu.dark.editor-menu + .menu-section-header + .title System Editors + %ul + %li.menu-item{"ng-repeat" => "editor in sysEditors", "ng-click" => "selectEditor(editor)"} + %span.pull-left.mr-10{"ng-if" => "!selectedEditor"} ✓ + .menu-item-title.pull-left {{editor.name}} + + %div{"ng-if" => "editors.length > 0"} + .menu-section-header + .title External Editors + .subtitle Can access your current note decrypted. + %ul + %li.menu-item{"ng-repeat" => "editor in editors", "ng-click" => "selectEditor(editor)"} + %span.pull-left.mr-10{"ng-if" => "selectedEditor == editor"} ✓ + .pull-left{"style" => "width: 60%"} + .menu-item-title {{editor.name}} + .menu-item-subtitle.wrap {{editor.url}} + .pull-right + %button.white.medium.inline.top{"style" => "width: 50px; height: 40px;", "ng-click" => "deleteEditor(editor); $event.stopPropagation();"} ☓ + .menu-section-footer.mt-10 + %input.form-control{"ng-model" => "formData.url", "placeholder" => "Add new editor via URL", "ng-keyup" => "$event.keyCode == 13 && submitNewEditorRequest()"} + %a.block{"href" => ""} Available Editors diff --git a/app/assets/templates/frontend/editor.html.haml b/app/assets/templates/frontend/editor.html.haml index 7b5242531..2556b403c 100644 --- a/app/assets/templates/frontend/editor.html.haml +++ b/app/assets/templates/frontend/editor.html.haml @@ -21,11 +21,17 @@ %li{"ng-click" => "ctrl.selectedMenuItem(); ctrl.toggleFullScreen()"} .text Toggle Fullscreen .shortcut Cmd + O - %li{"ng-click" => "ctrl.selectedMenuItem(); ctrl.toggleMarkdown()"} - .text Toggle Markdown Preview - .shortcut Cmd + M %li{"ng-click" => "ctrl.deleteNote()"} .text Delete + + %li.sep + %li.dropdown{"click-outside" => "ctrl.showEditorMenu = false;", "is-open" => "ctrl.showEditorMenu"} + %a.dropdown-toggle{"ng-click" => "ctrl.showEditorMenu = !ctrl.showEditorMenu; ctrl.showMenu = false;"} + Editor + %span.caret + %span.sr-only + %editor-menu{"ng-if" => "ctrl.showEditorMenu", "callback" => "ctrl.selectedEditor", "selected-editor" => "ctrl.customEditor"} + %li.sep %li.dropdown{"ng-if" => "ctrl.hasAvailableExtensions()", "click-outside" => "ctrl.showExtensions = false;", "is-open" => "ctrl.showExtensions"} %a.dropdown-toggle{"ng-click" => "ctrl.showExtensions = !ctrl.showExtensions; ctrl.showMenu = false;"} @@ -34,13 +40,7 @@ %span.sr-only %contextual-extensions-menu{"ng-if" => "ctrl.showExtensions", "item" => "ctrl.note"} - .markdown.icon{"ng-if" => "ctrl.editorMode == 'preview'", "ng-click" => "ctrl.showMarkdown = !ctrl.showMarkdown"} - .icon-markdown - .panel.panel-default.info-panel{"ng-if" => "ctrl.showMarkdown"} - .panel-body{"style" => "text-align: center; color: black;"} - This editor is Markdown enabled. - .editor-content{"ng-class" => "{'fullscreen' : ctrl.fullscreen }"} - %textarea.editable#note-text-editor{"ng-class" => "{'fullscreen' : ctrl.fullscreen }", "ng-show" => "ctrl.editorMode == 'edit'", "ng-model" => "ctrl.note.text", + %iframe#editor-iframe{"ng-if" => "ctrl.customEditor", "ng-src" => "{{ctrl.customEditor.url | trusted}}", "frameBorder" => "0", "style" => "width: 100%; height: 100%; z-index: 1000; float: left;"} + %textarea.editable#note-text-editor{"ng-if" => "!ctrl.customEditor", "ng-class" => "{'fullscreen' : ctrl.fullscreen }", "ng-model" => "ctrl.note.text", "ng-change" => "ctrl.contentChanged()", "ng-click" => "ctrl.clickedTextArea()", "ng-focus" => "ctrl.onContentFocus()"} - .preview{"ng-class" => "{'fullscreen' : ctrl.fullscreen }", "ng-if" => "ctrl.editorMode == 'preview'", "ng-bind-html" => "ctrl.renderedContent()", "ng-dblclick" => "ctrl.onPreviewDoubleClick()"} diff --git a/bower.json b/bower.json index dd0074806..fa8d65b8f 100644 --- a/bower.json +++ b/bower.json @@ -9,8 +9,7 @@ "dependencies": { "angular": "1.6.1", "angular-ui-router": "^0.3.2", - "restangular": "^1.6.1", - "marked": "0.3.6" + "restangular": "^1.6.1" }, "resolutions": { "angular": "1.6.1" diff --git a/vendor/assets/fonts/icomoon/icomoon.eot b/vendor/assets/fonts/icomoon/icomoon.eot deleted file mode 100755 index b972d618a..000000000 Binary files a/vendor/assets/fonts/icomoon/icomoon.eot and /dev/null differ diff --git a/vendor/assets/fonts/icomoon/icomoon.svg b/vendor/assets/fonts/icomoon/icomoon.svg deleted file mode 100755 index 1d0728296..000000000 --- a/vendor/assets/fonts/icomoon/icomoon.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - -Generated by IcoMoon - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/assets/fonts/icomoon/icomoon.ttf b/vendor/assets/fonts/icomoon/icomoon.ttf deleted file mode 100755 index 1f84022e6..000000000 Binary files a/vendor/assets/fonts/icomoon/icomoon.ttf and /dev/null differ diff --git a/vendor/assets/fonts/icomoon/icomoon.woff b/vendor/assets/fonts/icomoon/icomoon.woff deleted file mode 100755 index 8a59709f5..000000000 Binary files a/vendor/assets/fonts/icomoon/icomoon.woff and /dev/null differ