📜 ⬆️ ⬇️

How to protect against unexpected commenting by Ctrl + Enter?

(The experience of successful struggle with windmills.)

With enviable regularity in the comments, there are ragged messages in the mid-sentence with postscript that “I am sorry, I myself went ,” “ broke, ” and a continuation of the thought. Sometimes they say that they have unraveled the reason for this site behavior. Therefore, I want to inform you that I am not alone in my guess, and moreover, about six months ago I solved this problem with the help of user scripts. Since then, the false submissions have stopped for me, but I could not be sure that the only reason for the false submissions was this, so the experience of using the script and the guesses of other users had to confirm this.

And so, I noticed a note that someone else also sees the reason for the false sending in this:
habrahabr.ru/blogs/client_side_optimization/137318/#comment_4572800 (Jan 31, 2012)
A Google search showed that the reason was solved before: habrahabr.ru/qa/9515/#answer_40702 (July 15, 2011)
habrahabr.ru/qa/8447/#answer_35939 (June 12, 2011)
habrahabr.ru/company/regru/blog/105763/#comment_3318569 (Oct 8, 2010)
habrahabr.ru/blogs/bsdelniki/118485/#comment_3863623 (May 1, 2011)
habrahabr.ru/blogs/google/118622/#comment_3873012 (May 9, 2011), etc., can be continued for a long time, these links are from the first 30 search results (the Sphinx search on the site is no good, it does not search for an exact phrase Google and Yandex search is built into the same script. It should be noted that search by search engine is incomplete, it does not show all cases guaranteed, and there will not be any time (hours, days, weeks) for new messages).

The solution through technical support of the site has already shown its inefficiency. For example, the script of the script for displaying the source code of programs when the <BR> tag appears is not fixed for more than six months. In addition, the creators of the script may have the opposite opinion about the "usefulness" of this function. Therefore, disabling auto sending with Ctrl + Enter is much faster to implement on your own (some worries, but immediately, reliably (until the scripts change on the site) and controlled).
')
Until October 2011, user scripts worked successfully:
var win = (typeof unsafeWindow !='undefined')? unsafeWindow: window; if(win.commentForm) win.commentForm.sendOnEnter = function(){}; 
(except Chrome browser)

Since that time, the scripts on the site have been updated, and it can be seen (experiments can be safely conducted in the browser mode “offline”), that other sections of the code are responsible for sending, here they are:

(view.js file - for QA section)
 var answer_form = $('#add_answer_form'); var answer_text = $('#answer_text'); /** * CTRL + ENTER */ answer_text.keydown(function (e) { if ( (e.ctrlKey || e.metaKey ) && e.keyCode == 13) { $('input.submit',answer_form).click() } }); 

