Feedback
Feedback lets you send us suggestions about our products. We welcome problem reports, feature ideas and general comments.
Start by writing a brief description:
Next we\'ll let you identify areas of the page related to your description.
Please enter a description.
',highlighter:'Feedback
Thank you for your feedback. We value every piece of feedback we receive.
We cannot respond individually to every one, but we will use your comments as we strive to improve your experience.
',submitError:''),n.push(p),++p,d(m))}}})}a(document).on("mouseleave","body,#feedback-canvas",function(){d(m)}),a(document).on("mouseenter",".feedback-helper",function(){d(m)}),a(document).on("click","#feedback-welcome-next",function(){a("#feedback-note").val().length>0?(b=!0,a("#feedback-canvas").css("cursor","crosshair"),a("#feedback-helpers").show(),a("#feedback-welcome").hide(),a("#feedback-highlighter").show()):a("#feedback-welcome-error").show()}),a(document).on("mouseenter mouseleave",".feedback-helper",function(b){drag||(rect.w=0,rect.h=0,"mouseenter"===b.type?(a(this).css("z-index","30001"),a(this).append(''),a(this).append(''),a(this).find("#feedback-close").css({top:-1*(a(this).find("#feedback-close").height()/2)+"px",left:a(this).width()-a(this).find("#feedback-close").width()/2+"px"}),"blackout"==a(this).attr("data-type")&&(m.clearRect(0,0,a("#feedback-canvas").width(),a("#feedback-canvas").height()),m.fillStyle="rgba(102,102,102,0.5)",m.fillRect(0,0,a("#feedback-canvas").width(),a("#feedback-canvas").height()),a(".feedback-helper").each(function(){"highlight"==a(this).attr("data-type")&&e(m,parseInt(a(this).css("left"),10),parseInt(a(this).css("top"),10),a(this).width(),a(this).height())}),a(".feedback-helper").each(function(){"highlight"==a(this).attr("data-type")&&m.clearRect(parseInt(a(this).css("left"),10),parseInt(a(this).css("top"),10),a(this).width(),a(this).height())}),m.clearRect(parseInt(a(this).css("left"),10),parseInt(a(this).css("top"),10),a(this).width(),a(this).height()),m.fillStyle="rgba(0,0,0,0.75)",m.fillRect(parseInt(a(this).css("left"),10),parseInt(a(this).css("top"),10),a(this).width(),a(this).height()),ignore=a(this).attr("data-time"),a(".feedback-helper").each(function(){return a(this).attr("data-time")==ignore?!0:void("blackout"==a(this).attr("data-type")&&(m.fillStyle="rgba(0,0,0,1)",m.fillRect(parseInt(a(this).css("left"),10),parseInt(a(this).css("top"),10),a(this).width(),a(this).height())))}))):(a(this).css("z-index","30000"),a(this).children().remove(),"blackout"==a(this).attr("data-type")&&d(m)))}),a(document).on("click","#feedback-close",function(){if(f.highlightElement&&a(this).parent().attr("data-highlight-id"))var b=a(this).parent().attr("data-highlight-id");a(this).parent().remove(),f.highlightElement&&b&&a('[data-highlight-id="'+b+'"]').removeAttr("data-highlighted").removeAttr("data-highlight-id"),d(m)}),a("#feedback-module").on("click",".feedback-wizard-close,.feedback-close-btn",function(){c()}),a(document).on("keyup",function(a){27==a.keyCode&&c()}),a(document).on("selectstart dragstart",document,function(a){a.preventDefault()}),a(document).on("click","#feedback-highlighter-back",function(){b=!1,a("#feedback-canvas").css("cursor","default"),a("#feedback-helpers").hide(),a("#feedback-highlighter").hide(),a("#feedback-welcome-error").hide(),a("#feedback-welcome").show()}),a(document).on("mousedown",".feedback-sethighlight",function(){highlight=1,a(this).addClass("feedback-active"),a(".feedback-setblackout").removeClass("feedback-active")}),a(document).on("mousedown",".feedback-setblackout",function(){highlight=0,a(this).addClass("feedback-active"),a(".feedback-sethighlight").removeClass("feedback-active")}),a(document).on("click","#feedback-highlighter-next",function(){b=!1,a("#feedback-canvas").css("cursor","default");var e=a(document).scrollTop(),h=a(window).height();a("#feedback-helpers").hide(),a("#feedback-highlighter").hide(),f.screenshotStroke||d(m,!1),html2canvas(a("body"),{onrendered:function(b){f.screenshotStroke||d(m),_canvas=a('').hide().appendTo("body"),_ctx=_canvas.get(0).getContext("2d"),_ctx.drawImage(b,0,e,k,h,0,0,k,h),g=_canvas.get(0).toDataURL(),a(document).scrollTop(e),post.img=g,f.onScreenshotTaken(post.img),f.showDescriptionModal?(a("#feedback-canvas-tmp").remove(),a("#feedback-overview").show(),a("#feedback-overview-description-text>textarea").remove(),a("#feedback-overview-screenshot>img").remove(),a('").insertAfter("#feedback-overview-description-text h3:eq(0)"),a("#feedback-overview-screenshot").append('
')):(a("#feedback-module").remove(),c(),_canvas.remove())},proxy:f.proxy,letterRendering:f.letterRendering})}),a(document).on("click","#feedback-overview-back",function(c){b=!0,a("#feedback-canvas").css("cursor","crosshair"),a("#feedback-overview").hide(),a("#feedback-helpers").show(),a("#feedback-highlighter").show(),a("#feedback-overview-error").hide()}),a(document).on("keyup","#feedback-note-tmp,#feedback-overview-note",function(b){var c;"feedback-note-tmp"===b.target.id?c=a("#feedback-note-tmp").val():(c=a("#feedback-overview-note").val(),a("#feedback-note-tmp").val(c)),a("#feedback-note").val(c)}),a(document).on("click","#feedback-submit",function(){if(b=!1,a("#feedback-note").val().length>0){a("#feedback-submit-success,#feedback-submit-error").remove(),a("#feedback-overview").hide(),post.img=g,post.note=a("#feedback-note").val();var c={feedback:post},d=JSON.stringify(c);a.ajax({url:"function"==typeof f.ajaxURL?f.ajaxURL():f.ajaxURL,dataType:"json",contentType:"application/json",type:"POST",data:d,headers:{"Content-Type":"application/json"},success:function(){a("#feedback-module").append(f.tpl.submitSuccess)},error:function(){a("#feedback-module").append(f.tpl.submitError)}})}else a("#feedback-overview-error").show()})}))}}(jQuery),jQuery.feedback(a.options)}}}]);
--------------------------------------------------------------------------------
/src/angularSendFeedback.js:
--------------------------------------------------------------------------------
1 | angular.module('angular-send-feedback').directive('angularFeedback', [ function() {
2 |
3 |
4 | return {
5 | restrict: 'EA',
6 | replace: true,
7 | transclude: true,
8 | scope: {
9 | options : '='
10 | },
11 | //templateUrl: function(element, attributes) {
12 | //return attributes.template || "angularsendfeedback.html";
13 | //},
14 | link: function($scope, $element, $attrs) {
15 |
16 | (function($){
17 |
18 | $.feedback = function(options) {
19 |
20 | var settings = $.extend({
21 | ajaxURL: '',
22 | postBrowserInfo: true,
23 | postHTML: true,
24 | postURL: true,
25 | postTimeStamp: true,
26 | proxy: undefined,
27 | letterRendering: false,
28 | initButtonText: 'Send feedback',
29 | strokeStyle: 'black',
30 | shadowColor: 'black',
31 | shadowOffsetX: 1,
32 | shadowOffsetY: 1,
33 | shadowBlur: 10,
34 | lineJoin: 'bevel',
35 | lineWidth: 3,
36 | html2canvasURL: 'html2canvas.js',
37 | feedbackButton: '.feedback-btn',
38 | showDescriptionModal: true,
39 | isDraggable: true,
40 | onScreenshotTaken: function(){},
41 | tpl: {
42 | initButton: '',
43 | description: 'Feedback
Feedback lets you send us suggestions about our products. We welcome problem reports, feature ideas and general comments.
Start by writing a brief description:
Next we\'ll let you identify areas of the page related to your description.
Please enter a description.
',
44 | highlighter: 'Feedback
Click and drag on the page to help us better understand your feedback. You can move this dialog if it\'s in the way.
',
45 | overview: 'Feedback
Description
Additional info
None
Browser Info
Page Info
Time Stamp
Page Structure
Screenshot
Please enter a description.
',
46 | submitSuccess: 'Feedback
Thank you for your feedback. We value every piece of feedback we receive.
We cannot respond individually to every one, but we will use your comments as we strive to improve your experience.
',
47 | submitError: 'Feedback
Sadly an error occurred while sending your feedback. Please try again.
'
48 | },
49 | onClose: function() {},
50 | screenshotStroke: true,
51 | highlightElement: true,
52 | initialBox: false
53 | }, options);
54 | var supportedBrowser = !!window.HTMLCanvasElement;
55 | var isFeedbackButtonNative = settings.feedbackButton == '.feedback-btn';
56 | var _html2canvas = false;
57 | if (supportedBrowser) {
58 | if(isFeedbackButtonNative) {
59 | $('body').append(settings.tpl.initButton);
60 | }
61 | $(document).on('click', settings.feedbackButton, function(){
62 | if(isFeedbackButtonNative) {
63 | $(this).hide();
64 | }
65 | if (!_html2canvas) {
66 | $.getScript(settings.html2canvasURL, function() {
67 | _html2canvas = true;
68 | });
69 | }
70 | var canDraw = false,
71 | img = '',
72 | h = $(document).height(),
73 | w = $(document).width(),
74 | tpl = '';
75 |
76 | if (settings.initialBox) {
77 | tpl += settings.tpl.description;
78 | }
79 |
80 | tpl += settings.tpl.highlighter + settings.tpl.overview + '
';
81 |
82 | $('body').append(tpl);
83 |
84 | moduleStyle = {
85 | 'position': 'absolute',
86 | 'left': '0px',
87 | 'top': '0px'
88 | };
89 | canvasAttr = {
90 | 'width': w,
91 | 'height': h
92 | };
93 |
94 | $('#feedback-module').css(moduleStyle);
95 | $('#feedback-canvas').attr(canvasAttr).css('z-index', '30000');
96 |
97 | if (!settings.initialBox) {
98 | $('#feedback-highlighter-back').remove();
99 | canDraw = true;
100 | $('#feedback-canvas').css('cursor', 'crosshair');
101 | $('#feedback-helpers').show();
102 | $('#feedback-welcome').hide();
103 | $('#feedback-highlighter').show();
104 | }
105 |
106 | if(settings.isDraggable) {
107 | $('#feedback-highlighter').on('mousedown', function(e) {
108 | var $d = $(this).addClass('feedback-draggable'),
109 | drag_h = $d.outerHeight(),
110 | drag_w = $d.outerWidth(),
111 | pos_y = $d.offset().top + drag_h - e.pageY,
112 | pos_x = $d.offset().left + drag_w - e.pageX;
113 | $d.css('z-index', 40000).parents().on('mousemove', function(e) {
114 | _top = e.pageY + pos_y - drag_h;
115 | _left = e.pageX + pos_x - drag_w;
116 | _bottom = drag_h - e.pageY;
117 | _right = drag_w - e.pageX;
118 |
119 | if (_left < 0) _left = 0;
120 | if (_top < 0) _top = 0;
121 | if (_right > $(window).width())
122 | _left = $(window).width() - drag_w;
123 | if (_left > $(window).width() - drag_w)
124 | _left = $(window).width() - drag_w;
125 | if (_bottom > $(document).height())
126 | _top = $(document).height() - drag_h;
127 | if (_top > $(document).height() - drag_h)
128 | _top = $(document).height() - drag_h;
129 |
130 | $('.feedback-draggable').offset({
131 | top: _top,
132 | left: _left
133 | }).on("mouseup", function() {
134 | $(this).removeClass('feedback-draggable');
135 | });
136 | });
137 | e.preventDefault();
138 | }).on('mouseup', function(){
139 | $(this).removeClass('feedback-draggable');
140 | $(this).parents().off('mousemove mousedown');
141 | });
142 | }
143 |
144 | var ctx = $('#feedback-canvas')[0].getContext('2d');
145 |
146 | ctx.fillStyle = 'rgba(102,102,102,0.5)';
147 | ctx.fillRect(0, 0, $('#feedback-canvas').width(), $('#feedback-canvas').height());
148 |
149 | rect = {};
150 | drag = false;
151 | highlight = 1,
152 | post = {};
153 |
154 | if (settings.postBrowserInfo) {
155 | post.browser = {};
156 | post.browser.appCodeName = navigator.appCodeName;
157 | post.browser.appName = navigator.appName;
158 | post.browser.appVersion = navigator.appVersion;
159 | post.browser.cookieEnabled = navigator.cookieEnabled;
160 | post.browser.onLine = navigator.onLine;
161 | post.browser.platform = navigator.platform;
162 | post.browser.userAgent = navigator.userAgent;
163 | post.browser.plugins = [];
164 |
165 | $.each(navigator.plugins, function(i) {
166 | post.browser.plugins.push(navigator.plugins[i].name);
167 | });
168 | $('#feedback-browser-info').show();
169 | }
170 |
171 | if (settings.postURL) {
172 | post.url = document.URL;
173 | $('#feedback-page-info').show();
174 | }
175 |
176 | if (settings.postTimeStamp) {
177 | post.timestamp = new Date().getTime();
178 | $('#feedback-timestamp').show();
179 | }
180 |
181 | if (settings.postHTML) {
182 | post.html = $('html').html();
183 | $('#feedback-page-structure').show();
184 | }
185 |
186 | if (!settings.postBrowserInfo && !settings.postURL && !settings.postHTML)
187 | $('#feedback-additional-none').show();
188 |
189 | $(document).on('mousedown', '#feedback-canvas', function(e) {
190 | if (canDraw) {
191 |
192 | rect.startX = e.pageX - $(this).offset().left;
193 | rect.startY = e.pageY - $(this).offset().top;
194 | rect.w = 0;
195 | rect.h = 0;
196 | drag = true;
197 | }
198 | });
199 |
200 | $(document).on('mouseup', function(){
201 | if (canDraw) {
202 | drag = false;
203 |
204 | var dtop = rect.startY,
205 | dleft = rect.startX,
206 | dwidth = rect.w,
207 | dheight = rect.h;
208 | dtype = 'highlight';
209 |
210 | if (dwidth == 0 || dheight == 0) return;
211 |
212 | if (dwidth < 0) {
213 | dleft += dwidth;
214 | dwidth *= -1;
215 | }
216 | if (dheight < 0) {
217 | dtop += dheight;
218 | dheight *= -1;
219 | }
220 |
221 | if (dtop + dheight > $(document).height())
222 | dheight = $(document).height() - dtop;
223 | if (dleft + dwidth > $(document).width())
224 | dwidth = $(document).width() - dleft;
225 |
226 | if (highlight == 0)
227 | dtype = 'blackout';
228 |
229 | $('#feedback-helpers').append('');
230 |
231 | redraw(ctx);
232 | rect.w = 0;
233 | }
234 |
235 | });
236 |
237 | $(document).on('mousemove', function(e) {
238 | if (canDraw && drag) {
239 | $('#feedback-highlighter').css('cursor', 'default');
240 |
241 | rect.w = (e.pageX - $('#feedback-canvas').offset().left) - rect.startX;
242 | rect.h = (e.pageY - $('#feedback-canvas').offset().top) - rect.startY;
243 |
244 | ctx.clearRect(0, 0, $('#feedback-canvas').width(), $('#feedback-canvas').height());
245 | ctx.fillStyle = 'rgba(102,102,102,0.5)';
246 | ctx.fillRect(0, 0, $('#feedback-canvas').width(), $('#feedback-canvas').height());
247 | $('.feedback-helper').each(function() {
248 | if ($(this).attr('data-type') == 'highlight')
249 | drawlines(ctx, parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height());
250 | });
251 | if (highlight==1) {
252 | drawlines(ctx, rect.startX, rect.startY, rect.w, rect.h);
253 | ctx.clearRect(rect.startX, rect.startY, rect.w, rect.h);
254 | }
255 | $('.feedback-helper').each(function() {
256 | if ($(this).attr('data-type') == 'highlight')
257 | ctx.clearRect(parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height());
258 | });
259 | $('.feedback-helper').each(function() {
260 | if ($(this).attr('data-type') == 'blackout') {
261 | ctx.fillStyle = 'rgba(0,0,0,1)';
262 | ctx.fillRect(parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height())
263 | }
264 | });
265 | if (highlight == 0) {
266 | ctx.fillStyle = 'rgba(0,0,0,0.5)';
267 | ctx.fillRect(rect.startX, rect.startY, rect.w, rect.h);
268 | }
269 | }
270 | });
271 |
272 | if (settings.highlightElement) {
273 | var highlighted = [],
274 | tmpHighlighted = [],
275 | hidx = 0;
276 |
277 | $(document).on('mousemove click', '#feedback-canvas',function(e) {
278 | if (canDraw) {
279 | redraw(ctx);
280 | tmpHighlighted = [];
281 |
282 | $('#feedback-canvas').css('cursor', 'crosshair');
283 |
284 | $('* :not(body,script,iframe,div,section,.feedback-btn,#feedback-module *)').each(function(){
285 | if ($(this).attr('data-highlighted') === 'true')
286 | return;
287 |
288 | if (e.pageX > $(this).offset().left && e.pageX < $(this).offset().left + $(this).width() && e.pageY > $(this).offset().top + parseInt($(this).css('padding-top'), 10) && e.pageY < $(this).offset().top + $(this).height() + parseInt($(this).css('padding-top'), 10)) {
289 | tmpHighlighted.push($(this));
290 | }
291 | });
292 |
293 | var $toHighlight = tmpHighlighted[tmpHighlighted.length - 1];
294 |
295 | if ($toHighlight && !drag) {
296 | $('#feedback-canvas').css('cursor', 'pointer');
297 |
298 | var _x = $toHighlight.offset().left - 2,
299 | _y = $toHighlight.offset().top - 2,
300 | _w = $toHighlight.width() + parseInt($toHighlight.css('padding-left'), 10) + parseInt($toHighlight.css('padding-right'), 10) + 6,
301 | _h = $toHighlight.height() + parseInt($toHighlight.css('padding-top'), 10) + parseInt($toHighlight.css('padding-bottom'), 10) + 6;
302 |
303 | if (highlight == 1) {
304 | drawlines(ctx, _x, _y, _w, _h);
305 | ctx.clearRect(_x, _y, _w, _h);
306 | dtype = 'highlight';
307 | }
308 |
309 | $('.feedback-helper').each(function() {
310 | if ($(this).attr('data-type') == 'highlight')
311 | ctx.clearRect(parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height());
312 | });
313 |
314 | if (highlight == 0) {
315 | dtype = 'blackout';
316 | ctx.fillStyle = 'rgba(0,0,0,0.5)';
317 | ctx.fillRect(_x, _y, _w, _h);
318 | }
319 |
320 | $('.feedback-helper').each(function() {
321 | if ($(this).attr('data-type') == 'blackout') {
322 | ctx.fillStyle = 'rgba(0,0,0,1)';
323 | ctx.fillRect(parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height());
324 | }
325 | });
326 |
327 | if (e.type == 'click' && e.pageX == rect.startX && e.pageY == rect.startY) {
328 | $('#feedback-helpers').append('');
329 | highlighted.push(hidx);
330 | ++hidx;
331 | redraw(ctx);
332 | }
333 | }
334 | }
335 | });
336 | }
337 |
338 | $(document).on('mouseleave', 'body,#feedback-canvas', function() {
339 | redraw(ctx);
340 | });
341 |
342 | $(document).on('mouseenter', '.feedback-helper', function() {
343 | redraw(ctx);
344 | });
345 |
346 | $(document).on('click', '#feedback-welcome-next', function() {
347 | if ($('#feedback-note').val().length > 0) {
348 | canDraw = true;
349 | $('#feedback-canvas').css('cursor', 'crosshair');
350 | $('#feedback-helpers').show();
351 | $('#feedback-welcome').hide();
352 | $('#feedback-highlighter').show();
353 | }
354 | else {
355 | $('#feedback-welcome-error').show();
356 | }
357 | });
358 |
359 | $(document).on('mouseenter mouseleave', '.feedback-helper', function(e) {
360 | if (drag)
361 | return;
362 |
363 | rect.w = 0;
364 | rect.h = 0;
365 |
366 | if (e.type === 'mouseenter') {
367 | $(this).css('z-index', '30001');
368 | $(this).append('');
369 | $(this).append('');
370 | $(this).find('#feedback-close').css({
371 | 'top' : -1 * ($(this).find('#feedback-close').height() / 2) + 'px',
372 | 'left' : $(this).width() - ($(this).find('#feedback-close').width() / 2) + 'px'
373 | });
374 |
375 | if ($(this).attr('data-type') == 'blackout') {
376 | /* redraw white */
377 | ctx.clearRect(0, 0, $('#feedback-canvas').width(), $('#feedback-canvas').height());
378 | ctx.fillStyle = 'rgba(102,102,102,0.5)';
379 | ctx.fillRect(0, 0, $('#feedback-canvas').width(), $('#feedback-canvas').height());
380 | $('.feedback-helper').each(function() {
381 | if ($(this).attr('data-type') == 'highlight')
382 | drawlines(ctx, parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height());
383 | });
384 | $('.feedback-helper').each(function() {
385 | if ($(this).attr('data-type') == 'highlight')
386 | ctx.clearRect(parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height());
387 | });
388 |
389 | ctx.clearRect(parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height())
390 | ctx.fillStyle = 'rgba(0,0,0,0.75)';
391 | ctx.fillRect(parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height());
392 |
393 | ignore = $(this).attr('data-time');
394 |
395 | /* redraw black */
396 | $('.feedback-helper').each(function() {
397 | if ($(this).attr('data-time') == ignore)
398 | return true;
399 | if ($(this).attr('data-type') == 'blackout') {
400 | ctx.fillStyle = 'rgba(0,0,0,1)';
401 | ctx.fillRect(parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height())
402 | }
403 | });
404 | }
405 | }
406 | else {
407 | $(this).css('z-index','30000');
408 | $(this).children().remove();
409 | if ($(this).attr('data-type') == 'blackout') {
410 | redraw(ctx);
411 | }
412 | }
413 | });
414 |
415 | $(document).on('click', '#feedback-close', function() {
416 | if (settings.highlightElement && $(this).parent().attr('data-highlight-id'))
417 | var _hidx = $(this).parent().attr('data-highlight-id');
418 |
419 | $(this).parent().remove();
420 |
421 | if (settings.highlightElement && _hidx)
422 | $('[data-highlight-id="' + _hidx + '"]').removeAttr('data-highlighted').removeAttr('data-highlight-id');
423 |
424 | redraw(ctx);
425 | });
426 |
427 | $('#feedback-module').on('click', '.feedback-wizard-close,.feedback-close-btn', function() {
428 | close();
429 | });
430 |
431 | $(document).on('keyup', function(e) {
432 | if (e.keyCode == 27)
433 | close();
434 | });
435 |
436 | $(document).on('selectstart dragstart', document, function(e) {
437 | e.preventDefault();
438 | });
439 |
440 | $(document).on('click', '#feedback-highlighter-back', function() {
441 | canDraw = false;
442 | $('#feedback-canvas').css('cursor', 'default');
443 | $('#feedback-helpers').hide();
444 | $('#feedback-highlighter').hide();
445 | $('#feedback-welcome-error').hide();
446 | $('#feedback-welcome').show();
447 | });
448 |
449 | $(document).on('mousedown', '.feedback-sethighlight', function() {
450 | highlight = 1;
451 | $(this).addClass('feedback-active');
452 | $('.feedback-setblackout').removeClass('feedback-active');
453 | });
454 |
455 | $(document).on('mousedown', '.feedback-setblackout', function() {
456 | highlight = 0;
457 | $(this).addClass('feedback-active');
458 | $('.feedback-sethighlight').removeClass('feedback-active');
459 | });
460 |
461 | $(document).on('click', '#feedback-highlighter-next', function() {
462 | canDraw = false;
463 | $('#feedback-canvas').css('cursor', 'default');
464 | var sy = $(document).scrollTop(),
465 | dh = $(window).height();
466 | $('#feedback-helpers').hide();
467 | $('#feedback-highlighter').hide();
468 | if (!settings.screenshotStroke) {
469 | redraw(ctx, false);
470 | }
471 | html2canvas($('body'), {
472 | onrendered: function(canvas) {
473 | if (!settings.screenshotStroke) {
474 | redraw(ctx);
475 | }
476 | _canvas = $('').hide().appendTo('body');
477 | _ctx = _canvas.get(0).getContext('2d');
478 | _ctx.drawImage(canvas, 0, sy, w, dh, 0, 0, w, dh);
479 | img = _canvas.get(0).toDataURL();
480 | $(document).scrollTop(sy);
481 | post.img = img;
482 | settings.onScreenshotTaken(post.img);
483 | if(settings.showDescriptionModal) {
484 | $('#feedback-canvas-tmp').remove();
485 | $('#feedback-overview').show();
486 | $('#feedback-overview-description-text>textarea').remove();
487 | $('#feedback-overview-screenshot>img').remove();
488 | $('').insertAfter('#feedback-overview-description-text h3:eq(0)');
489 | $('#feedback-overview-screenshot').append('
');
490 | }
491 | else {
492 | $('#feedback-module').remove();
493 | close();
494 | _canvas.remove();
495 | }
496 | },
497 | proxy: settings.proxy,
498 | letterRendering: settings.letterRendering
499 | });
500 | });
501 |
502 | $(document).on('click', '#feedback-overview-back', function(e) {
503 | canDraw = true;
504 | $('#feedback-canvas').css('cursor', 'crosshair');
505 | $('#feedback-overview').hide();
506 | $('#feedback-helpers').show();
507 | $('#feedback-highlighter').show();
508 | $('#feedback-overview-error').hide();
509 | });
510 |
511 | $(document).on('keyup', '#feedback-note-tmp,#feedback-overview-note', function(e) {
512 | var tx;
513 | if (e.target.id === 'feedback-note-tmp')
514 | tx = $('#feedback-note-tmp').val();
515 | else {
516 | tx = $('#feedback-overview-note').val();
517 | $('#feedback-note-tmp').val(tx);
518 | }
519 |
520 | $('#feedback-note').val(tx);
521 | });
522 |
523 | $(document).on('click', '#feedback-submit', function() {
524 | canDraw = false;
525 |
526 | if ($('#feedback-note').val().length > 0) {
527 | $('#feedback-submit-success,#feedback-submit-error').remove();
528 | $('#feedback-overview').hide();
529 |
530 | post.img = img;
531 | post.note = $('#feedback-note').val();
532 | var data = {feedback: post};
533 | var jsonData = JSON.stringify(data);
534 | $.ajax({
535 | url: typeof settings.ajaxURL === 'function' ? settings.ajaxURL() : settings.ajaxURL,
536 | dataType: 'json',
537 | contentType: 'application/json',
538 | type: 'POST',
539 | data: jsonData,
540 | headers: {
541 | 'Content-Type': 'application/json'
542 | },
543 | success: function() {
544 | $('#feedback-module').append(settings.tpl.submitSuccess);
545 | },
546 | error: function(){
547 | $('#feedback-module').append(settings.tpl.submitError);
548 | }
549 | });
550 | }
551 | else {
552 | $('#feedback-overview-error').show();
553 | }
554 | });
555 | });
556 | }
557 |
558 | function close() {
559 | canDraw = false;
560 | $(document).off('mouseenter mouseleave', '.feedback-helper');
561 | $(document).off('mouseup keyup');
562 | $(document).off('mousedown', '.feedback-setblackout');
563 | $(document).off('mousedown', '.feedback-sethighlight');
564 | $(document).off('mousedown click', '#feedback-close');
565 | $(document).off('mousedown', '#feedback-canvas');
566 | $(document).off('click', '#feedback-highlighter-next');
567 | $(document).off('click', '#feedback-highlighter-back');
568 | $(document).off('click', '#feedback-welcome-next');
569 | $(document).off('click', '#feedback-overview-back');
570 | $(document).off('mouseleave', 'body');
571 | $(document).off('mouseenter', '.feedback-helper');
572 | $(document).off('selectstart dragstart', document);
573 | $('#feedback-module').off('click', '.feedback-wizard-close,.feedback-close-btn');
574 | $(document).off('click', '#feedback-submit');
575 |
576 | if (settings.highlightElement) {
577 | $(document).off('click', '#feedback-canvas');
578 | $(document).off('mousemove', '#feedback-canvas');
579 | }
580 | $('[data-highlighted="true"]').removeAttr('data-highlight-id').removeAttr('data-highlighted');
581 | $('#feedback-module').remove();
582 | $('.feedback-btn').show();
583 |
584 | settings.onClose.call(this);
585 | }
586 |
587 | function redraw(ctx, border) {
588 | border = typeof border !== 'undefined' ? border : true;
589 | ctx.clearRect(0, 0, $('#feedback-canvas').width(), $('#feedback-canvas').height());
590 | ctx.fillStyle = 'rgba(102,102,102,0.5)';
591 | ctx.fillRect(0, 0, $('#feedback-canvas').width(), $('#feedback-canvas').height());
592 | $('.feedback-helper').each(function() {
593 | if ($(this).attr('data-type') == 'highlight')
594 | if (border)
595 | drawlines(ctx, parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height());
596 | });
597 | $('.feedback-helper').each(function() {
598 | if ($(this).attr('data-type') == 'highlight')
599 | ctx.clearRect(parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height());
600 | });
601 | $('.feedback-helper').each(function() {
602 | if ($(this).attr('data-type') == 'blackout') {
603 | ctx.fillStyle = 'rgba(0,0,0,1)';
604 | ctx.fillRect(parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height());
605 | }
606 | });
607 | }
608 |
609 | function drawlines(ctx, x, y, w, h) {
610 | ctx.strokeStyle = settings.strokeStyle;
611 | ctx.shadowColor = settings.shadowColor;
612 | ctx.shadowOffsetX = settings.shadowOffsetX;
613 | ctx.shadowOffsetY = settings.shadowOffsetY;
614 | ctx.shadowBlur = settings.shadowBlur;
615 | ctx.lineJoin = settings.lineJoin;
616 | ctx.lineWidth = settings.lineWidth;
617 |
618 | ctx.strokeRect(x,y,w,h);
619 |
620 | ctx.shadowOffsetX = 0;
621 | ctx.shadowOffsetY = 0;
622 | ctx.shadowBlur = 0;
623 | ctx.lineWidth = 1;
624 | }
625 |
626 | };
627 |
628 | }(jQuery));
629 |
630 |
631 | jQuery.feedback($scope.options);
632 |
633 |
634 |
635 | }
636 | };
637 | }]);
638 |
--------------------------------------------------------------------------------
/dist/angular-send-feedback.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Angular feedback directive similar to Google Feedback
3 | * @version v1.2.0 - 2016-06-28 * @link https://github.com/jacobscarter/angular-feedback
4 | * @author Jacob Carter
5 | * @license MIT License, http://www.opensource.org/licenses/MIT
6 | */
7 | angular.module('templates-angularsendfeedback', ['angularsendfeedback.html']);
8 |
9 | angular.module("angularsendfeedback.html", []).run(["$templateCache", function($templateCache) {
10 | $templateCache.put("angularsendfeedback.html",
11 | "");
12 | }]);
13 |
14 | angular.module('angular-send-feedback', ['templates-angularsendfeedback']);
15 |
16 | angular.module('angular-send-feedback').directive('angularFeedback', [ function() {
17 |
18 |
19 | return {
20 | restrict: 'EA',
21 | replace: true,
22 | transclude: true,
23 | scope: {
24 | options : '='
25 | },
26 | //templateUrl: function(element, attributes) {
27 | //return attributes.template || "angularsendfeedback.html";
28 | //},
29 | link: function($scope, $element, $attrs) {
30 |
31 | (function($){
32 |
33 | $.feedback = function(options) {
34 |
35 | var settings = $.extend({
36 | ajaxURL: '',
37 | postBrowserInfo: true,
38 | postHTML: true,
39 | postURL: true,
40 | postTimeStamp: true,
41 | proxy: undefined,
42 | letterRendering: false,
43 | initButtonText: 'Send feedback',
44 | strokeStyle: 'black',
45 | shadowColor: 'black',
46 | shadowOffsetX: 1,
47 | shadowOffsetY: 1,
48 | shadowBlur: 10,
49 | lineJoin: 'bevel',
50 | lineWidth: 3,
51 | html2canvasURL: 'html2canvas.js',
52 | feedbackButton: '.feedback-btn',
53 | showDescriptionModal: true,
54 | isDraggable: true,
55 | onScreenshotTaken: function(){},
56 | tpl: {
57 | initButton: '',
58 | description: 'Feedback
Feedback lets you send us suggestions about our products. We welcome problem reports, feature ideas and general comments.
Start by writing a brief description:
Next we\'ll let you identify areas of the page related to your description.
Please enter a description.
',
59 | highlighter: 'Feedback
Click and drag on the page to help us better understand your feedback. You can move this dialog if it\'s in the way.
',
60 | overview: 'Feedback
Description
Additional info
None
Browser Info
Page Info
Time Stamp
Page Structure
Screenshot
Please enter a description.
',
61 | submitSuccess: 'Feedback
Thank you for your feedback. We value every piece of feedback we receive.
We cannot respond individually to every one, but we will use your comments as we strive to improve your experience.
',
62 | submitError: 'Feedback
Sadly an error occurred while sending your feedback. Please try again.
'
63 | },
64 | onClose: function() {},
65 | screenshotStroke: true,
66 | highlightElement: true,
67 | initialBox: false
68 | }, options);
69 | var supportedBrowser = !!window.HTMLCanvasElement;
70 | var isFeedbackButtonNative = settings.feedbackButton == '.feedback-btn';
71 | var _html2canvas = false;
72 | if (supportedBrowser) {
73 | if(isFeedbackButtonNative) {
74 | $('body').append(settings.tpl.initButton);
75 | }
76 | $(document).on('click', settings.feedbackButton, function(){
77 | if(isFeedbackButtonNative) {
78 | $(this).hide();
79 | }
80 | if (!_html2canvas) {
81 | $.getScript(settings.html2canvasURL, function() {
82 | _html2canvas = true;
83 | });
84 | }
85 | var canDraw = false,
86 | img = '',
87 | h = $(document).height(),
88 | w = $(document).width(),
89 | tpl = '';
90 |
91 | if (settings.initialBox) {
92 | tpl += settings.tpl.description;
93 | }
94 |
95 | tpl += settings.tpl.highlighter + settings.tpl.overview + '
';
96 |
97 | $('body').append(tpl);
98 |
99 | moduleStyle = {
100 | 'position': 'absolute',
101 | 'left': '0px',
102 | 'top': '0px'
103 | };
104 | canvasAttr = {
105 | 'width': w,
106 | 'height': h
107 | };
108 |
109 | $('#feedback-module').css(moduleStyle);
110 | $('#feedback-canvas').attr(canvasAttr).css('z-index', '30000');
111 |
112 | if (!settings.initialBox) {
113 | $('#feedback-highlighter-back').remove();
114 | canDraw = true;
115 | $('#feedback-canvas').css('cursor', 'crosshair');
116 | $('#feedback-helpers').show();
117 | $('#feedback-welcome').hide();
118 | $('#feedback-highlighter').show();
119 | }
120 |
121 | if(settings.isDraggable) {
122 | $('#feedback-highlighter').on('mousedown', function(e) {
123 | var $d = $(this).addClass('feedback-draggable'),
124 | drag_h = $d.outerHeight(),
125 | drag_w = $d.outerWidth(),
126 | pos_y = $d.offset().top + drag_h - e.pageY,
127 | pos_x = $d.offset().left + drag_w - e.pageX;
128 | $d.css('z-index', 40000).parents().on('mousemove', function(e) {
129 | _top = e.pageY + pos_y - drag_h;
130 | _left = e.pageX + pos_x - drag_w;
131 | _bottom = drag_h - e.pageY;
132 | _right = drag_w - e.pageX;
133 |
134 | if (_left < 0) _left = 0;
135 | if (_top < 0) _top = 0;
136 | if (_right > $(window).width())
137 | _left = $(window).width() - drag_w;
138 | if (_left > $(window).width() - drag_w)
139 | _left = $(window).width() - drag_w;
140 | if (_bottom > $(document).height())
141 | _top = $(document).height() - drag_h;
142 | if (_top > $(document).height() - drag_h)
143 | _top = $(document).height() - drag_h;
144 |
145 | $('.feedback-draggable').offset({
146 | top: _top,
147 | left: _left
148 | }).on("mouseup", function() {
149 | $(this).removeClass('feedback-draggable');
150 | });
151 | });
152 | e.preventDefault();
153 | }).on('mouseup', function(){
154 | $(this).removeClass('feedback-draggable');
155 | $(this).parents().off('mousemove mousedown');
156 | });
157 | }
158 |
159 | var ctx = $('#feedback-canvas')[0].getContext('2d');
160 |
161 | ctx.fillStyle = 'rgba(102,102,102,0.5)';
162 | ctx.fillRect(0, 0, $('#feedback-canvas').width(), $('#feedback-canvas').height());
163 |
164 | rect = {};
165 | drag = false;
166 | highlight = 1,
167 | post = {};
168 |
169 | if (settings.postBrowserInfo) {
170 | post.browser = {};
171 | post.browser.appCodeName = navigator.appCodeName;
172 | post.browser.appName = navigator.appName;
173 | post.browser.appVersion = navigator.appVersion;
174 | post.browser.cookieEnabled = navigator.cookieEnabled;
175 | post.browser.onLine = navigator.onLine;
176 | post.browser.platform = navigator.platform;
177 | post.browser.userAgent = navigator.userAgent;
178 | post.browser.plugins = [];
179 |
180 | $.each(navigator.plugins, function(i) {
181 | post.browser.plugins.push(navigator.plugins[i].name);
182 | });
183 | $('#feedback-browser-info').show();
184 | }
185 |
186 | if (settings.postURL) {
187 | post.url = document.URL;
188 | $('#feedback-page-info').show();
189 | }
190 |
191 | if (settings.postTimeStamp) {
192 | post.timestamp = new Date().getTime();
193 | $('#feedback-timestamp').show();
194 | }
195 |
196 | if (settings.postHTML) {
197 | post.html = $('html').html();
198 | $('#feedback-page-structure').show();
199 | }
200 |
201 | if (!settings.postBrowserInfo && !settings.postURL && !settings.postHTML)
202 | $('#feedback-additional-none').show();
203 |
204 | $(document).on('mousedown', '#feedback-canvas', function(e) {
205 | if (canDraw) {
206 |
207 | rect.startX = e.pageX - $(this).offset().left;
208 | rect.startY = e.pageY - $(this).offset().top;
209 | rect.w = 0;
210 | rect.h = 0;
211 | drag = true;
212 | }
213 | });
214 |
215 | $(document).on('mouseup', function(){
216 | if (canDraw) {
217 | drag = false;
218 |
219 | var dtop = rect.startY,
220 | dleft = rect.startX,
221 | dwidth = rect.w,
222 | dheight = rect.h;
223 | dtype = 'highlight';
224 |
225 | if (dwidth == 0 || dheight == 0) return;
226 |
227 | if (dwidth < 0) {
228 | dleft += dwidth;
229 | dwidth *= -1;
230 | }
231 | if (dheight < 0) {
232 | dtop += dheight;
233 | dheight *= -1;
234 | }
235 |
236 | if (dtop + dheight > $(document).height())
237 | dheight = $(document).height() - dtop;
238 | if (dleft + dwidth > $(document).width())
239 | dwidth = $(document).width() - dleft;
240 |
241 | if (highlight == 0)
242 | dtype = 'blackout';
243 |
244 | $('#feedback-helpers').append('');
245 |
246 | redraw(ctx);
247 | rect.w = 0;
248 | }
249 |
250 | });
251 |
252 | $(document).on('mousemove', function(e) {
253 | if (canDraw && drag) {
254 | $('#feedback-highlighter').css('cursor', 'default');
255 |
256 | rect.w = (e.pageX - $('#feedback-canvas').offset().left) - rect.startX;
257 | rect.h = (e.pageY - $('#feedback-canvas').offset().top) - rect.startY;
258 |
259 | ctx.clearRect(0, 0, $('#feedback-canvas').width(), $('#feedback-canvas').height());
260 | ctx.fillStyle = 'rgba(102,102,102,0.5)';
261 | ctx.fillRect(0, 0, $('#feedback-canvas').width(), $('#feedback-canvas').height());
262 | $('.feedback-helper').each(function() {
263 | if ($(this).attr('data-type') == 'highlight')
264 | drawlines(ctx, parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height());
265 | });
266 | if (highlight==1) {
267 | drawlines(ctx, rect.startX, rect.startY, rect.w, rect.h);
268 | ctx.clearRect(rect.startX, rect.startY, rect.w, rect.h);
269 | }
270 | $('.feedback-helper').each(function() {
271 | if ($(this).attr('data-type') == 'highlight')
272 | ctx.clearRect(parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height());
273 | });
274 | $('.feedback-helper').each(function() {
275 | if ($(this).attr('data-type') == 'blackout') {
276 | ctx.fillStyle = 'rgba(0,0,0,1)';
277 | ctx.fillRect(parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height())
278 | }
279 | });
280 | if (highlight == 0) {
281 | ctx.fillStyle = 'rgba(0,0,0,0.5)';
282 | ctx.fillRect(rect.startX, rect.startY, rect.w, rect.h);
283 | }
284 | }
285 | });
286 |
287 | if (settings.highlightElement) {
288 | var highlighted = [],
289 | tmpHighlighted = [],
290 | hidx = 0;
291 |
292 | $(document).on('mousemove click', '#feedback-canvas',function(e) {
293 | if (canDraw) {
294 | redraw(ctx);
295 | tmpHighlighted = [];
296 |
297 | $('#feedback-canvas').css('cursor', 'crosshair');
298 |
299 | $('* :not(body,script,iframe,div,section,.feedback-btn,#feedback-module *)').each(function(){
300 | if ($(this).attr('data-highlighted') === 'true')
301 | return;
302 |
303 | if (e.pageX > $(this).offset().left && e.pageX < $(this).offset().left + $(this).width() && e.pageY > $(this).offset().top + parseInt($(this).css('padding-top'), 10) && e.pageY < $(this).offset().top + $(this).height() + parseInt($(this).css('padding-top'), 10)) {
304 | tmpHighlighted.push($(this));
305 | }
306 | });
307 |
308 | var $toHighlight = tmpHighlighted[tmpHighlighted.length - 1];
309 |
310 | if ($toHighlight && !drag) {
311 | $('#feedback-canvas').css('cursor', 'pointer');
312 |
313 | var _x = $toHighlight.offset().left - 2,
314 | _y = $toHighlight.offset().top - 2,
315 | _w = $toHighlight.width() + parseInt($toHighlight.css('padding-left'), 10) + parseInt($toHighlight.css('padding-right'), 10) + 6,
316 | _h = $toHighlight.height() + parseInt($toHighlight.css('padding-top'), 10) + parseInt($toHighlight.css('padding-bottom'), 10) + 6;
317 |
318 | if (highlight == 1) {
319 | drawlines(ctx, _x, _y, _w, _h);
320 | ctx.clearRect(_x, _y, _w, _h);
321 | dtype = 'highlight';
322 | }
323 |
324 | $('.feedback-helper').each(function() {
325 | if ($(this).attr('data-type') == 'highlight')
326 | ctx.clearRect(parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height());
327 | });
328 |
329 | if (highlight == 0) {
330 | dtype = 'blackout';
331 | ctx.fillStyle = 'rgba(0,0,0,0.5)';
332 | ctx.fillRect(_x, _y, _w, _h);
333 | }
334 |
335 | $('.feedback-helper').each(function() {
336 | if ($(this).attr('data-type') == 'blackout') {
337 | ctx.fillStyle = 'rgba(0,0,0,1)';
338 | ctx.fillRect(parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height());
339 | }
340 | });
341 |
342 | if (e.type == 'click' && e.pageX == rect.startX && e.pageY == rect.startY) {
343 | $('#feedback-helpers').append('');
344 | highlighted.push(hidx);
345 | ++hidx;
346 | redraw(ctx);
347 | }
348 | }
349 | }
350 | });
351 | }
352 |
353 | $(document).on('mouseleave', 'body,#feedback-canvas', function() {
354 | redraw(ctx);
355 | });
356 |
357 | $(document).on('mouseenter', '.feedback-helper', function() {
358 | redraw(ctx);
359 | });
360 |
361 | $(document).on('click', '#feedback-welcome-next', function() {
362 | if ($('#feedback-note').val().length > 0) {
363 | canDraw = true;
364 | $('#feedback-canvas').css('cursor', 'crosshair');
365 | $('#feedback-helpers').show();
366 | $('#feedback-welcome').hide();
367 | $('#feedback-highlighter').show();
368 | }
369 | else {
370 | $('#feedback-welcome-error').show();
371 | }
372 | });
373 |
374 | $(document).on('mouseenter mouseleave', '.feedback-helper', function(e) {
375 | if (drag)
376 | return;
377 |
378 | rect.w = 0;
379 | rect.h = 0;
380 |
381 | if (e.type === 'mouseenter') {
382 | $(this).css('z-index', '30001');
383 | $(this).append('');
384 | $(this).append('');
385 | $(this).find('#feedback-close').css({
386 | 'top' : -1 * ($(this).find('#feedback-close').height() / 2) + 'px',
387 | 'left' : $(this).width() - ($(this).find('#feedback-close').width() / 2) + 'px'
388 | });
389 |
390 | if ($(this).attr('data-type') == 'blackout') {
391 | /* redraw white */
392 | ctx.clearRect(0, 0, $('#feedback-canvas').width(), $('#feedback-canvas').height());
393 | ctx.fillStyle = 'rgba(102,102,102,0.5)';
394 | ctx.fillRect(0, 0, $('#feedback-canvas').width(), $('#feedback-canvas').height());
395 | $('.feedback-helper').each(function() {
396 | if ($(this).attr('data-type') == 'highlight')
397 | drawlines(ctx, parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height());
398 | });
399 | $('.feedback-helper').each(function() {
400 | if ($(this).attr('data-type') == 'highlight')
401 | ctx.clearRect(parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height());
402 | });
403 |
404 | ctx.clearRect(parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height())
405 | ctx.fillStyle = 'rgba(0,0,0,0.75)';
406 | ctx.fillRect(parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height());
407 |
408 | ignore = $(this).attr('data-time');
409 |
410 | /* redraw black */
411 | $('.feedback-helper').each(function() {
412 | if ($(this).attr('data-time') == ignore)
413 | return true;
414 | if ($(this).attr('data-type') == 'blackout') {
415 | ctx.fillStyle = 'rgba(0,0,0,1)';
416 | ctx.fillRect(parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height())
417 | }
418 | });
419 | }
420 | }
421 | else {
422 | $(this).css('z-index','30000');
423 | $(this).children().remove();
424 | if ($(this).attr('data-type') == 'blackout') {
425 | redraw(ctx);
426 | }
427 | }
428 | });
429 |
430 | $(document).on('click', '#feedback-close', function() {
431 | if (settings.highlightElement && $(this).parent().attr('data-highlight-id'))
432 | var _hidx = $(this).parent().attr('data-highlight-id');
433 |
434 | $(this).parent().remove();
435 |
436 | if (settings.highlightElement && _hidx)
437 | $('[data-highlight-id="' + _hidx + '"]').removeAttr('data-highlighted').removeAttr('data-highlight-id');
438 |
439 | redraw(ctx);
440 | });
441 |
442 | $('#feedback-module').on('click', '.feedback-wizard-close,.feedback-close-btn', function() {
443 | close();
444 | });
445 |
446 | $(document).on('keyup', function(e) {
447 | if (e.keyCode == 27)
448 | close();
449 | });
450 |
451 | $(document).on('selectstart dragstart', document, function(e) {
452 | e.preventDefault();
453 | });
454 |
455 | $(document).on('click', '#feedback-highlighter-back', function() {
456 | canDraw = false;
457 | $('#feedback-canvas').css('cursor', 'default');
458 | $('#feedback-helpers').hide();
459 | $('#feedback-highlighter').hide();
460 | $('#feedback-welcome-error').hide();
461 | $('#feedback-welcome').show();
462 | });
463 |
464 | $(document).on('mousedown', '.feedback-sethighlight', function() {
465 | highlight = 1;
466 | $(this).addClass('feedback-active');
467 | $('.feedback-setblackout').removeClass('feedback-active');
468 | });
469 |
470 | $(document).on('mousedown', '.feedback-setblackout', function() {
471 | highlight = 0;
472 | $(this).addClass('feedback-active');
473 | $('.feedback-sethighlight').removeClass('feedback-active');
474 | });
475 |
476 | $(document).on('click', '#feedback-highlighter-next', function() {
477 | canDraw = false;
478 | $('#feedback-canvas').css('cursor', 'default');
479 | var sy = $(document).scrollTop(),
480 | dh = $(window).height();
481 | $('#feedback-helpers').hide();
482 | $('#feedback-highlighter').hide();
483 | if (!settings.screenshotStroke) {
484 | redraw(ctx, false);
485 | }
486 | html2canvas($('body'), {
487 | onrendered: function(canvas) {
488 | if (!settings.screenshotStroke) {
489 | redraw(ctx);
490 | }
491 | _canvas = $('').hide().appendTo('body');
492 | _ctx = _canvas.get(0).getContext('2d');
493 | _ctx.drawImage(canvas, 0, sy, w, dh, 0, 0, w, dh);
494 | img = _canvas.get(0).toDataURL();
495 | $(document).scrollTop(sy);
496 | post.img = img;
497 | settings.onScreenshotTaken(post.img);
498 | if(settings.showDescriptionModal) {
499 | $('#feedback-canvas-tmp').remove();
500 | $('#feedback-overview').show();
501 | $('#feedback-overview-description-text>textarea').remove();
502 | $('#feedback-overview-screenshot>img').remove();
503 | $('').insertAfter('#feedback-overview-description-text h3:eq(0)');
504 | $('#feedback-overview-screenshot').append('
');
505 | }
506 | else {
507 | $('#feedback-module').remove();
508 | close();
509 | _canvas.remove();
510 | }
511 | },
512 | proxy: settings.proxy,
513 | letterRendering: settings.letterRendering
514 | });
515 | });
516 |
517 | $(document).on('click', '#feedback-overview-back', function(e) {
518 | canDraw = true;
519 | $('#feedback-canvas').css('cursor', 'crosshair');
520 | $('#feedback-overview').hide();
521 | $('#feedback-helpers').show();
522 | $('#feedback-highlighter').show();
523 | $('#feedback-overview-error').hide();
524 | });
525 |
526 | $(document).on('keyup', '#feedback-note-tmp,#feedback-overview-note', function(e) {
527 | var tx;
528 | if (e.target.id === 'feedback-note-tmp')
529 | tx = $('#feedback-note-tmp').val();
530 | else {
531 | tx = $('#feedback-overview-note').val();
532 | $('#feedback-note-tmp').val(tx);
533 | }
534 |
535 | $('#feedback-note').val(tx);
536 | });
537 |
538 | $(document).on('click', '#feedback-submit', function() {
539 | canDraw = false;
540 |
541 | if ($('#feedback-note').val().length > 0) {
542 | $('#feedback-submit-success,#feedback-submit-error').remove();
543 | $('#feedback-overview').hide();
544 |
545 | post.img = img;
546 | post.note = $('#feedback-note').val();
547 | var data = {feedback: post};
548 | var jsonData = JSON.stringify(data);
549 | $.ajax({
550 | url: typeof settings.ajaxURL === 'function' ? settings.ajaxURL() : settings.ajaxURL,
551 | dataType: 'json',
552 | contentType: 'application/json',
553 | type: 'POST',
554 | data: jsonData,
555 | headers: {
556 | 'Content-Type': 'application/json'
557 | },
558 | success: function() {
559 | $('#feedback-module').append(settings.tpl.submitSuccess);
560 | },
561 | error: function(){
562 | $('#feedback-module').append(settings.tpl.submitError);
563 | }
564 | });
565 | }
566 | else {
567 | $('#feedback-overview-error').show();
568 | }
569 | });
570 | });
571 | }
572 |
573 | function close() {
574 | canDraw = false;
575 | $(document).off('mouseenter mouseleave', '.feedback-helper');
576 | $(document).off('mouseup keyup');
577 | $(document).off('mousedown', '.feedback-setblackout');
578 | $(document).off('mousedown', '.feedback-sethighlight');
579 | $(document).off('mousedown click', '#feedback-close');
580 | $(document).off('mousedown', '#feedback-canvas');
581 | $(document).off('click', '#feedback-highlighter-next');
582 | $(document).off('click', '#feedback-highlighter-back');
583 | $(document).off('click', '#feedback-welcome-next');
584 | $(document).off('click', '#feedback-overview-back');
585 | $(document).off('mouseleave', 'body');
586 | $(document).off('mouseenter', '.feedback-helper');
587 | $(document).off('selectstart dragstart', document);
588 | $('#feedback-module').off('click', '.feedback-wizard-close,.feedback-close-btn');
589 | $(document).off('click', '#feedback-submit');
590 |
591 | if (settings.highlightElement) {
592 | $(document).off('click', '#feedback-canvas');
593 | $(document).off('mousemove', '#feedback-canvas');
594 | }
595 | $('[data-highlighted="true"]').removeAttr('data-highlight-id').removeAttr('data-highlighted');
596 | $('#feedback-module').remove();
597 | $('.feedback-btn').show();
598 |
599 | settings.onClose.call(this);
600 | }
601 |
602 | function redraw(ctx, border) {
603 | border = typeof border !== 'undefined' ? border : true;
604 | ctx.clearRect(0, 0, $('#feedback-canvas').width(), $('#feedback-canvas').height());
605 | ctx.fillStyle = 'rgba(102,102,102,0.5)';
606 | ctx.fillRect(0, 0, $('#feedback-canvas').width(), $('#feedback-canvas').height());
607 | $('.feedback-helper').each(function() {
608 | if ($(this).attr('data-type') == 'highlight')
609 | if (border)
610 | drawlines(ctx, parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height());
611 | });
612 | $('.feedback-helper').each(function() {
613 | if ($(this).attr('data-type') == 'highlight')
614 | ctx.clearRect(parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height());
615 | });
616 | $('.feedback-helper').each(function() {
617 | if ($(this).attr('data-type') == 'blackout') {
618 | ctx.fillStyle = 'rgba(0,0,0,1)';
619 | ctx.fillRect(parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height());
620 | }
621 | });
622 | }
623 |
624 | function drawlines(ctx, x, y, w, h) {
625 | ctx.strokeStyle = settings.strokeStyle;
626 | ctx.shadowColor = settings.shadowColor;
627 | ctx.shadowOffsetX = settings.shadowOffsetX;
628 | ctx.shadowOffsetY = settings.shadowOffsetY;
629 | ctx.shadowBlur = settings.shadowBlur;
630 | ctx.lineJoin = settings.lineJoin;
631 | ctx.lineWidth = settings.lineWidth;
632 |
633 | ctx.strokeRect(x,y,w,h);
634 |
635 | ctx.shadowOffsetX = 0;
636 | ctx.shadowOffsetY = 0;
637 | ctx.shadowBlur = 0;
638 | ctx.lineWidth = 1;
639 | }
640 |
641 | };
642 |
643 | }(jQuery));
644 |
645 |
646 | jQuery.feedback($scope.options);
647 |
648 |
649 |
650 | }
651 | };
652 | }]);
653 |
--------------------------------------------------------------------------------