PageSourceSearch

https://opentutorials.org/static/js/desktop/comment.js?4

js opentutorials.org collected 2026-09-24 08:43:08 UTC 21,674 bytes, 574 lines download raw bytes

1// 코멘트 액션
2(function($) {
3  var cmtContentWithoutLogin, dialogDelete, filterComment, form, list, options, page, replyIndicator, target;
4  form = $('form#comment_new_form');
5  list = $('#comment_list');
6  replyIndicator = $('#reply_indicator');
7  cmtContentWithoutLogin = $('#cmt_content_without_login');
8  page = 1;
9  dialogDelete = new ConfirmDialog();
10  dialogDelete.unstage();
11  dialogDelete.pin();
12  dialogDelete.whitify();
13  $.support.touch = document.ontouchend !== void 0;
14  if ($.support.touch) {
15    $(document.body).addClass('touch');
16  }
17  options = {
18    id: 'comment_delete_dialog',
19    modal: false,
20    width: 240,
21    label: {
22      positive: '삭제',
23      negative: '취소'
24    }
25  };
26  cmtContentWithoutLogin.on('click', function() {
27    return location.href = $(this).data('login-url');
28  });
29  $('textarea', form).on('focus', function() {
30    return form.addClass('extended');
31  });
32  replyIndicator.find('a.btn_unchain').on('click', function() {
33    replyIndicator.slideUp();
34    replyIndicator.find('input[name=parent]').val('');
35    $('div.column_left', form).css('visibility', 'visible');
36    return false;
37  });
38  form.on('submit', function() {
39    var content, data, indicator, password, text, username;
40    text = form.find('.comment_form_footer button span');
41    data = {
42      course_id: $('input[name=course_id]', form).val(),
43      module_id: $('input[name=module_id]', form).val(),
44      topic_id: $('input[name=topic_id]', form).val(),
45      is_question: $('input[name=is_question]:checked', form).size() ? 'yes' : 'no'
46    };
47    if (!user_id) {
48      username = $('input[name=username]', form).val();
49      password = $('input[type=password]', form).val();
50      if (username.length === 0) {
51        xalert(null, '이름을 입력해 주세요.', {
52          modal: true
53        });
54        return false;
55      } else if (password.length === 0) {
56        xalert(null, '비밀번호를 입력해 주세요.', {
57          modal: true
58        });
59        return false;
60      }
61      data.username = username;
62      data.password = password;
63    }
64    content = $('textarea', form).val();
65    if (content.length === 0) {
66      xalert(null, '댓글 내용을 입력해 주세요.', {
67        modal: true
68      });
69      return false;
70    }
71    indicator = new ProcessIndicator('#comment_new_form div.comment_form_footer button[type=submit]', PROCESSINDICATOR_TINY, '#fff');
72    indicator.start();
73    text.css('visibility', 'hidden');
74    data.content = content;
75    data.parent = replyIndicator.find('input[name=parent]').val();
76    ga('send', 'event', 'Participation', 'comment_add', path_context + (topic_id ? '/' + topic_id : '') + ', ' + document.title, {
77      useBeacon: true
78    });
79    $.post(form.attr('action'), data, function(response) {
80      var buttons, template;
81      if (response.result) {
82        template = $(`<li data-id="${response.data.id}" data-is-question="${response.data.is_question}">
83	<div class="profile_image">
84		<img class="profile_icon" data-id="${response.data.user_id}" src="${response.data.user_pict}" alt="">
85	</div>
86
87	<div class="name time">
88		<strong>${response.data.username}</strong><a name="comment${response.data.id}"><time datetime="${response.data.created.original}">${response.data.created.relative}</time></a>
89	</div>
90
91	<div class="comment_content">
92		${response.data.description}
93	</div>
94</li>`);
95        if (response.data.parent > 0) {
96          template.append(`<dl class="parents">
97	<dt><a href="#" data-parent="${response.data.parent}">대화보기</a><span></span></dt>
98	<dd>
99		<ul></ul>
100	</dd>
101</dl>`);
102        }
103        buttons = '<div class="buttons">';
104        if (user_id) {
105          if (user_id === response.data.user_id) {
106            buttons += `<a class="icon block reply" href="#"><span class="ico ico_reply"></span> 답글</a>|<a class="icon block edit" href="#"><span class="ico ico_modify"></span> 수정</a>|<a class="icon block delete" href="#" data-user_id="${response.data.user_id}"><span class="ico ico_close"></span> 삭제</a>`;
107          } else {
108            buttons += '<a class="icon block reply" href="#"><span class="ico ico_reply"></span> 답글</a>';
109          }
110        } else {
111          if (!response.data.user_id) {
112            buttons += '<a class="icon block reply" href="#"><span class="ico ico_reply"></span> 답글</a>|<a class="icon block edit" href="#"><span class="ico ico_modify"></span> 수정</a>|<a class="icon block delete" href="#" data-user_id="0"><span class="ico ico_close"></span> 삭제</a>';
113          } else {
114            buttons += '<a class="icon block reply" href="#"><span class="ico ico_reply"></span> 답글</a>';
115          }
116        }
117        buttons += '</div>';
118        template.append(buttons);
119        list.prepend(template.hide());
120        //setFlash template
121        template.slideDown();
122        $('dl input, dl textarea', form).val('');
123        replyIndicator.slideUp();
124      } else {
125        xalert(null, response.msg, {
126          modal: true
127        });
128      }
129      indicator.stop();
130      return text.css('visibility', 'visible');
131    }, 'json');
132    return false;
133  });
134  if (!$(document.body).hasClass('touch')) {
135    $(document).on('mouseenter', '#comment_list' + ' > li', function() {
136      return $(this).find('> div.buttons').fadeIn();
137    });
138    $(document).on('mouseleave', '#comment_list' + ' > li', function() {
139      $(this).find('> div.buttons').hide();
140      return $('#comment_delete_dialog').hide().remove();
141    });
142  }
143  $(document).on('click', '#comment_list' + ' > li > dl > dt a[data-parent]', function() {
144    var drawer, indicator, pointer;
145    drawer = $(this).parents('dl').find('dd');
146    if (drawer.is(':hidden')) {
147      if ($(this).data('loaded')) {
148        drawer.show();
149        $(this).text('대화닫기');
150      } else {
151        pointer = $(this).parent().find('span');
152        indicator = new ProcessIndicator(pointer, PROCESSINDICATOR_TINY);
153        indicator.start();
154        $.post(`${base_url}/comment/get_parents_ajax/` + $(this).data('parent'), (response) => {
155          var comment, i, index, len, point, ref;
156          if (response.errorCode) {
157            xalert(null, '정보를 가져오지 못했습니다.', {
158              modal: true
159            });
160          } else {
161            point = drawer.find('ul');
162            ref = response.data;
163            for (index = i = 0, len = ref.length; i < len; index = ++i) {
164              comment = ref[index];
165              if (comment.is_deleted === 'yes') {
166                point.append(`<li class="deleted"><div class="profile_image small"><img class="profile_icon" data-id="${comment.user_id}" src="${comment.user_pict}" alt=""></div>
167	<div class="comment_content small">
168		<span>${comment.description}</span>
169	</div>
170</li>`);
171              } else {
172                point.append(`<li><div class="profile_image small"><img class="profile_icon" data-id="${comment.user_id}" src="${comment.user_pict}" alt=""></div>
173	<div class="comment_content small">
174		<strong class="name">${htmlspecialchars(comment.name)}</strong>
175		<span>${comment.description}</span>
176		/ <a href="#comment${comment.id}"><time datetime="${comment.created.original}">${comment.created.relative}</time></a>
177	</div>
178</li>`);
179              }
180            }
181            $(this).data('loaded', true);
182            $(this).text('대화닫기');
183            drawer.show();
184          }
185          indicator.stop();
186          return pointer.text('');
187        }, 'json');
188      }
189    } else {
190      drawer.hide();
191      $(this).html('대화보기');
192    }
193    return false;
194  });
195  $(document).on('click', '#comment_list' + ' > li > div.buttons a.reply', function() {
196    var comment_id, offset, username;
197    comment_id = $(this).parents('li').data('id');
198    username = $(this).parents('li').find('div.name.time strong').text();
199    replyIndicator.slideDown().find('a:first').attr('href', '#comment' + comment_id).text(username + '님의 댓글에 대한 답글입니다.');
200    replyIndicator.find('input[name=parent]').val(comment_id);
201    offset = replyIndicator.offset();
202    $(window).scrollTop(offset.top - 10);
203    $('textarea', form).focus();
204    return false;
205  });
206  $(document).on('click', '#comment_list' + ' > li > div.buttons a.edit', function() {
207    var cmt_id, node;
208    node = $(this).parents('li');
209    cmt_id = node.data('id');
210    $.post(base_url + 'comment/check_editable_ajax/' + cmt_id, function(response) {
211      var _form;
212      if (response.result) {
213        _form = $(`<li class="comment_editor">
214	<form action="${base_url}comment/update_ajax" method="post">
215		<div class="profile_image">
216			<img src="${response.data.user_pict}" alt="">
217		</div>
218
219		<div class="form_wrapper">
220			<div class="name time">
221				<strong>${response.data.username}</strong><time datetime="${response.data.created.original}">${response.data.created.relative}</time>
222			</div>
223
224			<dl class="comment_form_content">
225				<dt>댓글 본문</dt>
226				<dd>
227					<textarea name="cmt_content">${response.data.content}</textarea>
228				</dd>
229			</dl>
230
231			<dl class="comment_form_password">
232				<dt class="hidden">비밀번호</dt>
233				<dd><input type="password" name="password" placeholder="비밀번호"></dd>
234			</dl>
235
236			<div class="comment_form_footer">
237				<input type="hidden" name="cmt_id" value="${cmt_id}">
238				<button class="btn_close">닫기</button>
239				<div class="column_left"><input type="checkbox" id="is_question" name="is_question" ${response.data.is_question === 'yes' ? 'checked' : void 0}><span>답변을 원하는 질문입니다.</span></div>
240				<div class="column_right"><button type="submit"><span>댓글 수정</span></button></div>
241			</div>
242		</div>
243	</form>
244</li>`);
245        if (response.data.loggedin) {
246          _form.find('dl.comment_form_password').remove();
247        }
248        return node.hide().after(_form);
249      } else {
250        return xalert(null, response.msg, {
251          modal: true
252        });
253      }
254    }, 'json');
255    return false;
256  });
257  $(document).on('click', '#comment_list' + ' > li > div.buttons a.delete', function() {
258    var node, question;
259    node = $(this).parents('li');
260    if (user_id > 0) {
261      question = '<p>삭제하시겠습니까?</p>';
262    } else {
263      question = '<p>삭제하시겠습니까?</p><input type="password" name="password" placeholder="비밀번호">';
264    }
265    dialogDelete.show(function(dialog) {
266      var data;
267      data = {
268        'id': node.data('id')
269      };
270      if (dialog.find('input[type=password]').size() > 0) {
271        data['password'] = dialog.find('input[type=password]').val();
272      }
273      return $.post(base_url + 'comment/delete_ajax', data, function(response) {
274        if (response.result) {
275          return node.remove();
276        } else {
277          return xalert(null, response.msg, {
278            modal: true
279          });
280        }
281      }, 'json');
282    }, null, question, options);
283    dialogDelete.dom.appendTo($(this).parents('li'));
284    return false;
285  });
286  $(document).on('click', '#comment_list' + ' > li.comment_editor button.btn_close', function() {
287    var _form;
288    _form = $(this).parents('li.comment_editor');
289    _form.prev().show();
290    _form.remove();
291    return false;
292  });
293  $(document).on('submit', '#comment_list' + ' > li.comment_editor form', function() {
294    var data, indicator, node, pwd, text;
295    text = $(this).find('.comment_form_footer button span');
296    node = $(this).parent();
297    data = {
298      'id': $(this).find('input[name=cmt_id]').val(),
299      'content': $(this).find('textarea').val(),
300      'is_question': $(this).find('input[name=is_question]:checked').size() ? 'yes' : 'no'
301    };
302    if (data.content.length === 0) {
303      xalert(null, '댓글 내용을 입력해 주세요.', {
304        modal: true
305      });
306      return false;
307    } else if (!user_id) {
308      pwd = $(this).find('input[name=password]');
309      if (pwd.length === 0) {
310        xalert(null, '잘못된 접근입니다.', {
311          modal: true
312        });
313        return false;
314      }
315      if (pwd.val().length === 0) {
316        xalert(null, '비밀번호를 입력해 주세요.', {
317          modal: true
318        });
319        return false;
320      }
321      data.password = pwd.val();
322    }
323    indicator = new ProcessIndicator($(this).find('.comment_form_footer button[type=submit]'), {
324      lines: 9,
325      length: 4,
326      width: 2,
327      radius: 4
328    }, '#fff');
329    indicator.start();
330    text.css('visibility', 'hidden');
331    $.post($(this).attr('action'), data, function(response) {
332      var onode;
333      if (response.result) {
334        onode = node.prev();
335        onode.show().find(' > div.comment_content').html(response.data.description);
336        onode.attr('data-is-question', data.is_question);
337        node.remove();
338      } else {
339        xalert(null, response.msg, {
340          modal: true
341        });
342      }
343      indicator.stop();
344      return text.css('visibility', 'visible');
345    }, 'json');
346    return false;
347  });
348  $(document).on('click', '#comment_list' + ' > li a[href^="#comment"]', function() {
349    var comment_id, node, target;
350    node = $(this).parents('li');
351    comment_id = $(this).attr('href').substr(8);
352    target = $(' > li a[name="comment' + comment_id + '"]', list);
353    if (target.size() > 0) {
354      return true;
355    } else {
356      return $.getJSON(base_url + 'comment/get_ajax/' + comment_id, function(response) {
357        var buttons, comment, template;
358        if (response.result) {
359          comment = response.data;
360          if (comment.created === null && comment.updated === null) {
361            return xalert(null, '존재하지 않는 댓글입니다.', {
362              modal: true
363            });
364          } else {
365            template = $(`<li class="calling_alone" data-id="${comment.id}">
366	<div class="profile_image">
367		<img class="profile_icon" data-id="${comment.user_id}" src="${comment.user_pict}" alt="">
368	</div>
369
370	<div class="name time">
371		<strong>${comment.name}</strong><a href="#comment${comment.id}" name="comment${comment.id}"><time datetime="${comment.created.original}">${comment.created.relative}</time></a>
372	</div>
373
374	<div class="comment_content">
375		${comment.description}
376	</div>
377</li>`);
378            if (comment.parent > 0) {
379              template.append(`<dl class="parents">
380	<dt><a href="#" data-parent="${comment.parent}">대화보기</a><span></span></dt>
381	<dd>
382		<ul></ul>
383	</dd>
384</dl>`);
385            }
386            buttons = '<div class="buttons">';
387            if (user_id) {
388              if (user_id === comment.cm_owner_user_id || user_id === comment.user_id) {
389                buttons += `<a class="reply" href="#">답글</a>|<a class="edit" href="#">수정</a>|<a class="delete" href="#" data-user_id="${comment.user_id}">삭제</a>`;
390              } else {
391                buttons += '<a class="reply" href="#">답글</a>';
392              }
393            } else {
394              if (!comment.user_id) {
395                buttons += '<a class="reply" href="#">답글</a>|<a class="edit" href="#">수정</a>|<a class="delete" href="#" data-user_id="0">삭제</a>';
396              } else {
397                buttons += '<a class="reply" href="#">답글</a>';
398              }
399            }
400            buttons += '</div>';
401            template.append(buttons);
402            node.before(template.hide());
403            //setFlash template
404            return template.slideDown();
405          }
406        } else {
407          return xalert(null, response.msg, {
408            modal: true
409          });
410        }
411      });
412    }
413  });
414  filterComment = function() {
415    if ($('#show_question_only input:checked').size() > 0) {
416      return $('li[data-is-question=no]').hide();
417    } else {
418      return $('li[data-is-question=no]').show();
419    }
420  };
421  $(document).on('click', '#show_question_only', function() {
422    return filterComment();
423  });
424  $(document).on('click', '#cmt_more a', function() {
425    var data, indicator, text;
426    text = $('span', this);
427    data = {
428      course_id: $('input[name=course_id]', form).val(),
429      module_id: $('input[name=module_id]', form).val(),
430      topic_id: $('input[name=topic_id]', form).val(),
431      page: ++page
432    };
433    indicator = new ProcessIndicator('#cmt_more', PROCESSINDICATOR_SMALL);
434    indicator.start();
435    text.css('visibility', 'hidden');
436    $.getJSON(base_url + 'comment', data, function(response) {
437      var buttons, comment, i, index, len, ref, template;
438      if (response.errorCode === 0) {
439        ref = response.data.comments;
440        for (index = i = 0, len = ref.length; i < len; index = ++i) {
441          comment = ref[index];
442          template = $(`<li data-id="${comment.id}" data-is-question="${comment.is_question}">
443	<div class="profile_image">
444		<img class="profile_icon" data-id="${comment.user_id}" src="${comment.user_pict}" alt="">
445	</div>
446
447	<div class="name time">
448		<strong>${comment.name}</strong><a href="#comment${comment.id}" name="comment${comment.id}"><time datetime="${comment.created.original}">${comment.created.relative}</time></a>
449	</div>
450
451	<div class="comment_content">
452		${comment.description}
453	</div>
454</li>`);
455          if (comment.parent > 0) {
456            template.append(`<dl class="parents">
457	<dt><a href="#" data-parent="${comment.parent}">대화보기</a><span></span></dt>
458	<dd>
459		<ul></ul>
460	</dd>
461</dl>`);
462          }
463          buttons = '<div class="buttons">';
464          if (user_id) {
465            if (user_id === comment.user_id) {
466              buttons += `<a class="reply" href="#">답글</a>|<a class="edit" href="#">수정</a>|<a class="delete" href="#">삭제</a>`;
467            } else if (comment.topic_id > 0 || (comment.course_id === 0 && comment.module_id > 0)) {
468              if (comment.module.user_id === user_id) {
469                buttons += '<a class="reply" href="#">답글</a>|<a class="delete" href="#">삭제</a>';
470              } else {
471                buttons += '<a class="reply" href="#">답글</a>';
472              }
473            } else if (comment.course_id > 0) {
474              if (comment.course.user_id === user_id) {
475                buttons += '<a class="reply" href="#">답글</a>|<a class="delete" href="#">삭제</a>';
476              } else {
477                buttons += '<a class="reply" href="#">답글</a>';
478              }
479            }
480          } else {
481            if (comment.user_id === 0) {
482              buttons += '<a class="reply" href="#">답글</a>|<a class="edit" href="#">수정</a>|<a class="delete" href="#">삭제</a>';
483            } else {
484              buttons += '<a class="reply" href="#">답글</a>';
485            }
486          }
487          buttons += '</div>';
488          template.append(buttons);
489          list.append(template.hide());
490          //setFlash template
491          template.slideDown();
492        }
493        filterComment();
494        if (response.data.isLast) {
495          $('#cmt_more').hide();
496        }
497      } else if (response.errorCode === 9999) {
498        $('#cmt_more').hide();
499        xalert(null, response.msg, {
500          modal: true
501        });
502      } else {
503        xalert(null, '알 수 없는 에러가 발생했습니다.', {
504          modal: true
505        });
506      }
507      indicator.stop();
508      return text.css('visibility', 'visible');
509    });
510    return false;
511  });
512  if (hash.length > 0 && /^comment/.test(hash)) {
513    target = $('a[name="' + hash + '"]', list);
514    if (target.size() === 0) {
515      return $.getJSON(base_url + 'comment/get_ajax/' + hash.substr(7), function(response) {
516        var buttons, comment, template;
517        if (response.result) {
518          comment = response.data;
519          if (comment.created === null && comment.updated === null) {
520            return xalert(null, '존재하지 않는 댓글입니다.', {
521              modal: true
522            });
523          } else {
524            template = $(`<li class="calling_alone" data-id="${comment.id}">
525	<div class="profile_image">
526		<img class="profile_icon" data-id="${comment.user_id}" src="${comment.user_pict}" alt="">
527	</div>
528
529	<div class="name time">
530		<strong>${comment.name}</strong><a href="#comment${comment.id}" name="comment${comment.id}"><time datetime="${comment.created.original}">${comment.created.relative}</time></a>
531	</div>
532
533	<div class="comment_content">
534		${comment.description}
535	</div>
536</li>`);
537            if (comment.parent > 0) {
538              template.append(`<dl class="parents">
539	<dt><a href="#" data-parent="${comment.parent}">대화보기</a><span></span></dt>
540	<dd>
541		<ul></ul>
542	</dd>
543</dl>`);
544            }
545            buttons = '<div class="buttons">';
546            if (user_id) {
547              if (user_id === comment.cm_owner_user_id || user_id === comment.user_id) {
548                buttons += `<a class="reply" href="#">답글</a>|<a class="edit" href="#">수정</a>|<a class="delete" href="#" data-user_id="${comment.user_id}">삭제</a>`;
549              } else {
550                buttons += '<a class="reply" href="#">답글</a>';
551              }
552            } else {
553              if (!comment.user_id) {
554                buttons += '<a class="reply" href="#">답글</a>|<a class="edit" href="#">수정</a>|<a class="delete" href="#" data-user_id="0">삭제</a>';
555              } else {
556                buttons += '<a class="reply" href="#">답글</a>';
557              }
558            }
559            buttons += '</div>';
560            template.append(buttons);
561            list.prepend(template.hide());
562            return template.slideDown();
563          }
564        } else {
565          return xalert(null, response.msg, {
566            modal: true
567          });
568        }
569      });
570    } else {
571      return target.parents('li').addClass('calling_alone');
572    }
573  }
574})(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.