📜 ⬆️ ⬇️

But let's write the writing tool for Uncle Fyodor!

image
I read yesterday's post Prostokvashino on Habré or Uncle Fedor’s letter . Thought interesting, but.

Comments scare.

Let me explain why.
')
Comments there can be divided into two types.



The soul of the poet could not stand it, found half an hour, and drew userscript .

The script is simple to horror - it looks through all the comments in search of a special marker. If the marker is found - shows all comments with a marker in the pop-up window.

Anyone wishing to participate in the improvement - welcome, so to speak roll back technology . If your comment should be added to the post - write inside the comment like this [also] . And I, as the initiator of this disgrace - as far as possible I will transfer your wishes to the post. And accordingly - to improve the script, too.



It looks like this:
image

And now poboku lyrics, and consider what we are doing here is.

The standard start is to explain Greasemonkey what it is and why. And also we get a couple of variables - for the window and for the marker.

// ==UserScript== // @name Prostokvashino // @namespace habrahabr.ru // @description habrahabr.ru/post/213263 // @include http://*.habrahabr.ru/post/* // @include http://habrahabr.ru/post/* var MARKER = '[also]'; var floatingDiv = null; 


Now we will consider the main algorithm - the benefit is as simple as five kopecks. To begin with, we find where the comments are, prepare the array for the results (found):

 function showMarkedComments () { var commentsBlock = document.getElementById('comments'); var eltList = commentsBlock.getElementsByTagName('div'); var found = []; 


Next, we do it very simply - let's iterate through all the divs, with the actual texts.

  for(var j=0; j<eltList.length; ++j) { var elt = eltList[j]; if(elt.className != 'comment_body' ) continue; // now elt has two sub-divs - info with author and div with text // in version 0.1 we're ignoring authors and other technical stuff - just use div with text for(var k=0; k < elt.childNodes.length; ++k) { if(elt.childNodes[k].nodeName.toLowerCase() == "div") { ... } } } 


Not the top of optimality, but will bypass the entire hierarchy with responses to comments, and in the order in which it is described in the page. Voila - you don’t have to think about dates.

Actually, checking and memorizing is so obvious (and also not optimal) that there is nothing to comment on:

  divtxt = elt.childNodes[k].innerHTML; if(divtxt.indexOf(MARKER) < 0) continue; found.push(divtxt); 


There is a trifle - fill the contents of the pop-up window. I, like an old hardcore player, drew a rasp from a tractor, so screwing up jQuery plug-ins - the most there is a lot of room to improve this outrage.

 // in found, we have list of HTML texts together with marker. // All we need is to place it in floating div and make it visible if(found.length < 1) return; var buf = new StringBuffer(); for(var j = 0; j < found.length; ++j) { buf.append('<div id="comment_"'+j+' class="comment_item">\n'); buf.append('<div class="comment_body">'); buf.append('<div class="message html_format "><hr/>'); buf.append(found[j]); buf.append('</div>'); buf.append('</div>\n'); buf.append('</div>\n'); } buf.append('<hr/>'); floatingDiv.innerHTML = buf.toString(); floatingDiv.style.top = (window.pageYOffset + 10) + 'px'; floatingDiv.style.display = ''; } 


Here, in the process of sawing with a rasp, I suddenly became preoccupied with myself for productivity, quickly giving birth to an analogue of StringBuffer / StringBuilder on my knee. That's actually this part :

 // simple string buffer function StringBuffer() { this.buffer = []; } StringBuffer.prototype.append = function append(string) { this.buffer.push(string); return this; }; StringBuffer.prototype.toString = function toString() { return this.buffer.join(""); }; 


If you need to comment it out, let someone know. For me, so obvious code, but you never know. Friday, evening, on the eve of February 23 ...

Little things remained - to draw a window, hang up events , go for the juice , and here it is - a script.

any junk
No less hardcore, using the same rasp, I painted a pop-up window. Yes, I know - only the old footers, remembering the peculiarities of the hawker in netcat 3.0, write this .

 function makeFloatingDiv() { if(!floatingDiv) { floatingDiv = document.createElement('div'); floatingDiv.style.position = "absolute"; //floatingDiv.style.height = '600px'; floatingDiv.style.width = '800px'; floatingDiv.style.backgroundColor = '#f2f2f2'; floatingDiv.style.borderColor = 'red'; floatingDiv.style.borderWidth = '2px'; floatingDiv.style.borderStyle = 'groove'; floatingDiv.style.padding = '2px'; floatingDiv.valign = 'top'; floatingDiv.align = 'left'; floatingDiv.style.display = 'none'; floatingDiv.textAlign = 'left'; floatingDiv.style.overflow = 'auto'; floatingDiv.style.left = '10px'; floatingDiv.style.top = '10px'; document.getElementsByTagName('body')[0].appendChild(floatingDiv); floatingDiv.style.display = ''; floatingDiv.innerHTML = "..."; } } function makeDivWExtraLinks() { var xdiv = document.createElement('span'); xdiv.appendChild(document.createElement('br')); xdiv.appendChild(document.createElement('br')); xdiv.appendChild(mk_Link(1, 'See additions to post')); return xdiv; } function goHide(event) { if(event.target.style.display != 'none') event.target.style.display = 'none'; } 



Well, a couple more of the same functions in the same style:

 function mk_Link(code, label) { var newElt = document.createElement('a'); newElt.appendChild(document.createTextNode('[' + label + ']')); newElt.href= 'javascript:void(-' + code + ')'; return newElt; } 


However, an attentive reader will see a terrible heresy. Not only that pieces of HTML are glued together with lines of pieces! There are still some unobvious khaki built. Like these ones

newElt.href = 'javascript: void (-' + code + ')';


Himself in shock! Probably someone had mixed hemp in a freshly eaten cake ...

The idea here is as follows - we create a separate link between the article and the comments, by clicking on which all the work is done. This is why this is done - so that you can use other convenient scripts and buttons to update comments without reloading the page. And since comments can come to us after the download and very much “after”, then our algorithm should be able to work at any convenient time.

And since this was all drawn on my knee, so as not to knock my forehead with the execution contexts and their principals, I formed a link so that neither the site code nor the browser can do anything useful with the link. But in my handler, I can easily understand what to do with it. You can even write obscene words, as long as it is not a valid link or valid code.

However, there was a last spurt! No intrigues will not interfere ... ik! We register a couple of handlers - for loading the document and processing a terrible hack:

 window.addEventListener("load", goLoad, true); document.addEventListener('click', goClick, true); 


When loading a page, we add a special link between the article and comments. By clicking on it and we will carry out all the work:

 function goLoad() { // starting here: extra links plus other stuff var commentsBlock = document.getElementById('comments'); commentsBlock.parentNode.insertBefore(makeDivWExtraLinks(), commentsBlock); makeFloatingDiv(); floatingDiv.addEventListener('click', goHide, true); } 


and here is the treatment by clicking on this link:

 function goClick(event) { if(event.target.href) { var j = event.target.href.indexOf('javascript:void(-'); if( j >=0 ) { // kind is group of operations' prefix: 0..9 var kind = event.target.href.substring(j + 16, j + 18); if(kind == '-1') showMarkedComments(); } } } 


Thanks for attention.

UPD: And here are the comments!

[also] a marker can be set there for debugging anything — when I debugged the brace at all I asked. And then there are no live posts with such a label - only this one.

[also] Nothing happened ...

Let me remind you, the script is here . Already - checked only in Ognelis. What happens in other browsers - did not even look. Especially if it's IE ;-)

[also] Wrong, Uncle Fedor, you do custom scripts — if there is a lot of such [also] in some post, it will look scary when opened — it’s better to insert directly into the page instead of position: absolute.

Right remark. Corrected. The code has become simpler and smaller.

 function makeFloatingDiv() { if(!floatingDiv) { floatingDiv = document.createElement('div'); floatingDiv.style.backgroundColor = '#f2f2f2'; floatingDiv.style.borderColor = 'red'; floatingDiv.style.borderWidth = '2px'; floatingDiv.style.borderStyle = 'groove'; floatingDiv.style.padding = '2px'; floatingDiv.valign = 'top'; floatingDiv.align = 'left'; floatingDiv.textAlign = 'left'; floatingDiv.style.overflow = 'auto'; floatingDiv.style.display = 'none'; floatingDiv.innerHTML = "..."; } return floatingDiv; } function goLoad() { // starting here: extra links plus other stuff var commentsBlock = document.getElementById('comments'); commentsBlock.parentNode.insertBefore(makeFloatingDiv(), commentsBlock); commentsBlock.parentNode.insertBefore(makeDivWExtraLinks(), floatingDiv); floatingDiv.addEventListener('click', goHide, true); } 


And now it looks like this

Source: https://habr.com/ru/post/213481/


All Articles