-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
editor settings, new paragrath and new line, one instance add buttons #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| # --- proj files --- | ||
| .DS_Store | ||
| Thumbs.db | ||
| /.idea/ | ||
| /*.sublime-project | ||
| /*.sublime-workspace |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,67 +3,75 @@ | |
| * @author Savchenko Peter (vk.com/specc) | ||
| */ | ||
|
|
||
| var ce = function(textareaId) { | ||
| var ce = function(settings) { | ||
|
|
||
| this.resultTextarea = document.getElementById(textareaId); | ||
| this.resultTextarea = document.getElementById("codex_editor"); | ||
|
|
||
| if (typeof this.resultTextarea == undefined || this.resultTextarea == null ){ | ||
|
|
||
| console.warn('Textarea not found with ID %o', textareaId); | ||
| console.warn('Textarea not found with ID %o', this.textareaId); | ||
| return this; | ||
| } | ||
|
|
||
| /* Prepare settings */ | ||
| if ("undefined" == typeof settings) settings = this.defaultSettings; | ||
| else { | ||
| // todo just merge settings with defaults | ||
| } | ||
|
|
||
| this.toolbarOpened = false; | ||
| this.tools = ['header', 'picture', 'list', 'quote', 'code', 'twitter', 'instagram', 'smile']; | ||
| settings.tools = settings.tools || this.allTools; | ||
| this.settings = settings; | ||
|
|
||
| /** Some configurations */ | ||
| this.BUTTONS_TOGGLED_CLASSNANE = 'buttons_toggled'; | ||
| this.key = { TAB: 9, ENTER: 13, BACKSPACE: 8, DELETE: 46, DOWN: 40, SPACE: 32, ESC: 27, CTRL: 17, META: 91, SHIFT: 16, ALT: 18 }; | ||
|
|
||
| /** Making a wrapper and interface */ | ||
| this.makeInterface(); | ||
|
|
||
| /** Bind all events */ | ||
| this.bindEvents(); | ||
|
|
||
| } | ||
| }; | ||
|
|
||
| // All posible tools | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Слово Tools не понятно простому смертному, стоит упомянуть, что это виды блоков, которые можно добавить |
||
| ce.prototype.allTools = ['header', 'picture', 'list', 'quote', 'code', 'twitter', 'instagram', 'smile']; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Зачем всё делать через прототип? На сколько я вижу в спецификации мозилы — это свойство достаточно медленное и вообще, зачем здесь его использовать? Может я что-то не понимаю?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. может константы и, так сказать статические элементы, можно делать без прототипа. А все что касается работы в экземплярах класса - делается через прототип для правильного замыкания. Ну примерно так, может я не совсем точен в терминологии. @neSpecc что скажешь? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. А почему нельзя всё делать в виде модульной структуры, есть же специальные паттерны программирования на JS. А здесь просто огромный нестуктурированный блок кода.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. можно подробнее об этом. примеры, ссылки. я пока не очень понимаю что ты хотел бы видеть. |
||
|
|
||
| // Default settings configuration | ||
| ce.prototype.defaultSettings = { | ||
|
|
||
| }; | ||
|
|
||
| // Add this class when open tool bar for css animation | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Такое ощущение, что это нужно будет делать самому
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. не понял There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Коментарий гласит: "Добавьте этот класс когда будет открыт тулбар для анимации с помощью CSS". |
||
| ce.prototype.BUTTONS_TOGGLED_CLASSNANE = 'buttons_toggled'; | ||
|
|
||
| // Default tool bar is closed | ||
| ce.prototype.toolbarOpened = false; | ||
|
|
||
| // Key event constants | ||
| ce.prototype.key = { TAB: 9, ENTER: 13, BACKSPACE: 8, DELETE: 46, DOWN: 40, SPACE: 32, ESC: 27, CTRL: 17, META: 91, SHIFT: 16, ALT: 18 }; | ||
|
|
||
| /** | ||
| * Editor interface drawing | ||
| * @use this.tools to get necessary items | ||
| * @todo get tools from user inital-settings | ||
| * Editor interface drawing | ||
| * calls one time in editor constructor | ||
| */ | ||
| ce.prototype.makeInterface = function () { | ||
|
|
||
| var wrapper = this.make.editorWrapper(), | ||
| firstNode = this.make.node(null, 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Porro quia nihil repellendus aut cupiditate reprehenderit sapiente magnam nobis doloremque eaque! Sint nobis assumenda nisi ducimus minima illo tenetur, cumque facilis.' ), | ||
| toolbar = this.make.toolbar(), | ||
| button; | ||
| firstNode = this.make.textNode('Lorem ipsum dolor sit amet, consectetur adipisicing elit. Porro quia nihil repellendus aut cupiditate reprehenderit sapiente magnam nobis doloremque eaque! Sint nobis assumenda nisi ducimus minima illo tenetur, cumque facilis.' ), | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Что это, а главное нафига? Я правильно понимаю, что это то, чем будет заполнен первый текстовый блок, когда будет открыт редактор — если да, то это отстой. Я открываю редактор затем чтобы начать писать свои мысли и я очень хотел бы, чтобы он встречал меня дружелюбной мигающей стрелочкой с помощью которой можно сразу начать что-нибудь вводить There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Вместо рыбы лучше показать, как сделать так, чтобы редактор показывал уже готовую статью с помощью переданной извне переменной, но думаю, что это можно будет сделать в отдельной задаче
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. так и будет. Эта рыба для демонстрации возможности There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Стоит написать, что этот код тестовый и будет удалён. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. И вообще, у нас есть отдельная задача на это #5, я всё же считаю, что внутри текста редактора не должно быть никаких тестовых данных. |
||
| toolbar = this.make.toolbar(); | ||
|
|
||
| for (var i = 0; i < this.tools.length; i++) { | ||
| button = this.make.toolbarButton(this.tools[i]); | ||
| toolbar.appendChild(button); | ||
| }; | ||
| this.wrapper = wrapper; | ||
| this.toolbar = toolbar; | ||
|
|
||
| /** | ||
| * Add toolbar to node | ||
| * @todo make toolbar rendering once | ||
| */ | ||
| firstNode.appendChild(toolbar); | ||
| this.toolbarButtons = this.make.toolbarButtons(this.allTools, this.settings.tools); | ||
|
|
||
| /** Add first node */ | ||
| /** Add first node and tool bar*/ | ||
| wrapper.appendChild(firstNode); | ||
| wrapper.appendChild(toolbar); | ||
|
|
||
| /** Insert Editor after initial textarea. Hide textarea */ | ||
| this.resultTextarea.parentNode.insertBefore(wrapper, this.resultTextarea.nextSibling); | ||
| this.resultTextarea.hidden = true; | ||
|
|
||
| /** Set auto focus */ | ||
| var contentEditable = firstNode.getElementsByClassName('ce_node_content'); | ||
| contentEditable.length && contentEditable[0].focus(); | ||
|
|
||
| } | ||
| this.focusNode(firstNode); | ||
| }; | ||
|
|
||
| /** | ||
| * All events binds in one place | ||
|
|
@@ -77,7 +85,18 @@ ce.prototype.bindEvents = function () { | |
| _this.globalKeydownCallback(event); | ||
| }, false ); | ||
|
|
||
| } | ||
| }; | ||
|
|
||
| /** | ||
| * Sets focus to node conteneditable child | ||
| * todo depending on node type | ||
| */ | ||
| ce.prototype.focusNode = function (node) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. фокусируй узел. может |
||
|
|
||
| var contentEditable = node.getElementsByClassName('ce_node_content'); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. класс лучше куда-то вынести, в константу например. Тем более, что он еще используется при создании узла
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. а лучше вообще этот content выпилить |
||
| contentEditable.length && contentEditable[0].focus(); | ||
|
|
||
| }; | ||
|
|
||
| /** | ||
| * All window keydowns handles here | ||
|
|
@@ -89,40 +108,69 @@ ce.prototype.globalKeydownCallback = function (event) { | |
| case this.key.ENTER : this.enterKeyPressed(event); break; // Enter | ||
| } | ||
|
|
||
| } | ||
| }; | ||
|
|
||
| /** | ||
| * @todo: check if currently focused in contenteditable element | ||
| * | ||
| */ | ||
| ce.prototype.tabKeyPressed = function(event) { | ||
|
|
||
| var toolbar = document.getElementsByClassName('add_buttons'); | ||
| // check if currently focused in contenteditable element | ||
| if ("BODY" == event.target.tagName) return; | ||
|
|
||
| if ( !toolbar[0].className.includes(this.BUTTONS_TOGGLED_CLASSNANE) ){ | ||
| toolbar[0].className += ' ' + this.BUTTONS_TOGGLED_CLASSNANE; | ||
| this.toolbarOpened = true; | ||
| } else { | ||
| toolbar[0].className = toolbar[0].className.replace(this.BUTTONS_TOGGLED_CLASSNANE, ''); | ||
| this.toolbarOpened = false | ||
| } | ||
| var toolbar = event.target.parentNode.nextSibling, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. надежно ли это
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. должно быть. заодно проверим. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Это плохой подход, такой вопрос будет возникать у каждого человека, который увидит эту строчку. Вот как раз здесь стоит написать комментарий
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. а что писать-то в комментарии?) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ну типо, что мы проверяем и не уверены, что это надёжно. Чтобы знать, где искать багу если что
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. а нельзя как-то по другому обратиться к тулбару?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. мы вынесли кнопку добавления из узла, и она идет следом за узлом. можно узлам задавать ИД и искать кнопку добавления с данным префиксом?
С уважением,
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. в Пт придумали крутое решение - будем хранить виртуальную структуру узлов редактора и их параметры. Т.о. блок с кнопками добавления можно будет получить через ссылку в параметрах блока, примерно так: this - editor object |
||
| _this = this; | ||
|
|
||
| toolbar.appendChild(this.toolbarButtons); | ||
|
|
||
| // repair buttons animation - just add css class async | ||
| setTimeout(function () { | ||
|
|
||
| if ( !toolbar.className.includes(_this.BUTTONS_TOGGLED_CLASSNANE) ){ | ||
| toolbar.className += ' ' + _this.BUTTONS_TOGGLED_CLASSNANE; | ||
| _this.toolbarOpened = true; | ||
| } else { | ||
| toolbar.className = toolbar.className.replace(_this.BUTTONS_TOGGLED_CLASSNANE, ''); | ||
| _this.toolbarOpened = false | ||
| } | ||
|
|
||
| }); | ||
|
|
||
| event.preventDefault(); | ||
|
|
||
| } | ||
| }; | ||
|
|
||
| /** | ||
| * Handle Enter key. Adds new Node; | ||
| */ | ||
| ce.prototype.enterKeyPressed = function(event) { | ||
|
|
||
| console.log('ENTER'); | ||
| if (event.shiftKey){ | ||
| document.execCommand('insertHTML', false, '<br><br>'); | ||
| } else { | ||
| var newNode = this.make.textNode(), | ||
| toolbar = this.make.toolbar(); | ||
|
|
||
| /** Add node */ | ||
| this.wrapper.insertBefore(newNode, event.target.parentNode.nextSibling); | ||
|
|
||
| /** Add toolbar to node */ | ||
| this.wrapper.insertBefore(toolbar, newNode); | ||
|
|
||
| } | ||
| /** Set auto focus */ | ||
| var contentEditable = newNode.getElementsByClassName('ce_node_content'); | ||
| contentEditable.length && contentEditable[0].focus(); | ||
| } | ||
|
|
||
| event.preventDefault(); | ||
| }; | ||
|
|
||
| /** | ||
| * Creates HTML elements | ||
| */ | ||
| ce.prototype.make = function (window) { | ||
| ce.prototype.make = function () { | ||
|
|
||
| var _this = this; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. боюсь, здесь все равно не будет того, чего ты хочешь. То есть экземпляра. Тут будет window
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. да, я уже отказался от этого. это не используется. надо удалить.
С уважением, |
||
|
|
||
| /** Empty toolbar with toggler */ | ||
| function toolbar () { | ||
|
|
@@ -133,12 +181,13 @@ ce.prototype.make = function (window) { | |
|
|
||
| /** Toggler button*/ | ||
| bar.innerHTML = '<span class="toggler">' + | ||
| '<i class="ce_icon-plus-circled-1"></i>'+ | ||
| '<i class="plus_btn ce_icon-plus-circled-1"></i>'+ | ||
| '</span>'; | ||
| return bar; | ||
|
|
||
| } | ||
|
|
||
| // Creates one button with given type | ||
| function toolbarButton (type) { | ||
|
|
||
| var button = document.createElement('button'); | ||
|
|
@@ -147,13 +196,33 @@ ce.prototype.make = function (window) { | |
| button.innerHTML = '<i class="ce_icon-' + type + '"></i>'; | ||
|
|
||
| return button; | ||
|
|
||
| } | ||
|
|
||
| // Creates all tool bar buttons from editor settings | ||
| // allTools, usedTools - needs becose cant get them from editor object - bad context | ||
| function toolbarButtons (allTools, usedTools) { | ||
|
|
||
| var toolbarButtons = document.createElement("span"); | ||
|
|
||
| toolbarButtons.classList.add("buttons"); | ||
|
|
||
| // Walk base buttons list - save buttons origin sorting | ||
| allTools.forEach(function(item) { | ||
|
|
||
| if (usedTools.indexOf(item) >= 0) toolbarButtons.appendChild( this.toolbarButton(item) ); | ||
|
|
||
| }, this); | ||
|
|
||
| return toolbarButtons; | ||
|
|
||
| } | ||
|
|
||
| /** | ||
| * Paragraph node | ||
| * @todo set unique id with prefix | ||
| */ | ||
| function node (id, content){ | ||
| function textNode (content){ | ||
|
|
||
| var node = document.createElement('div'); | ||
|
|
||
|
|
@@ -173,15 +242,16 @@ ce.prototype.make = function (window) { | |
| } | ||
|
|
||
| var ceMake = function () { | ||
| this.toolbar = toolbar; | ||
| this.toolbarButton = toolbarButton; | ||
| this.node = node; | ||
| this.editorWrapper = editorWrapper; | ||
| } | ||
| this.toolbar = toolbar; | ||
| this.toolbarButtons = toolbarButtons; | ||
| this.toolbarButton = toolbarButton; | ||
| this.textNode = textNode; | ||
| this.editorWrapper = editorWrapper; | ||
| }; | ||
|
|
||
| return new ceMake(); | ||
|
|
||
| }(this) | ||
| }(); | ||
|
|
||
|
|
||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
а почему ты сперва пишешь то, с чем сравниваешь, а потом то, что сравниваешь?
Мне кажется, так воспринимается хуже и дольше — мы же читаем слева направо, а у тебя приходится смотреть справа налево
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
так невозможно случайно опечататься и присвоить значени вместо сравнения, например
if (typeof settings = "undefined") settings = this.defaultSettings; хотя в данном конкретном случае это вызовет ошибку)
но я про такую ситуацию
if ($someVar = "undefined") settings = this.defaultSettings;
С уважением,
Марк Дерманов
моб: +7 (921) 769-56-55
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
это не оправданная порча кода, на мой взгляд. Опечатываются так только первокурсники. Да и потом, они все равно могут написать = вместо ==
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
это известная рекомендация под названием "стиль Йоды"
https://ru.wikipedia.org/wiki/%D0%A3%D1%81%D0%BB%D0%BE%D0%B2%D0%B8%D1%8F_%D0%99%D0%BE%D0%B4%D1%8B
я не знал, что это плохо
С уважением,
Марк Дерманов
моб: +7 (921) 769-56-55
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
я понял идею. Ну смотри сам, мне кажется, стремная штука