var $header = $('header');
var $header_panel = $('#header-panel');
var $progress_bar = $('#progress-bar');
var $section_list = $('#section-list');
var $url_form = $('#url-form');
var $url_field = $('#url-field');
var $url_share = $('#url-share');
var $url_mark_btn = $('#url-mark-btn');
var $reload_link = $('#reload-link');
var $original_section = $('#original-section');
var $original_loaded_label = $('#original-loaded-label');
var $original_wrap = $('#original-wrap');
var $original_frame = $('#original-frame');
var $original_popup_button = $('#original-popup-button');
var $rules_wrap = $('#rules-wrap');
var $rules_header = $('#rules-header');
var $rules_section = $('#rules-section');
var $rules_field = $('#rules-field');
var $save_link = $('#save-link');
var $after_rules_field = $('#after-rules-field');
var $result_section = $('#result-section');
var $result_preview_wrap = $('#result-preview-wrap');
var $result_wrap = $('#result-wrap');
var $result_frame = $('#result-frame');
var $result_preview = $('#result-preview');
var $footer = $('#footer');
var $debug_block = $('#debug-block');
var $debug_wrap = $('#debug-wrap');
var $status_section = $('#status-section');
var $status_wrap = $('#status-wrap');
var $process_time = $('#process-time');
var original_frame = $original_frame.get(0);
var result_frame = $result_frame.get(0);
var App = {};
var Popups = [];
function apiRequest(method, data, onSuccess, try_num) {
$.ajax(App.baseUrl, {
type: 'POST',
data: $.extend(data, {method: method}),
dataType: 'json',
xhrFields: {
withCredentials: true
},
success: onSuccess,
error: function(xhr) {
if (xhr.status == 401) {
location.href = '/auth';
} else if (xhr.status >= 500) {
try_num = try_num || 0;
if (++try_num < 5) {
setTimeout(function() {
apiRequest(method, data, onSuccess, try_num);
}, 300 * try_num);
}
} else {
location.reload();
}
}
});
}
function escapeHtml(text) {
var map = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": ''',
"\n": '
'
};
return text.replace(/[&<>"'\n]/g, function(m){ return map[m]; });
}
function showProgress($el) {
clearTimeout($el.data('to'));
var to = setTimeout(showProgress, 400, $el),
value = $el.data('value') || 0,
next_value = value + (99 - value) / 4;
if (!value) {
$el.addClass('no-transition').css('width', 0);
$el.offset();
$el.removeClass('no-transition');
}
$el.data('to', to).data('value', next_value);
$el.removeClass('no-shown').css('width', value + '%');
}
function hideProgress($el, cancel) {
clearTimeout($el.data('to'));
$el.data('to', false).data('value', 0);
$el.css('width', cancel ? '0%' : '100%');
setTimeout(function() { $el.addClass('no-shown'); }, 400);
}
function setDebug(debug_items) {
var debug_block = $debug_block.get(0);
if (debug_block) {
var st = debug_block.scrollTop;
var sb = Math.max(0, debug_block.scrollHeight - debug_block.offsetHeight);
$debug_wrap.html(debug_items.join(''));
if (st == sb) {
debug_block.scrollTop = debug_block.scrollHeight;
}
$footer.toggleClass('more', debug_items.length > 0);
if (debug_items.length > 0 && !App.state.footer_collapsed) {
$footer.removeClass('collapsed');
debug_block.scrollTop = debug_block.scrollHeight;
}
if (!debug_items.length) {
$footer.addClass('collapsed');
}
}
}
function setStatus(status) {
if ($status_wrap.html() != status) {
$status_wrap.html(status);
}
}
function openPopup(popup) {
if (!popup) return false;
var $popup = $(popup);
var popup_id = $popup.data('puid');
if (!popup_id) {
if (!Popups._pid) Popups._pid = 0;
popup_id = ++Popups._pid;
$popup.data('puid', popup_id);
}
var i = Popups.indexOf(popup_id);
if (i >= 0) {
Popups.splice(i, 1);
}
Popups.push(popup_id);
$('body').css('overflow', 'hidden');
$popup.appendTo('body');
$popup.removeClass('hide');
// $popup.on('click', function(e) {
// if (!$(e.target).closest('.popup').length) {
// closePopup($popup);
// }
// });
$('.popup-cancel-btn', $popup).on('click', function(e) {
closePopup($popup);
});
$popup.trigger('popup:open');
}
function closePopup(popup) {
if (!Popups.length) return false;
var $popup, popup_id;
if (popup) {
$popup = $(popup);
popup_id = $popup.data('puid');
} else {
popup_id = Popups.pop();
var $popups = $('.popup-container');
var found = false;
for (var i = 0; i < $popups.length; i++) {
$popup = $popups.eq(i);
if (popup_id == $popup.data('puid')) {
found = true
break;
}
}
if (!found) {
return false;
}
}
var i = Popups.indexOf(popup_id);
if (i >= 0) {
Popups.splice(i, 1);
}
if (!Popups.length) {
$('body').css('overflow', '');
}
// $popup.off('click');
$('.popup-cancel-btn', $popup).off('click');
$popup.addClass('hide');
$popup.trigger('popup:close');
}
$(document).on('keydown', function(e) {
if (e.keyCode == 27 && Popups.length > 0) {
closePopup();
}
});
$(document).on('keydown', 'textarea', function(e) {
if (e.keyCode == 13 && (e.metaKey || e.ctrlKey)) {
$(this.form).submit();
}
});
function showAlert(html, options) {
options = options || {};
var $alert = $('
');
$('.popup-text', $alert).html(html);
$alert.on('popup:close', function() {
$alert.remove();
});
openPopup($alert);
}
function showConfirm(html, onConfirm, confirm_btn) {
var $confirm = $('');
$('.popup-text', $confirm).html(html);
$('.popup-primary-btn', $confirm).on('click', function() {
onConfirm && onConfirm($confirm);
closePopup($confirm);
});
$confirm.on('popup:close', function() {
$('.popup-primary-btn', $confirm).off('click');
$confirm.remove();
});
openPopup($confirm);
}
function openUrlField(no_focus) {
$header.addClass('url-form-opened');
if (!no_focus) {
$url_field.focus();
}
$url_field.select();
}
function closeUrlField() {
$header.removeClass('url-form-opened');
}
function initFrameRegions(frame, no_edit, regions) {
sendPostMessage(frame, {event: 'init_regions', no_edit: no_edit || false, regions: regions || ''});
}
function updateFrame(frame, doc_url) {
frame.onload = function(e) {
e.target.loaded = true;
if (frame.onloadCallbacks && frame.onloadCallbacks.length > 0) {
for (var i = 0; i < frame.onloadCallbacks.length; i++) {
frame.onloadCallbacks[i]();
}
}
}
frame.src = doc_url;
return frame;
}
function updateOriginalFrame() {
updateFrame(original_frame, App.state.original_doc_url);
updateOriginalLabels();
}
function updateOriginalLabels() {
var time_label = $original_loaded_label.attr('data-time') || '';
var date_label = $original_loaded_label.attr('data-date') || '';
var label = formatTplDate(App.state.loaded_date, time_label, date_label);
$original_loaded_label.text(label);
$original_section.removeClass('original-loading');
if (!App.state.rules_id) {
$original_section.addClass('original-loaded');
}
$original_section.toggleClass('original-saved', !!App.state.original_saved);
$original_section.toggleClass('original-readonly', !!(App.state.readonly || App.state.demo));
}
function updateResult() {
updateFrame(result_frame, App.state.result_doc_url);
$result_preview_wrap.toggleClass('hide', !App.state.preview_html);
if (App.state.result_empty) {
$result_preview.html(App.state.preview_html);
$result_wrap.addClass('collapsed');
} else {
if (!App.state.result_collapsed) {
setTimeout(function() {
$result_preview.html(App.state.preview_html);
}, 200);
$result_wrap.removeClass('collapsed');
} else {
$result_preview.html(App.state.preview_html);
}
}
if (App.state.checked) {
$result_section.attr('class', 'result-not-modified');
$url_mark_btn.addClass('disabled').removeClass('btn-primary');
} else {
if (App.state.can_check) {
if (App.state.not_tracked) {
$result_section.attr('class', 'result-not-tracked');
} else {
$result_section.attr('class', 'result-modified');
}
} else {
$result_section.attr('class', App.state.is_error ? 'result-error' : '');
}
if (App.state.can_check && App.state.can_add) {
$url_mark_btn.addClass('btn-primary').removeClass('disabled');
} else {
$url_mark_btn.addClass('disabled').removeClass('btn-primary');
}
}
$url_mark_btn.text($url_mark_btn.attr(App.state.not_tracked ? 'data-track' : 'data-mark'));
$result_section.toggleClass('result-readonly', !$url_mark_btn.length);
if (App.state.is_error) {
$url_share.addClass('disabled').removeClass('btn-info');
} else {
$url_share.addClass('btn-info').removeClass('disabled');
}
$result_section.removeClass('result-processing');
if (App.state.result_debug) {
setDebug(App.state.result_debug);
}
if (App.state.result_status) {
setStatus(App.state.result_status);
}
if (App.state.process_time) {
$process_time.html(App.state.process_time);
}
if (App.state.mark_after_process) {
App.state.mark_after_process = false;
if (!$url_mark_btn.hasClass('disabled')) {
markUrlAsChecked();
}
}
}
function sendPostMessage(frame, data) {
try {
if (frame.loaded) {
frame.contentWindow.postMessage(JSON.stringify(data), App.frameOrigin);
} else {
if (!frame.onloadCallbacks) frame.onloadCallbacks = [];
frame.onloadCallbacks.push(function() {
frame.contentWindow.postMessage(JSON.stringify(data), App.frameOrigin);
});
}
} catch(e) {}
}
function postMessageHandler(event) {
if (event.source !== original_frame.contentWindow &&
event.source !== result_frame.contentWindow ||
event.origin != App.frameOrigin) {
return;
}
try {
var data = JSON.parse(event.data);
} catch(e) {
var data = {};
}
if (data.event == 'regions_change') {
if (event.source === original_frame.contentWindow) {
App.state.originalRegions = data.regions;
} else if (event.source === result_frame.contentWindow) {
App.state.resultRegions = data.regions;
}
} else if (data.event == 'link_click') {
$url_field.val(data.url);
$url_form.submit();
}
}
window.onmessage = postMessageHandler;
function initIssuePage(url, page_data) {
App.state = {
result_url: url,
original_doc_url: false,
sections: [],
rules: '',
saved_rules: false,
section: page_data.section || '',
rules_id: page_data.rules_id || 0,
issue_id: page_data.issue_id || 0,
originalRegions: '',
resultRegions: ''
};
var regions = (page_data.regions || '').split(';');
var original_regions = regions[0];
var result_regions = regions[1];
updateFrame(original_frame, page_data.original_doc_url);
initFrameRegions(original_frame, true, original_regions);
updateFrame(result_frame, page_data.result_doc_url);
initFrameRegions(result_frame, true, result_regions);
var result_collapsed = false;
$result_preview_wrap.toggleClass('hide', !page_data.preview_html);
if (page_data.result_empty) {
$result_preview.html(page_data.preview_html);
$result_wrap.addClass('collapsed');
} else {
if (!result_collapsed) {
setTimeout(function() {
$result_preview.html(page_data.preview_html);
}, 200);
$result_wrap.removeClass('collapsed');
} else {
$result_preview.html(page_data.preview_html);
}
}
if (page_data.is_error) {
$url_share.addClass('disabled').removeClass('btn-info');
} else {
$url_share.addClass('btn-info').removeClass('disabled');
}
$result_preview_wrap.click(function(e) {
$result_wrap.toggleClass('collapsed');
result_collapsed = $result_wrap.hasClass('collapsed');
});
$('.issue-comment-photo').click(function(e) {
var src = $(this).attr('data-src');
var $alert = $('');
$('img', $alert).attr('src', src);
$alert.on('popup:open', function() {
$alert.on('click', function(e) {
closePopup($alert);
});
});
$alert.on('popup:close', function() {
$alert.off('click');
$alert.remove();
});
openPopup($alert);
});
initOriginalPopupButton();
}
function updateRulesField() {
if (!App.editor) return;
var field_value = App.editor.getValue();
if (App.state.saved_rules !== false && App.state.saved_rules != field_value) {
$rules_section.addClass('rules-changed');
} else {
$rules_section.removeClass('rules-changed');
}
}
function reloadOriginal() {
apiRequest('reloadOriginal', {
url: App.state.result_url,
section: App.state.section
}, onReloadOriginal);
}
function onReloadOriginal(result) {
if (!result.error) {
App.state.pending = true;
loadUrlData();
} else {
showAlert(result.error);
}
}
function saveRules() {
clearTimeout(App.state.rules_timeout);
processRules(App.editor.getValue());
}
function acHint(cm, callback, option) {
var cursor = cm.getCursor(), line = cm.getLine(cursor.line);
var start = cursor.ch, end = cursor.ch;
if (end < line.length && /[a-z0-9_]/i.test(line.charAt(end))) {
return;
}
while (start && /[a-z0-9_]/i.test(line.charAt(start - 1))) {
--start;
}
var before = line.slice(0, start), comp;
var tab = (before.match(/^\s+/) || [''])[0];
before = before.replace(/^\s+/, '');
if (before == '?' || before == '!') {
comp = App.autocomplete.conditions;
} else if (before == '@') {
comp = [].concat(App.autocomplete.functions);
for (var j = 0; j < App.autocomplete.block_functions.length; j++) {
var text = App.autocomplete.block_functions[j];
comp.push({text: text + '( ) {\n' + tab + ' \n' + tab + '}', displayText: text, ch_offset: text.length + 2, hint: function(cm, data, completion) {
cm.replaceRange(completion.text, data.from, data.to, 'complete');
cm.doc.setCursor(CodeMirror.Pos(data.from.line, data.from.ch + (completion.ch_offset || 0)));
}});
}
} else if (before == '~') {
comp = [];
for (var j = 0; j < App.autocomplete.options.length; j++) {
var opt = App.autocomplete.options[j];
if (typeof opt === 'string') {
opt = {text: opt};
}
var defValue = opt.defValue || '';
comp.push({text: opt.text + ': "' + defValue + '"', displayText: opt.text, ch_offset: opt.text.length + 3, ch_len: defValue.length, hint: function(cm, data, completion) {
cm.replaceRange(completion.text, data.from, data.to, 'complete');
var from = data.from.ch + (completion.ch_offset || 0);
var to = from + (completion.ch_len || 0);
cm.doc.setSelection(CodeMirror.Pos(data.from.line, to), CodeMirror.Pos(data.from.line, from));
}});
}
} else if (!before && end - start > 0) {
comp = App.autocomplete.properties;
} else if (/[\s:,]\$$/i.test(before)) {
comp = getVariables();
} else {
return;
}
var prefix = line.slice(start, end).toLowerCase();
var list = [];
for (var i = 0; i < comp.length; i++) {
var cmp = comp[i].displayText || comp[i];
if (cmp == prefix && !comp[i].displayText) continue;
if (cmp.indexOf(prefix) == 0) list.push(comp[i]);
}
if (!list.length) return;
return callback({
list: list,
from: CodeMirror.Pos(cursor.line, start),
to: CodeMirror.Pos(cursor.line, end)
});
}
acHint.async = true;
function getVariables() {
var variables = {'$': 1, '@': 1};
for (var i = 0; i < App.editor.lineCount(); i++) {
var tokens = App.editor.getLineTokens(i);
for (var j = 0; j < tokens.length; j++) {
if (tokens[j].type == 'variable-2') {
var variable = tokens[j].string;
if (variable [0] == '$') {
variable = variable.substr(1);
}
variables[variable] = 1;
}
}
}
var list = Object.keys(variables);
list.sort();
return list;
}
function betterTab(shift) {
if (shift) {
return function(cm) {
cm.indentSelection('subtract');
};
}
return function(cm) {
if (cm.somethingSelected()) {
cm.indentSelection('add');
} else {
if (cm.getOption('indentWithTabs')) {
cm.replaceSelection('\t', 'end', '+input');
} else {
cm.execCommand('insertSoftTab');
}
}
};
}
function duplicate() {
return function(cm) {
var current_cursor = cm.doc.getCursor('to');
if (cm.somethingSelected()) {
var sel_content = cm.doc.getSelection();
cm.doc.setCursor(current_cursor);
cm.doc.replaceSelection(sel_content, 'around');
} else {
var line_content = cm.doc.getLine(current_cursor.line);
CodeMirror.commands.goLineEnd(cm);
CodeMirror.commands.newlineAndIndent(cm);
cm.doc.replaceSelection(line_content);
cm.doc.setCursor(current_cursor.line + 1, current_cursor.ch);
}
}
};
function formatTplDate(timestamp, time_format, date_format) {
if (!timestamp) return '';
var cur = new Date();
var date = new Date(timestamp * 1000);
if (+cur - date < 79200000) {
var hours = date.getHours();
var mins = date.getMinutes();
if (mins < 10) mins = '0' + mins;
return (time_format || '')
.replace('{hours}', (hours % 12) || 12)
.replace('{mins}', mins)
.replace('{am_pm}', (hours < 12 ? 'AM' : 'PM'));
}
var day = date.getDate();
var month = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'][date.getMonth()];
var year = (+cur - date < 14688000000) ? '' : date.getFullYear();
return (date_format || '')
.replace('{date}', day)
.replace('{month}', month)
.replace('{year}', year)
.replace(/\s+$/, '');
}
function ivFormatDate(date) {
var date = new Date(date * 1000);
var cur_date = new Date();
var j = date.getDate();
var M = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'][date.getMonth()];
var Y = date.getFullYear();
if (cur_date.getFullYear() != Y) {
return M + ' ' + j + ', ' + Y;
}
var hours = date.getHours();
var g = (hours % 12) || 12;
var i = date.getMinutes();
if (i < 10) i = '0' + i;
return M + ' ' + j + ' at ' + g + ':' + i + ' ' + (hours < 12 ? 'AM' : 'PM');
}
function svgStat(stat) {
var values_count = 3;
var colors = ['#5cb85c', '#f0ad4e', '#d9534f'];
var col_width = 10;
if (!stat.length) {
return '';
}
stat_window = 7;
if (stat_window > 0) {
var new_stat = [];
for (var i = 0, k = 0; i < stat.length; i += values_count, k++) {
for (var j = values_count - 1; j >= 0; j--) {
var w_sum = 0, w_size = 0;
for (var w = Math.min(k, stat_window - 1); w >= 0; w--) {
w_sum += stat[(k - w) * values_count + j];
w_size++;
}
new_stat[k * values_count + j] = w_size ? w_sum / w_size : 0;
}
}
stat = new_stat;
}
var paths = [];
var rpaths = [];
for (var j = values_count - 1; j >= 0; j--) {
paths[j] = '';
rpaths[j] = '';
}
var x = 0, first = true;
for (var i = 0; i < stat.length; i += values_count) {
var values = stat.slice(i, i + values_count);
var sum = 0;
for (var j = values_count - 1; j >= 0; j--) {
sum += values[j];
}
var y = sum > 0 ? 0 : 100;
for (var j = values_count - 1; j >= 0; j--) {
if (first) {
paths[j] += 'M' + x + ' ' + (j ? y : 100) + ' ';
}
rpaths[j] = 'L' + x + ' ' + (j ? y : 100) + ' ' + rpaths[j];
if (j > 0) {
y += sum > 0 ? Math.round(values[j] / sum * 100) : 0;
}
paths[j] += 'L' + x + ' ' + y + ' ';
}
first = false;
x += col_width;
}
x -= col_width;
for (var j = values_count - 1; j >= 0; j--) {
paths[j] += rpaths[j];
}
var width = (stat.length / 3 - 1) * col_width;
var height = 100;
var html = '';
for (var k = 0; k < paths.length; k++) {
html += '';
}
html = '';
return html;
}
function initWorkspace(url, url_data) {
App.state = {
result_url: url,
original_doc_url: false,
sections: [],
rules: '',
saved_rules: false,
contest: url_data.contest || false,
originalRegions: '',
resultRegions: ''
};
App.autocomplete = {
conditions: ['domain', 'domain_not', 'path', 'path_not', 'exists', 'not_exists', 'false', 'true'],
functions: ['debug', 'remove', 'match', 'replace', 'urlencode', 'urldecode', 'htmlencode', 'htmldecode', 'datetime', 'set_attr', 'set_attrs', 'style_to_attrs', 'background_to_image', 'json_to_xml', 'html_to_dom', 'prepend_to', 'append_to', 'before_el', 'after_el', 'prepend', 'append', 'before', 'after', 'replace_tag', 'wrap', 'wrap_inner', 'clone', 'detach', 'split_parent', 'pre', 'combine', 'inline', 'load', 'unsupported', 'simplify'],
block_functions: ['if', 'if_not', 'map', 'repeat', 'while', 'while_not'],
properties: ['title', 'subtitle', 'kicker', 'author', 'author_url', 'published_date', 'description', 'image_url', 'document_url', 'cover', 'channel', 'site_name', 'body'],
options: [{text: 'version', defValue: '2.1'}, 'allowed_origin']
};
var mac = /Mac/.test(navigator.platform) ||
/AppleWebKit/.test(navigator.userAgent) &&
/Mobile\/\w+/.test(navigator.userAgent);
if ($rules_field.length) {
App.editor = CodeMirror.fromTextArea($rules_field.get(0), {
mode: 'instantview',
tabSize: 2,
lineWrapping: true,
lineNumbers: true,
matchBrackets: true,
autoCloseBrackets: true,
viewportMargin: 50,
readOnly: 'nocursor',
extraKeys: mac ? {
'Cmd-D': duplicate(), 'Shift-Cmd-D': duplicate(),
'Cmd-S': saveRules, 'Cmd-/': 'toggleComment',
'Tab': betterTab(), 'Shift-Tab': betterTab(true),
"Alt-F": 'findPersistent'
} : {
'Ctrl-D': duplicate(), 'Shift-Ctrl-D': duplicate(),
'Ctrl-S': saveRules, 'Ctrl-/': 'toggleComment',
'Tab': betterTab(), 'Shift-Tab': betterTab(true),
"Alt-F": 'findPersistent'
}
});
App.editor.on('change', function() {
updateRulesField();
clearTimeout(App.state.rules_timeout);
App.state.rules_timeout = setTimeout(saveRules, 5000);
App.editor.showHint({hint: acHint, completeSingle: false});
});
App.afterTpl = CodeMirror.fromTextArea($after_rules_field.get(0), {
mode: 'instantview',
tabSize: 2,
lineWrapping: true,
lineNumbers: true,
viewportMargin: 1000,
readOnly: true,
cursorBlinkRate: -1
});
} else {
App.editor = false;
App.afterTpl = false;
}
$url_mark_btn.click(function() {
if ($url_mark_btn.hasClass('disabled')) {
return;
}
markUrlAsChecked();
});
$rules_header.click(function(e) {
$rules_wrap.toggleClass('collapsed');
});
$reload_link.click(function(e) {
e.preventDefault();
reloadOriginal();
});
$save_link.click(function(e) {
e.preventDefault();
saveRules();
});
$result_preview_wrap.click(function(e) {
$result_wrap.toggleClass('collapsed');
App.state.result_collapsed = $result_wrap.hasClass('collapsed');
});
$debug_wrap.on('click', '.rule-ref', function() {
var ref = $(this).text().split(':');
var source = ref[0];
var after_tpl = (source == '..after');
var collapsed = $rules_wrap.hasClass('collapsed');
var timeout = 0;
if (!collapsed != !after_tpl) {
$rules_wrap.toggleClass('collapsed', after_tpl);
timeout = 150;
}
setTimeout(function() {
var cm = after_tpl ? App.afterTpl : App.editor;
var ln = ref[1].split('-');
var line_from = ln[0] - 1, line_to = ln[1] ? ln[1] - 1 : line_from;
if (line_from >= 0 && line_to >= 0) {
var y = cm.heightAtLine(line_from, 'local');
var ch = cm.getScrollInfo().clientHeight;
var scroll_top = y - (ch - cm.defaultTextHeight() * (line_to - line_from + 1)) / 2;
cm.scrollTo(null, scroll_top);
for (var l = line_from; l <= line_to; l++) {
cm.doc.addLineClass(l, 'text', 'line-highlight');
}
setTimeout(function() {
for (var l = line_from; l <= line_to; l++) {
cm.doc.removeLineClass(l, 'text', 'line-highlight');
}
}, 50);
}
}, timeout);
});
$status_section.click(function(e) {
if (!$footer.hasClass('more')) {
return;
}
$footer.toggleClass('collapsed');
App.state.footer_collapsed = $footer.hasClass('collapsed');
});
window.onbeforeunload = function (e) {
if (App.state.popup) {
try { App.state.popup.close(); } catch(e) {}
}
if (!App.editor) return;
var field_value = App.editor.getValue();
if (App.state.saved_rules !== false && App.state.saved_rules != field_value) {
var message = 'You have unsaved changes, you really want to leave this page?';
if (typeof e === 'undefined') e = window.e;
if (e) {
e.returnValue = message;
}
return message;
}
}
initOriginalPopupButton();
showProgress($progress_bar);
onLoadUrlData(url_data);
}
function initOriginalPopupButton() {
$original_popup_button.attr('href', App.state.result_url);
$original_popup_button.click(function(e) {
if (e.metaKey || e.ctrlKey) return true;
e.preventDefault();
var winX = window.screenLeft ? window.screenLeft : window.screenX;
var winY = window.screenTop ? window.screenTop : window.screenY;
var winH = window.outerHeight;
var popupW = $original_wrap.outerWidth(),
popupH = winH - 200,
popupX = winX + $original_wrap.offset().left,
popupY = winY + 100,
params = [
'width=' + popupW,
'height=' + popupH,
'left=' + popupX,
'top=' + popupY,
].join(',');
var popup = App.state.popup;
if (popup && !popup.closed) {
if (App.state.popup_url != App.state.result_url) {
App.state.popup_url = App.state.result_url;
popup.location.href = App.state.popup_url;
}
try {
popup.resizeTo(popupW, popupH);
popup.moveTo(popupX, popupY);
} catch(e) {}
} else {
App.state.popup_url = App.state.result_url;
App.state.popup = window.open(App.state.popup_url, 'iv-original', params);
}
if (App.state.popup) {
try { App.state.popup.focus(); } catch(e) {}
}
});
}
function loadUrlData() {
if (!App.state.pending) {
return;
}
clearTimeout(App.state.timeout);
$original_section.addClass('original-loading');
App.editor && App.editor.setOption('readOnly', 'nocursor');
$url_mark_btn.addClass('disabled').removeClass('btn-primary');
apiRequest('getUrlData', {
url: App.state.result_url,
section: App.state.section,
rules_id: App.state.rules_id
}, onLoadUrlData);
}
function onLoadUrlData(url_data) {
if (url_data.pending) {
clearTimeout(App.state.timeout);
App.state.pending = true;
App.state.section = url_data.section;
App.state.rules_id = url_data.rules_id || '';
App.state.timeout = setTimeout(loadUrlData, 1000);
}
else if (url_data.error) {
hideProgress($progress_bar, true);
showAlert(url_data.error);
}
else {
if (App.state.result_url != url_data.result_url) {
location.href = '?url=' + encodeURIComponent(url_data.result_url);
return;
}
App.state.pending = false;
App.state.original_doc_url = url_data.original_doc_url || '';
App.state.original_saved = url_data.original_saved || false;
App.state.loaded_date = url_data.loaded_date || 0;
App.state.section = url_data.section || '';
App.state.rules_id = url_data.rules_id || '';
App.state.rules = false;
App.state.readonly = url_data.readonly;
App.state.demo = url_data.demo;
App.state.saved_rules = App.state.rules;
if (App.editor) {
App.editor.setValue(url_data.rules);
App.editor.setOption('readOnly', !!App.state.readonly);
App.editor.setOption('cursorBlinkRate', App.state.readonly ? -1 : 530);
}
updateOriginalFrame();
processRules(url_data.rules);
}
}
function processRules(rules) {
if (App.state.rules === rules) {
return;
}
App.state.rules = rules;
App.state.random_id = false;
showProgress($progress_bar);
$rules_section.addClass('rules-saving');
$result_section.addClass('result-processing');
return processPageByRules();
}
function processPageByRules() {
clearTimeout(App.state.process_timeout);
apiRequest('processByRules', {
url: App.state.result_url,
section: App.state.section,
rules: App.state.random_id ? '' : App.state.rules,
rules_id: App.state.rules_id,
random_id: App.state.random_id || ''
}, onProcessPageByRules);
}
function onProcessPageByRules(page_data) {
if (typeof page_data.saved_rules !== 'undefined') {
App.state.saved_rules = page_data.saved_rules;
$rules_section.removeClass('rules-saving');
if (App.state.demo) {
$rules_section.addClass('rules-demo');
} else if (App.state.readonly) {
$rules_section.addClass('rules-readonly');
} else {
$rules_section.addClass('rules-saved');
}
updateRulesField();
}
if (page_data.pending) {
clearTimeout(App.state.process_timeout);
App.state.random_id = page_data.random_id;
if (page_data.debug) {
setDebug(page_data.debug);
}
if (page_data.status) {
setStatus(page_data.status);
}
if (page_data.process_time) {
$process_time.html(page_data.process_time);
}
App.state.process_timeout = setTimeout(processPageByRules, 400);
}
else if (page_data.error) {
hideProgress($progress_bar, true);
$rules_section.removeClass('rules-saving');
$result_section.removeClass('result-processing');
App.state.mark_after_process = false;
showAlert(page_data.error);
}
else {
hideProgress($progress_bar);
App.state.random_id = page_data.random_id;
App.state.result_empty = page_data.result_empty;
App.state.result_doc_url = page_data.result_doc_url;
App.state.preview_html = page_data.preview_html;
App.state.result_debug = page_data.debug;
App.state.result_status = page_data.status;
App.state.process_time = page_data.process_time;
App.state.checked = page_data.checked;
App.state.can_check = page_data.can_check;
App.state.not_tracked = page_data.not_tracked;
App.state.can_add = page_data.can_add;
App.state.is_error = page_data.result_error;
if (page_data.original_saved) {
App.state.original_saved = true;
updateOriginalLabels();
}
updateResult();
if (!page_data.contest) {
onUpdateSectionList(page_data.section_data);
}
$(document).trigger('iv:result:updated');
}
}
function markUrlAsChecked() {
apiRequest('markUrlAsChecked', {
url: App.state.result_url,
section: App.state.section,
random_id: App.state.random_id
}, onMarkUrlAsChecked);
}
function onMarkUrlAsChecked(result) {
if (!result.error) {
if (result) {
if (result.contest_ready) {
$('.contest-ready-tooltip-wrap').removeClass('tooltip-hidden');
$('.contest-ready-tooltip-wrap').click(function() {
var $tt = $(this);
$tt.addClass('tooltip-hidden');
setTimeout(function(){ $tt.remove(); }, 1000);
});
}
$result_section.attr('class', App.state.not_tracked ? 'result-tracked' : 'result-saved');
$url_mark_btn.addClass('disabled').removeClass('btn-primary');
$url_mark_btn.text($url_mark_btn.attr('data-mark'));
App.state.original_saved = true;
updateOriginalLabels();
updateSectionList();
} else {
$url_mark_btn.addClass('disabled').removeClass('btn-primary');
var field_value = App.editor.getValue();
if (App.state.saved_rules != field_value) {
return saveRules();
}
App.state.random_id = false;
App.state.mark_after_process = true;
showProgress($progress_bar);
$result_section.addClass('result-processing');
return processPageByRules();
}
} else {
showAlert(result.error);
}
}
function updateSectionList() {
clearTimeout(App.state.list_timeout);
apiRequest('getSectionData', {
url: App.state.result_url,
section: App.state.section
}, onUpdateSectionList);
}
function onUpdateSectionList(section_data) {
if (!section_data || section_data.values.updating) {
clearTimeout(App.state.list_timeout);
if (!App.state.list_tries) {
App.state.list_tries = 0;
}
App.state.list_tries++;
if (App.state.list_tries < 30) {
App.state.list_timeout = setTimeout(updateSectionList, 700);
} else {
App.state.list_tries = 0;
}
} else {
App.state.list_tries = 0;
}
$section_list.html(section_data.items);
for (var key in section_data.values) {
var val = section_data.values[key];
$('#count-' + key).width(val + '%').toggleClass('no-shown', !val);
}
}
function initHeader() {
$url_field.keydown(function(e) {
if (e.keyCode == 27) {
$url_form.get(0).reset();
closeUrlField();
e.preventDefault();
return;
}
});
$url_field.focus(function(e) {
openUrlField(true);
});
$('.url-status').click(function(e) {
openUrlField();
});
$('.dropdown', $url_form).on('show.bs.dropdown', function() {
closeUrlField();
});
$(document).click(function(e) {
if ($(e.target).closest('#url-form .input-dropdown, .url-status').length) {
return;
}
closeUrlField();
});
}
function updateNavBar() {
var $nav_menu = $('.nav-menu');
$nav_menu.addClass('nav-menu-can-fix');
if ($nav_menu.css('position') == 'fixed') {
$nav_menu.width($nav_menu.parent().width());
} else {
$nav_menu.css('width', 'auto');
}
}
function initRulesList() {
$('main.rules section .list-group-row').click(function(e) {
e.preventDefault();
$(this).addClass('hide');
$('+ .list-group', this).removeClass('hide');
});
$('main.rules .list-group button.close').click(function(e) {
e.preventDefault();
var $btn = $(this);
showConfirm(App.lang.delete_url_confirmation, function() {
var url = $btn.attr('data-url');
var section = $btn.parents('section').attr('data-section');
apiRequest('deleteUrlData', {
url: url,
section: section
}, function(result) {
if (!result.error) {
var $list_group = $btn.parents('.list-group');
var $section = $btn.parents('section');
$btn.parents('.list-group-item').remove();
if (!$('.list-group-item', $list_group).length) {
$section.remove();
}
$('.contest-btn', $section).toggleClass('inactive', !result.contest_ready);
} else {
showAlert(result.error);
}
});
}, App.lang.delete_url_confirm_button);
});
$('main.rules section .contest-btn').click(function(e) {
e.preventDefault();
var $btn = $(this);
if ($btn.hasClass('inactive')) {
return showAlert(App.lang.not_ready_for_contest_alert);
}
var confirm_text = ($btn.hasClass('in-contest') ? App.lang.submit_for_contest_confirmation : App.lang.submit_template_confirmation) || '';
var confirm_btn = ($btn.hasClass('in-contest') ? App.lang.submit_for_contest_confirm_button : App.lang.submit_template_confirm_button) || '';
var section = $btn.parents('section').attr('data-section');
confirm_text = confirm_text.replace(/\{domain\}/g, section);
showConfirm(confirm_text, function() {
apiRequest('sendToContest', {
section: section
}, function(result) {
if (!result.error) {
if (result) {
var $label1 = $btn.parents('.contest-label1-wrap');
var $label2 = $label1.next('.contest-label2-wrap');
var $status = $('.contest-rules-status', $label2);
$status.html('');
$label2.removeClass('hide');
$('.contest-resend-btn', $label2).addClass('hide');
$label1.addClass('hide');
if (result.ok) {
$status.html(result.status || '');
showAlert(result.ok, result.ok_options);
}
}
} else {
showAlert(result.error);
}
});
}, confirm_btn);
});
$('main.rules section .contest-remove-btn').click(function(e) {
e.preventDefault();
var $btn = $(this);
var $label2 = $(this).parents('.contest-label2-wrap');
var confirm_text = ($btn.hasClass('in-contest') ? App.lang.revoke_from_contest_confirmation : App.lang.revoke_template_confirmation) || '';
var confirm_btn = ($btn.hasClass('in-contest') ? App.lang.revoke_from_contest_confirm_button : App.lang.revoke_template_confirm_button) || '';
showConfirm(confirm_text, function() {
var section = $label2.parents('section').attr('data-section');
apiRequest('removeFromContest', {
section: section
}, function(result) {
if (!result.error) {
if (result) {
var $label1 = $label2.prev('.contest-label1-wrap');
var $status = $('.contest-rules-status', $label1);
$status.html('');
$label1.removeClass('hide');
$('.contest-resend-btn', $label2).addClass('hide');
$label2.addClass('hide');
if (result.ok) {
$status.html(result.status || '');
}
}
} else {
showAlert(result.error);
}
});
}, confirm_btn);
});
$('main.rules section .contest-resend-btn').click(function(e) {
e.preventDefault();
var $btn = $(this);
var confirm_text = ($btn.hasClass('in-contest') ? App.lang.resubmit_for_contest_confirmation : App.lang.resubmit_template_confirmation) || '';
var confirm_btn = ($btn.hasClass('in-contest') ? App.lang.resubmit_for_contest_confirm_button : App.lang.resubmit_template_confirm_button) || '';
var section = $btn.parents('section').attr('data-section');
confirm_text = confirm_text.replace(/\{domain\}/g, section);
showConfirm(confirm_text, function() {
apiRequest('removeFromContest', {
section: section
}, function(result) {
if (result.error) {
return showAlert(result.error);
}
$btn.addClass('hide');
setTimeout(function() {
apiRequest('sendToContest', {
section: section
}, function(result) {
if (result.error) {
showAlert(result.error);
} else if (result.ok) {
showAlert(result.ok, result.ok_options);
var $label2 = $btn.parents('.contest-label2-wrap');
$('.contest-rules-status', $label2).html(result.status || '');
}
});
}, 1500);
});
}, confirm_btn);
});
$(document).on('click', '.list-feedback-message-more', function(e) {
e.preventDefault();
var $btn = $(this);
var section = $btn.parents('section').attr('data-section');
var url_hash = $btn.attr('data-url-hash');
var offset = $btn.attr('data-offset');
apiRequest('getFeedbackComments', {
section: section,
url_hash: url_hash,
offset: offset
}, function(result) {
if (!result.error) {
if (result.comments) {
$btn.parents('.list-feedback-message').after(result.comments);
}
$btn.remove();
} else {
showAlert(result.error);
}
});
});
}
function initDeadlines() {
if (!App.deadlineInitTime) {
App.deadlineInitTime = Math.floor((new Date()).getTime() / 1000);
setTimeout(updateDeadlines, 100);
}
}
function formatDeadLinePeriod(period, short) {
if (period <= 0) {
return short ? 'checking' : '0 sec';
}
var hours = Math.floor(period / 3600);
if (hours > 1) {
return hours + (short ? 'h left' : ' hours');
}
var mins = Math.floor(period / 60);
if (mins > 1) {
return mins + (short ? 'm left' : ' min');
}
return period + (short ? 's left' : ' sec');
}
function updateDeadlines() {
var nowTime = Math.floor((new Date()).getTime() / 1000);
$('.iv-deadline[data-period]').map(function() {
var period = this.getAttribute('data-period');
var short = this.getAttribute('data-short');
period -= nowTime - App.deadlineInitTime;
var text = formatDeadLinePeriod(period, short);
if (this.innerText != text) {
if ($(this).hasClass('highlight')) {
$(this).toggleClass('soon', period > 0 && period < 86400);
}
$(this).text(text);
}
return this;
});
setTimeout(updateDeadlines, 100);
}
function versionString(ver) {
if (!ver) return '–';
var major = parseInt(ver);
var minor = Math.round(ver * 100) % 100;
return major + '.' + minor;
}
function initTemplatesList(options, search_opts) {
var $searchField = $('.templates-filter-input');
var $results = $('.templates-list');
var templatesListSortBy = 'domain';
var templatesListSortAsc = true;
$('.cell-sort').on('click', function(e) {
var sortEl = $(this);
var sortBy = sortEl.attr('data-sort-by');
var sortAsc = sortEl.hasClass('sort-asc');
if (sortBy == templatesListSortBy) {
templatesListSortAsc = !sortAsc;
} else {
templatesListSortBy = sortBy;
templatesListSortAsc = false;
}
updateTemplatesList();
$searchField.trigger('datachange');
});
var updateTemplatesList = function() {
if (App.templatesList) {
var sortBy = templatesListSortBy;
var sortAsc = templatesListSortAsc;
$('.cell-sort').each(function() {
var sortEl = $(this);
var curSortBy = sortEl.attr('data-sort-by');
sortEl.toggleClass('sort-active', sortBy == curSortBy);
sortEl.toggleClass('sort-asc', sortAsc && sortBy == curSortBy);
});
App.templatesList.sort(function(ad1, ad2) {
var v1 = sortAsc ? ad1 : ad2;
var v2 = sortAsc ? ad2 : ad1;
if (typeof v1[sortBy + '_asc'] !== 'undefined') {
return (v1[sortBy] - v2[sortBy]) || (v1[sortBy + '_asc'] - v2[sortBy + '_asc']) || (v1.date - v2.date);
}
if (v1[sortBy] && v1[sortBy].localeCompare) {
return v1[sortBy].localeCompare(v2[sortBy]) || (v1.date - v2.date);
}
return (v1[sortBy] - v2[sortBy]) || (v1.date - v2.date);
});
}
};
var loadTemplatesList = function(opts) {
opts = opts || {};
apiRequest('getProductionTemplatesList', {
offset_id: opts.offset
}, function(result) {
if (result.error) {
if (!opts.retry) opts.retry = 1;
else opts.retry++;
setTimeout(function(){ loadTemplatesList(opts); }, opts.retry * 1000);
} else {
if (opts.retry) {
opts.retry = 0;
}
processTemplatesList(result, opts);
}
});
};
var getTemplatesList = function() {
var _data = App.templatesList;
if (_data === false) {
return false;
} else if (_data) {
return _data;
}
App.templatesList = false;
App.templatesListIsLoading = true;
if (options.init_items) {
setTimeout(function() {
processTemplatesList(options.init_items);
}, 10);
} else {
loadTemplatesList({offset: 0});
}
return false;
};
var processTemplatesList = function(result, opts) {
opts = opts || {};
if (result.items) {
if (!App.templatesList) {
App.templatesList = [];
}
for (var i = 0; i < result.items.length; i++) {
var item = result.items[i];
item._values = [
item.domain.toLowerCase(),
];
if (options.prepareItem) {
options.prepareItem(item);
}
App.templatesList.push(item);
}
updateTemplatesList();
$searchField.trigger('contentchange');
}
if (result.next_offset) {
opts.offset = result.next_offset;
loadTemplatesList(opts);
} else {
App.templatesListIsLoading = false;
$searchField.trigger('dataready');
}
}
$searchField.initSearch($.extend({
$results: $results,
emptyQueryEnabled: true,
updateOnInit: true,
resultsNotScrollable: true,
getData: getTemplatesList
}, search_opts));
}
$('body').removeClass('no-transition');
/*!
Autosize 3.0.20
license: MIT
http://www.jacklmoore.com/autosize
*/
!function(e,t){if("function"==typeof define&&define.amd)define(["exports","module"],t);else if("undefined"!=typeof exports&&"undefined"!=typeof module)t(exports,module);else{var n={exports:{}};t(n.exports,n),e.autosize=n.exports}}(this,function(e,t){"use strict";function n(e){function t(){var t=window.getComputedStyle(e,null);"vertical"===t.resize?e.style.resize="none":"both"===t.resize&&(e.style.resize="horizontal"),s="content-box"===t.boxSizing?-(parseFloat(t.paddingTop)+parseFloat(t.paddingBottom)):parseFloat(t.borderTopWidth)+parseFloat(t.borderBottomWidth),isNaN(s)&&(s=0),l()}function n(t){var n=e.style.width;e.style.width="0px",e.offsetWidth,e.style.width=n,e.style.overflowY=t}function o(e){for(var t=[];e&&e.parentNode&&e.parentNode instanceof Element;)e.parentNode.scrollTop&&t.push({node:e.parentNode,scrollTop:e.parentNode.scrollTop}),e=e.parentNode;return t}function r(){var t=e.style.height,n=o(e),r=document.documentElement&&document.documentElement.scrollTop;e.style.height="auto";var i=e.scrollHeight+s;return 0===e.scrollHeight?void(e.style.height=t):(e.style.height=i+"px",u=e.clientWidth,n.forEach(function(e){e.node.scrollTop=e.scrollTop}),void(r&&(document.documentElement.scrollTop=r)))}function l(){r();var t=Math.round(parseFloat(e.style.height)),o=window.getComputedStyle(e,null),i=Math.round(parseFloat(o.height));if(i!==t?"visible"!==o.overflowY&&(n("visible"),r(),i=Math.round(parseFloat(window.getComputedStyle(e,null).height))):"hidden"!==o.overflowY&&(n("hidden"),r(),i=Math.round(parseFloat(window.getComputedStyle(e,null).height))),a!==i){a=i;var l=d("autosize:resized");try{e.dispatchEvent(l)}catch(e){}}}if(e&&e.nodeName&&"TEXTAREA"===e.nodeName&&!i.has(e)){var s=null,u=e.clientWidth,a=null,p=function(){e.clientWidth!==u&&l()},c=function(t){window.removeEventListener("resize",p,!1),e.removeEventListener("input",l,!1),e.removeEventListener("keyup",l,!1),e.removeEventListener("autosize:destroy",c,!1),e.removeEventListener("autosize:update",l,!1),Object.keys(t).forEach(function(n){e.style[n]=t[n]}),i.delete(e)}.bind(e,{height:e.style.height,resize:e.style.resize,overflowY:e.style.overflowY,overflowX:e.style.overflowX,wordWrap:e.style.wordWrap});e.addEventListener("autosize:destroy",c,!1),"onpropertychange"in e&&"oninput"in e&&e.addEventListener("keyup",l,!1),window.addEventListener("resize",p,!1),e.addEventListener("input",l,!1),e.addEventListener("autosize:update",l,!1),e.style.overflowX="hidden",e.style.wordWrap="break-word",i.set(e,{destroy:c,update:l}),t()}}function o(e){var t=i.get(e);t&&t.destroy()}function r(e){var t=i.get(e);t&&t.update()}var i="function"==typeof Map?new Map:function(){var e=[],t=[];return{has:function(t){return e.indexOf(t)>-1},get:function(n){return t[e.indexOf(n)]},set:function(n,o){e.indexOf(n)===-1&&(e.push(n),t.push(o))},delete:function(n){var o=e.indexOf(n);o>-1&&(e.splice(o,1),t.splice(o,1))}}}(),d=function(e){return new Event(e,{bubbles:!0})};try{new Event("test")}catch(e){d=function(e){var t=document.createEvent("Event");return t.initEvent(e,!0,!1),t}}var l=null;"undefined"==typeof window||"function"!=typeof window.getComputedStyle?(l=function(e){return e},l.destroy=function(e){return e},l.update=function(e){return e}):(l=function(e,t){return e&&Array.prototype.forEach.call(e.length?e:[e],function(e){return n(e,t)}),e},l.destroy=function(e){return e&&Array.prototype.forEach.call(e.length?e:[e],o),e},l.update=function(e){return e&&Array.prototype.forEach.call(e.length?e:[e],r),e}),t.exports=l});