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