aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/assets/javascript/core.js
diff options
context:
space:
mode:
authorNathaniel Guse <nathaniel.guse@gmail.com>2013-06-06 14:07:27 -0500
committerNathaniel Guse <nathaniel.guse@gmail.com>2013-06-06 14:07:27 -0500
commit8c3bb26a62ade208d5035015299c2126b15854cb (patch)
tree6e8b789cfad8bd87e86b1df5df4c6aacfc4e6eb7 /phpBB/assets/javascript/core.js
parent4a4a822df888231d2fbea7bf9555604b93f3dc95 (diff)
parent9db0fa88569da1922ac21d9a003b7e577a96c810 (diff)
downloadforums-8c3bb26a62ade208d5035015299c2126b15854cb.tar
forums-8c3bb26a62ade208d5035015299c2126b15854cb.tar.gz
forums-8c3bb26a62ade208d5035015299c2126b15854cb.tar.bz2
forums-8c3bb26a62ade208d5035015299c2126b15854cb.tar.xz
forums-8c3bb26a62ade208d5035015299c2126b15854cb.zip
Merge remote-tracking branch 'remotes/cyberalien/feature/editor-code-tabs' into develop
# By Vjacheslav Trushkin # Via Vjacheslav Trushkin * remotes/cyberalien/feature/editor-code-tabs: [feature/editor-code-tabs] Make inTag function reusable [feature/editor-code-tabs] Check for browser support in function [feature/editor-code-tabs] Apply code editor to everything [feature/editor-code-tabs] Correctly count indentation on first line
Diffstat (limited to 'phpBB/assets/javascript/core.js')
-rw-r--r--phpBB/assets/javascript/core.js159
1 files changed, 159 insertions, 0 deletions
diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js
index e0f1dc1eef..cdba6f9d26 100644
--- a/phpBB/assets/javascript/core.js
+++ b/phpBB/assets/javascript/core.js
@@ -678,5 +678,164 @@ 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
+*
+* 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 || typeof textarea.selectionStart !== 'number') {
+ return;
+ }
+
+ if ($(textarea).data('code-editor') === true) {
+ return;
+ }
+
+ function inTag() {
+ return phpbb.inBBCodeTag(textarea, startTags, endTags);
+ }
+
+ /**
+ * 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