From b2e5cc89344d641394e5c15575379de3c86c0806 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Mon, 20 May 2013 20:29:37 +0300 Subject: [feature/editor-code-tabs] Apply code editor to everything Move code editor from prosilver to assets Apply code editor to subsilver2 Apply code editor to ACP elements where bbcode is allowed PHPBB3-11557 --- phpBB/assets/javascript/core.js | 140 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) (limited to 'phpBB/assets/javascript') diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js index e3f1f9f55b..ba76ba8c10 100644 --- a/phpBB/assets/javascript/core.js +++ b/phpBB/assets/javascript/core.js @@ -663,5 +663,145 @@ phpbb.resizeTextArea = function(items, options) { }); }; +/** +* Adjust textarea to manage code bbcode +* +* This function allows to use tab characters when typing code +* and keeps indentation of previous line of code when adding new +* line while typing code. +* +* Editor's functionality is changed only when cursor is between +* [code] and [/code] bbcode tags. +* +* @param {object} textarea Textarea DOM object to apply editor to +*/ +phpbb.applyCodeEditor = function(textarea) { + // list of allowed start and end bbcode code tags, in lower case + var startTags = ['[code]', '[code='], + startTagsEnd = ']', + endTags = ['[/code]']; + + if ($(textarea).data('code-editor') === true) { + return; + } + + /** + * Check if cursor is currently inside code tag + * + * @return {boolean} True if cursor is in code tag + */ + function inTag() { + var start = textarea.selectionStart, + lastEnd = -1, + lastStart = -1, + i, index, value; + + value = textarea.value.toLowerCase(); + + for (i = 0; i < startTags.length; i++) { + var tagLength = startTags[i].length; + if (start >= tagLength) { + index = value.lastIndexOf(startTags[i], start - tagLength); + lastStart = Math.max(lastStart, index); + } + } + if (lastStart == -1) return false; + + if (start > 0) { + for (i = 0; i < endTags.length; i++) { + index = value.lastIndexOf(endTags[i], start - 1); + lastEnd = Math.max(lastEnd, index); + } + } + + return (lastEnd < lastStart); + } + + /** + * Get line of text before cursor + * + * @param {boolean} stripCodeStart If true, only part of line + * after [code] tag will be returned. + * + * @return {string} Line of text + */ + function getLastLine(stripCodeStart) { + var start = textarea.selectionStart, + value = textarea.value, + index = value.lastIndexOf("\n", start - 1); + + value = value.substring(index + 1, start); + + if (stripCodeStart) { + for (var i = 0; i < startTags.length; i++) { + index = value.lastIndexOf(startTags[i]); + if (index >= 0) { + var tagLength = startTags[i].length; + + value = value.substring(index + tagLength); + if (startTags[i].lastIndexOf(startTagsEnd) != tagLength) { + index = value.indexOf(startTagsEnd); + + if (index >= 0) { + value = value.substr(index + 1); + } + } + } + } + } + + return value; + } + + /** + * Append text at cursor position + * + * @param {string} Text Text to append + */ + function appendText(text) { + var start = textarea.selectionStart, + end = textarea.selectionEnd, + value = textarea.value; + + textarea.value = value.substr(0, start) + text + value.substr(end); + textarea.selectionStart = textarea.selectionEnd = start + text.length; + } + + $(textarea).data('code-editor', true).on('keydown', function(event) { + var key = event.keyCode || event.which; + + // intercept tabs + if (key == 9) { + if (inTag()) { + appendText("\t"); + event.preventDefault(); + return; + } + } + + // intercept new line characters + if (key == 13) { + if (inTag()) { + var lastLine = getLastLine(true), + code = '' + /^\s*/g.exec(lastLine); + + if (code.length > 0) { + appendText("\n" + code); + event.preventDefault(); + return; + } + } + } + }); +}; + +/** +* Apply code editor to all textarea elements with data-bbcode attribute +*/ +$(document).ready(function() { + $('textarea[data-bbcode]').each(function() { + phpbb.applyCodeEditor(this); + }); +}); })(jQuery); // Avoid conflicts with other libraries -- cgit v1.2.1 From 809c51f30d28e5dc1449f817b7563d12e4050f7e Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Mon, 20 May 2013 20:33:51 +0300 Subject: [feature/editor-code-tabs] Check for browser support in function Check for browser support and valid textarea in function instead of before applying function. PHPBB3-11557 --- phpBB/assets/javascript/core.js | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'phpBB/assets/javascript') diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js index ba76ba8c10..1a8beb8224 100644 --- a/phpBB/assets/javascript/core.js +++ b/phpBB/assets/javascript/core.js @@ -681,6 +681,10 @@ phpbb.applyCodeEditor = function(textarea) { startTagsEnd = ']', endTags = ['[/code]']; + if (!textarea || typeof textarea.selectionStart !== 'number') { + return; + } + if ($(textarea).data('code-editor') === true) { return; } -- cgit v1.2.1 From 9db0fa88569da1922ac21d9a003b7e577a96c810 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Wed, 22 May 2013 20:52:15 +0300 Subject: [feature/editor-code-tabs] Make inTag function reusable Change inTag function to reusable JS function that can check for any BBCode PHPBB3-11557 --- phpBB/assets/javascript/core.js | 73 +++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 29 deletions(-) (limited to 'phpBB/assets/javascript') diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js index 1a8beb8224..be4b21abf0 100644 --- a/phpBB/assets/javascript/core.js +++ b/phpBB/assets/javascript/core.js @@ -663,6 +663,49 @@ phpbb.resizeTextArea = function(items, options) { }); }; +/** +* Check if cursor in textarea is currently inside a bbcode tag +* +* @param {object} textarea Textarea DOM object +* @param {Array} startTags List of start tags to look for +* For example, Array('[code]', '[code=') +* @param {Array} endTags List of end tags to look for +* For example, Array('[/code]') +* +* @return {boolean} True if cursor is in bbcode tag +*/ +phpbb.inBBCodeTag = function(textarea, startTags, endTags) { + var start = textarea.selectionStart, + lastEnd = -1, + lastStart = -1, + i, index, value; + + if (typeof start !== 'number') { + return false; + } + + value = textarea.value.toLowerCase(); + + for (i = 0; i < startTags.length; i++) { + var tagLength = startTags[i].length; + if (start >= tagLength) { + index = value.lastIndexOf(startTags[i], start - tagLength); + lastStart = Math.max(lastStart, index); + } + } + if (lastStart == -1) return false; + + if (start > 0) { + for (i = 0; i < endTags.length; i++) { + index = value.lastIndexOf(endTags[i], start - 1); + lastEnd = Math.max(lastEnd, index); + } + } + + return (lastEnd < lastStart); +} + + /** * Adjust textarea to manage code bbcode * @@ -689,36 +732,8 @@ phpbb.applyCodeEditor = function(textarea) { return; } - /** - * Check if cursor is currently inside code tag - * - * @return {boolean} True if cursor is in code tag - */ function inTag() { - var start = textarea.selectionStart, - lastEnd = -1, - lastStart = -1, - i, index, value; - - value = textarea.value.toLowerCase(); - - for (i = 0; i < startTags.length; i++) { - var tagLength = startTags[i].length; - if (start >= tagLength) { - index = value.lastIndexOf(startTags[i], start - tagLength); - lastStart = Math.max(lastStart, index); - } - } - if (lastStart == -1) return false; - - if (start > 0) { - for (i = 0; i < endTags.length; i++) { - index = value.lastIndexOf(endTags[i], start - 1); - lastEnd = Math.max(lastEnd, index); - } - } - - return (lastEnd < lastStart); + return phpbb.inBBCodeTag(textarea, startTags, endTags); } /** -- cgit v1.2.1