2 // @name Kita-Yen 4Chan
3 // @description Add kita to your post with ctr+"k" and Yen with ctr+"\"
5 // @match *://boards.4chan.org/*
7 // @namespace https://greasyfork.org/users/125336
8 // @updateURL https://github.com/ECHibiki/4chan-UserScripts/raw/master/Kita-Yen_4chan.user.js
9 // @downloadURL https://github.com/ECHibiki/4chan-UserScripts/raw/master/Kita-Yen_4chan.user.js
14 colorCharacters(document.body);
17 new MutationObserver(function(mutations){
18 mutations.forEach(function(mutation){
19 //pass along root nodes
20 /* (element, index, array) */
21 mutation.addedNodes.forEach(colorCharacters);
23 }).observe(document.body, {childList: true, subtree: true});
26 function colorCharacters(root){
27 if(root.nodeType !== Node.ELEMENT_NODE){
31 var nodes = Array.from(root.getElementsByClassName('postMessage'));
32 if(root.classList.contains('postmessage')){
33 //insert above nodes, the root.
37 nodes.forEach(function(node){
38 if(node.textContent.indexOf('\xa5') <= -1 && node.textContent.indexOf("キタ━━━(゚∀゚)━━━!!") <= -1){
41 var txtItterator = document.createNodeIterator(node, NodeFilter.SHOW_TEXT);
43 while((text_node = txtItterator.nextNode())){
44 //disregard text inside of A tag links and already colored text
45 if(text_node.parentNode.tagName == "A" || /the_[a-z]_word/g.test(text_node.parentNode.className)) continue;
46 setColor(text_node, txtItterator);
51 //give color to text inside of nodes.
52 // first scan for yen symbols and then check the front of the text for not nested kita.
53 function setColor(text_node, txtItterator){
54 var start_text_node = text_node;
56 var yen_node = searchYen(text_node);
57 if(yen_node != false){
58 //jump to internal node
59 text_node = txtItterator.nextNode();
60 //scan for nested kita
62 var result = searchKita(text_node);
64 //jump foreward to point after kita inserted
65 text_node = txtItterator.nextNode();
66 text_node = txtItterator.nextNode();
68 }while(result != false);
71 //scan for outside kita from start
73 var result = searchKita(start_text_node);
74 start_text_node = result.nextSibling;
75 }while(result != false && start_text_node !== undefined);
79 //find the location of a yen, split the text from above that position, create a span element and place split into this span.
80 //Then take the initial text node and insert into it from after the text node.
81 function searchYen (text_node){
82 var yenIndex = text_node.textContent.indexOf('\xa5');
84 var splitNode = text_node.splitText(yenIndex);
86 var span = document.createElement('span');
87 span.className = "the_m_word";
89 span.appendChild(splitNode);
90 text_node.parentNode.insertBefore(span, text_node.nextSibling);
97 //find the location of a kita, isolate it by splitting from the point where the kita ends and the point where it begins.
98 //Now that there are 3 text nodes, take the middle one from the start position index split, add the text which goes to the point of the rightmost split,
99 //then refer back to the parent and place it after the leftmost string.
100 function searchKita (text_node){
101 var kIndex = text_node.textContent.indexOf("キタ━━━(゚∀゚)━━━!!");
103 var far_split_note = text_node.splitText(kIndex + "キタ━━━(゚∀゚)━━━!!".length);
104 var splitNode = text_node.splitText(kIndex);
106 var span = document.createElement('span');
107 span.className = "the_k_word";
109 span.appendChild(splitNode);
110 text_node.parentNode.insertBefore(span, text_node.nextSibling);
118 var style = document.createElement("STYLE");
119 style.innerHTML = ".the_m_word{color:#9370DB} \n.the_k_word{color:#555555}";
120 document.head.appendChild(style);
123 //hotkeys for kita and yen
124 var listener_obj = {};
125 window.addEventListener("keydown", function(e){
126 listener_obj[e.keyCode] = true;
128 var node = document.activeElement;
129 if (listener_obj[17] && listener_obj[75]){
131 insertAtPos(node, 'キタ━━━(゚∀゚)━━━!!');
133 if (listener_obj[17] && listener_obj[220]){
135 insertAtPos(node, '\xa5');
137 }, {passive:false, capture:false, once:false});
139 window.addEventListener("keyup", function(e){
140 listener_obj[e.keyCode] = false;
141 }, {passive:false, capture:false, once:false});
143 function insertAtPos(node, buzzwords){
144 var sel_start = node.selectionStart;
145 var sel_end = node.selectionEnd;
148 node.value = n_tc.substr(0, sel_start) + buzzwords + n_tc.substr(sel_end);
150 node.selectionStart = sel_start + buzzwords.length;
151 node.selectionEnd = sel_end + buzzwords.length;