And in another place (comments.js file, for other sections):
 $(document).ready(function(){ var comments_form = $('#comments_form'); var comment_text = $('#comment_text'); comment_text.keydown(function (e) { if ( (e.ctrlKey || e.metaKey ) && e.keyCode == 13) { $('input.submit',comments_form).click() } }); ... 

These scripts are funny. If we had root access to the site or at least a proxomitron (a well-known tool for editing the flow on a proxy server), it would be a small matter. Now it is necessary to make several times more additional movements in order to correct the destructive consequences of several lines. On the other hand, for educational purposes, this is good. We are complicated by the task, and we are getting stronger (in the knowledge of methods of solution). And here we will show how to solve the problem by “unleashing” the problem from the source.

We see hanging an event with an anonymous function via jQuery. As far as we know, an event can be removed if you write $ ('# comment_text'). Unbind ('keydown', the same function), and with a function is a problem, it is anonymous, and user scripts work altogether before creating a keydown handler. ( UPD 05.02, 22:00 - taliban showed how using “DOMContentLoaded” to apply a simpler solution through the jQuery .unbind ('keydown') method. The code is in addition to the article below.) Repeating the text of the function, for example, does not resolve the issue . Disable and redo the effect - $ ('input.submit', $ ('# comments_form')). Click ()? It does not solve the question, because “e” is not transmitted to it - an event object from which data on a pressed key would be taken. So, we remake the “keydown” method of jQuery, which processes keystrokes in this form (text from compressed jQuery):
 function (a, c) { c == null && (c = a, a = null); return arguments.length > 0 ? this.bind(b, a, c) : this.trigger(b); } 

Here b is obviously the “keydown” constant, c - (according to the description in the documentation) - handler (eventObject) is the same user handler whose body we need to change, a is an optional hash data for the handler. And this piece of code in the library is common to many events. It is necessary not to violate this function for other applications in jQuery and make a check when this is $ ('textarea'). The method must be overridden, referring not to the function itself, but to its prototype.

And, since actions take place in userscript, these operations will not be easy to force to execute in Chrome (environments for userscripts and scripts are separated), and in the rest - at the beginning you need to write an environment object - win, which (typeof unsafeWindow! = 'Undefined')? unsafeWindow: window.

Partial solution of the problem (Firefox, Opera, Safari) will look like this, and we’ll stop on it now, because the overall solution is beyond the essence of the article.
 var win = (typeof unsafeWindow !='undefined')? unsafeWindow: window; if(win.$){ //   Ctrl+Enter ( Chrome) var comT = win.$('#comment_text, #answer_text'); if(comT){ //  Textarea   ... comT.constructor.prototype.keydown = function(ha, fKeyD){ fKeyD == null && (fKeyD = ha, ha = null); //   var k ='keydown'; if(this[0].tagName=='TEXTAREA' && /^(comment|answer)_text$/.test(this[0].id)){ fKeyD = function(ev){ if((ev.ctrlKey || ev.metaKey)&& ev.keyCode == 13) //  win.console.log('Ctrl-enter  '); }; } return arguments.length > 0 ? this.bind(k, ha, fKeyD) : this.trigger(k); } } } 

What was received from the point of view of the beauty of the solution? The jQuery library function had to be loaded with a special check, because there is no other possibility to cancel the triggering of the send action, and inside it we need to replace the function that makes the click on the button an empty function (we are not empty for demonstration purposes only). The source code of the library, of course, does not patch, because we did not have access to it, as we have not.

Based on this code, it is easy to make a small user script that solves only this task (just use the whole one). But, since there is a common user script that solves 2-3 dozen tasks, called HabrAjax , we will create this function for it. It will take effect at the script with version 2.06 and higher.

To check whether the message was not sent by Ctrl-Enter in the specified browsers, you need to install a user script (short, above, or HabrAjax), load the site page with a comment input field, switch the browser to offline mode and make sure that inside the input field by Ctrl- Enter form is not sent. If you disable the script, this combination will lead to an animation of the “Send” button, accompanying the attempt to send via Ajax (visible in the Firebug console, for example).

The problem is solved - now the accidental pressing of Ctrl + Enter, which sometimes happens during speed dialing, will not lead to an unexpected sending (uncorrectable!) Message to the server.

For a common solution involving Chrome, the easiest way is to make a workaround. Create a new send key. Delete the old key with all events attached to it. By clicking on the new - the form will be automatically sent in all browsers. At the same time, in Firefox, it will be possible to correct the styles of the submit button, which were not amenable to user-style correction by other methods due to the special order of priorities for the use of styles.
UPD : about the tab from the first comment. You can intercept the tab and prevent it from being used by the default browser. For writing code, this is even better - tabs create indents. But someone can use tabs to switch between fields, and someone never does. I think to include this setting in the general HabAjax script. And, say, by default, prohibit the transition between fields. There are opposing opinions?
UPD 22:30: According to the discussion results in the comments, the HabrAjax settings were enriched with two new (disconnectable) ones: “do not send comments by Ctrl + Enter” and “do not leave textarea by Tab, but enter tabs”. The latter, more precisely, applies only to comments and allows you to enter "& nbsp;" Ctrl + space. In the meantime, made a selection of new settings in the list. In Chrome, both settings are not shown (even in the list), because they are not supported, but after a while there is an opportunity to remake the script so that it becomes universal (which, by the way, was still true for all the capabilities of the script). Laid out in version 0.808.
(On the way (to close the topic of character input) - control of indents by Tab - Chift + Tab.)
UPD Feb 5, 10:00 pm: On the initiative and with the help of taliban, a script for Firefox / Opera was written, which uses disabling the event handler using jQuery:
 // ==UserScript== // @name noCtrlEnter // @version 1.1, 2012-02-05 // @description     Ctrl+Enter  textarea // @include http://habrahabr.ru/* document.addEventListener( 'DOMContentLoaded', function(){ var win = (typeof unsafeWindow !='undefined')? unsafeWindow: window; if(!win.$) return; var comT = win.$('#comment_text, #answer_text'); comT.length && comT.unbind('keydown'); },!1); 

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


All Articles