Translated using Weblate (Slovenian)
[phpmyadmin.git] / js / error_report.js
blobbe37a42d1b87b0520424134e86173373b7b11d4d
2 /* global TraceKit */ // js/vendor/tracekit.js
4 /**
5  * general function, usually for data manipulation pages
6  *
7  */
8 var ErrorReport = {
9     /**
10      * @var object stores the last exception info
11      */
12     lastException: null,
13     /**
14      * handles thrown error exceptions based on user preferences
15      *
16      * @return void
17      */
18     errorHandler: function (exception) {
19         // issue: 14359
20         if (JSON.stringify(ErrorReport.lastException) === JSON.stringify(exception)) {
21             return;
22         }
23         if (exception.name === null || typeof(exception.name) === 'undefined') {
24             exception.name = ErrorReport.extractExceptionName(exception);
25         }
26         ErrorReport.lastException = exception;
27         $.post('index.php?route=/error-report', {
28             'ajax_request': true,
29             'server': CommonParams.get('server'),
30             'get_settings': true,
31             'exception_type': 'js'
32         }, function (data) {
33             if (data.success !== true) {
34                 Functions.ajaxShowMessage(data.error, false);
35                 return;
36             }
37             if (data.report_setting === 'ask') {
38                 ErrorReport.showErrorNotification();
39             } else if (data.report_setting === 'always') {
40                 var reportData = ErrorReport.getReportData(exception);
41                 var postData = $.extend(reportData, {
42                     'send_error_report': true,
43                     'automatic': true
44                 });
45                 $.post('index.php?route=/error-report', postData, function (data) {
46                     if (data.success === false) {
47                         // in the case of an error, show the error message returned.
48                         Functions.ajaxShowMessage(data.error, false);
49                     } else {
50                         Functions.ajaxShowMessage(data.message, false);
51                     }
52                 });
53             }
54         });
55     },
56     /**
57      * Shows the modal dialog previewing the report
58      *
59      * @param exception object error report info
60      *
61      * @return void
62      */
63     showReportDialog: function (exception) {
64         var reportData = ErrorReport.getReportData(exception);
66         /* Remove the hidden dialogs if there are*/
67         if ($('#error_report_dialog').length !== 0) {
68             $('#error_report_dialog').remove();
69         }
70         var $div = $('<div id="error_report_dialog"></div>');
71         $div.css('z-index', '1000');
73         var buttonOptions = {};
75         buttonOptions[Messages.strSendErrorReport] = function () {
76             var $dialog = $(this);
77             var postData = $.extend(reportData, {
78                 'send_error_report': true,
79                 'description': $('#report_description').val(),
80                 'always_send': $('#always_send_checkbox')[0].checked
81             });
82             $.post('index.php?route=/error-report', postData, function (data) {
83                 $dialog.dialog('close');
84                 if (data.success === false) {
85                     // in the case of an error, show the error message returned.
86                     Functions.ajaxShowMessage(data.error, false);
87                 } else {
88                     Functions.ajaxShowMessage(data.message, 3000);
89                 }
90             });
91         };
93         buttonOptions[Messages.strCancel] = function () {
94             $(this).dialog('close');
95         };
97         $.post('index.php?route=/error-report', reportData, function (data) {
98             if (data.success === false) {
99                 // in the case of an error, show the error message returned.
100                 Functions.ajaxShowMessage(data.error, false);
101             } else {
102                 // Show dialog if the request was successful
103                 $div
104                     .append(data.message)
105                     .dialog({
106                         title: Messages.strSubmitErrorReport,
107                         width: 650,
108                         modal: true,
109                         buttons: buttonOptions,
110                         close: function () {
111                             $(this).remove();
112                         }
113                     });
114             }
115         });
116     },
117     /**
118      * Shows the small notification that asks for user permission
119      *
120      * @return void
121      */
122     showErrorNotification: function () {
123         ErrorReport.removeErrorNotification();
125         var $div = $(
126             '<div class="alert alert-danger userPermissionModal" role="alert" id="error_notification"></div>'
127         ).append(
128             Functions.getImage('s_error') + Messages.strErrorOccurred
129         );
131         var $buttons = $('<div class="floatright"></div>');
133         var buttonHtml  = '<button class="btn btn-primary" id="show_error_report">';
134         buttonHtml += Messages.strShowReportDetails;
135         buttonHtml += '</button>';
137         buttonHtml += '<a id="change_error_settings">';
138         buttonHtml += Functions.getImage('s_cog', Messages.strChangeReportSettings);
139         buttonHtml += '</a>';
141         buttonHtml += '<a href="#" id="ignore_error">';
142         buttonHtml += Functions.getImage('b_close', Messages.strIgnore);
143         buttonHtml += '</a>';
145         $buttons.html(buttonHtml);
147         $div.append($buttons);
148         $div.appendTo(document.body);
149         $(document).on('click', '#change_error_settings', ErrorReport.redirectToSettings);
150         $(document).on('click', '#show_error_report', ErrorReport.createReportDialog);
151         $(document).on('click', '#ignore_error', ErrorReport.removeErrorNotification);
152     },
153     /**
154      * Removes the notification if it was displayed before
155      *
156      * @return void
157      */
158     removeErrorNotification: function (e) {
159         if (e) {
160             // don't remove the hash fragment by navigating to #
161             e.preventDefault();
162         }
163         $('#error_notification').fadeOut(function () {
164             $(this).remove();
165         });
166     },
167     /**
168      * Extracts Exception name from message if it exists
169      *
170      * @return String
171      */
172     extractExceptionName: function (exception) {
173         if (exception.message === null || typeof(exception.message) === 'undefined') {
174             return '';
175         }
177         var reg = /([a-zA-Z]+):/;
178         var regexResult = reg.exec(exception.message);
179         if (regexResult && regexResult.length === 2) {
180             return regexResult[1];
181         }
183         return '';
184     },
185     /**
186      * Shows the modal dialog previewing the report
187      *
188      * @return void
189      */
190     createReportDialog: function () {
191         ErrorReport.removeErrorNotification();
192         ErrorReport.showReportDialog(ErrorReport.lastException);
193     },
194     /**
195      * Redirects to the settings page containing error report
196      * preferences
197      *
198      * @return void
199      */
200     redirectToSettings: function () {
201         window.location.href = 'index.php?route=/preferences/features';
202     },
203     /**
204      * Returns the report data to send to the server
205      *
206      * @param exception object exception info
207      *
208      * @return object
209      */
210     getReportData: function (exception) {
211         if (exception && exception.stack && exception.stack.length) {
212             for (var i = 0; i < exception.stack.length; i++) {
213                 var stack = exception.stack[i];
214                 if (stack.context && stack.context.length) {
215                     for (var j = 0; j < stack.context.length; j++) {
216                         if (stack.context[j].length >  80) {
217                             stack.context[j] = stack.context[j].substring(-1, 75) + '//...';
218                         }
219                     }
220                 }
221             }
222         }
223         var reportData = {
224             'server': CommonParams.get('server'),
225             'ajax_request': true,
226             'exception': exception,
227             'url': window.location.href,
228             'exception_type': 'js'
229         };
230         if (AJAX.scriptHandler.scripts.length > 0) {
231             reportData.scripts = AJAX.scriptHandler.scripts.map(
232                 function (script) {
233                     return script;
234                 }
235             );
236         }
237         return reportData;
238     },
239     /**
240      * Wraps all global functions that start with PMA_
241      *
242      * @return void
243      */
244     wrapGlobalFunctions: function () {
245         for (var key in window) {
246             if (key.indexOf('PMA_') === 0) {
247                 var global = window[key];
248                 if (typeof(global) === 'function') {
249                     window[key] = ErrorReport.wrapFunction(global);
250                 }
251             }
252         }
253     },
254     /**
255      * Wraps given function in error reporting code and returns wrapped function
256      *
257      * @param func function to be wrapped
258      *
259      * @return function
260      */
261     wrapFunction: function (func) {
262         if (!func.wrapped) {
263             var newFunc = function () {
264                 try {
265                     return func.apply(this, arguments);
266                 } catch (x) {
267                     TraceKit.report(x);
268                 }
269             };
270             newFunc.wrapped = true;
271             // Set guid of wrapped function same as original function, so it can be removed
272             // See bug#4146 (problem with jquery draggable and sortable)
273             newFunc.guid = func.guid = func.guid || newFunc.guid || jQuery.guid++;
274             return newFunc;
275         } else {
276             return func;
277         }
278     },
279     /**
280      * Automatically wraps the callback in AJAX.registerOnload
281      *
282      * @return void
283      */
284     wrapAjaxOnloadCallback: function () {
285         var oldOnload = AJAX.registerOnload;
286         AJAX.registerOnload = function (file, func) {
287             var wrappedFunction = ErrorReport.wrapFunction(func);
288             oldOnload.call(this, file, wrappedFunction);
289         };
290     },
291     /**
292      * Automatically wraps the callback in $.fn.on
293      *
294      * @return void
295      */
296     wrapJqueryOnCallback: function () {
297         var oldOn = $.fn.on;
298         $.fn.on = function () {
299             for (var i = 1; i <= 3; i++) {
300                 if (typeof(arguments[i]) === 'function') {
301                     arguments[i] = ErrorReport.wrapFunction(arguments[i]);
302                     break;
303                 }
304             }
305             return oldOn.apply(this, arguments);
306         };
307     },
308     /**
309      * Wraps all global functions that start with PMA_
310      * also automatically wraps the callback in AJAX.registerOnload
311      *
312      * @return void
313      */
314     setUpErrorReporting: function () {
315         ErrorReport.wrapGlobalFunctions();
316         ErrorReport.wrapAjaxOnloadCallback();
317         ErrorReport.wrapJqueryOnCallback();
318     }
321 AJAX.registerOnload('error_report.js', function () {
322     TraceKit.report.subscribe(ErrorReport.errorHandler);
323     ErrorReport.setUpErrorReporting();
324     ErrorReport.wrapGlobalFunctions();