]> git.ipfire.org Git - ipfire.org.git/blame - src/static/js/editor.js
wiki: Add editor elements to insert headlines
[ipfire.org.git] / src / static / js / editor.js
CommitLineData
feeace6e
MT
1class Editor {
2 constructor(parent) {
3 this.parent = $(parent);
4
5 // Get the textarea
6 this.textarea = this.parent.find("textarea");
7
8 // Make the textarea magic
9 this.activateTextArea();
10
11 // Bind all keys
12 this.bindKeys();
13
14 console.log("Editor initialised for " + this.parent);
15 }
16
17 activateTextArea() {
18 var editor = this;
19
20 // Remember any selected text
18c36357 21 this.textarea.on("select keyup click", function(e) {
feeace6e
MT
22 editor.selection = {
23 start : this.selectionStart,
24 end : this.selectionEnd,
18c36357
MT
25 text : this.value.slice(this.selectionStart, this.selectionEnd),
26 length: this.selectionEnd - this.selectionStart,
feeace6e
MT
27 };
28
29 console.debug("Something got selected:");
30 console.debug(editor.selection);
31 })
32 }
33
34 bindKeys() {
18c36357 35 // Typography
feeace6e
MT
36 this.parent.find("#bold").click(this.bold.bind(this));
37 this.parent.find("#italic").click(this.italic.bind(this));
18c36357
MT
38
39 // Headlines
40 this.parent.find("#headline").click(this.headline.bind(this));
41 this.parent.find("#headline-down").click(this.headline_down.bind(this));
42 this.parent.find("#headline-up").click(this.headline_up.bind(this));
feeace6e
MT
43 }
44
45 // Functions to modify the text
46
47 replaceSelection(replacement) {
48 var text = this.textarea.val();
49
50 text = text.slice(0, this.selection.start) + replacement + text.slice(this.selection.end);
51
52 // Write text to textarea
53 this.textarea.val(text);
54 }
55
18c36357
MT
56 insertAtCursor(insertion) {
57 this.replaceSelection(insertion);
58 }
59
feeace6e
MT
60 bold() {
61 console.debug("Converting into bold: " + this.selection.text);
62 this.replaceSelection("**" + this.selection.text + "**");
63 }
64
65 italic() {
66 console.debug("Converting into italic: " + this.selection.text);
67 this.replaceSelection("*" + this.selection.text + "*");
68 }
18c36357
MT
69
70 // Headlines
71
72 findLevel() {
73 // Get all text between start and cursor position
74 var text = this.textarea.val().slice(0, this.selection.start);
75
76 // Split it in lines and reverse
77 var lines = text.split("\n");
78 lines.reverse();
79
80 for (var line of lines) {
81 console.debug(line);
82
83 // Return the number of # found in the nearest headline
84 var match = line.match("^(#+)");
85 if (match) {
86 return match[1].length;
87 }
88 }
89
90 // If nothing was found, we are on level one
91 return 1;
92 }
93
94 insertHeadline(offset) {
95 // Find level of headlines
96 var level = Math.max(this.findLevel() + offset, 1);
97
98 console.debug("Adding headline (" + level + ")");
99 var headline = "#".repeat(level);
100
101 if (this.selection.length == 0) {
102 headline += " ...";
103 } else {
104 // Add some space if we don't have any, yet
105 if (!this.selection.text.startsWith(" "))
106 headline += " ";
107
108 headline += this.selection.text + "\n\n";
109 }
110
111 this.replaceSelection(headline);
112 }
113
114 headline() {
115 return this.insertHeadline(0);
116 }
117
118 headline_down() {
119 return this.insertHeadline(1);
120 }
121
122 headline_up() {
123 return this.insertHeadline(-1);
124 }
feeace6e
MT
125}
126
127$(document).ready(function() {
128 // Initialise all editors
129 $(".editor").each(function(i, e) {
130 new Editor(e);
131 });
132});