var mroot = '(Media Root)'; var matchesp = ' ~matches~ '; function quot(str) { if (!str) return '""'; if (str.indexOf(" ") == -1 && str.indexOf('"') == -1 && str.indexOf("\\") == -1) return str; return '{' + str + '}'; } function splitarg(arg) { o = { 'arg': arg, 'opt': '' }; i = arg.indexOf(' '); if (i > -1) { o.arg = arg.substring(0, i); o.opt = arg.substring(i + 1); } return o; } function fixupdown() { $('#ruleset a.uprule').enable().filter(':first').disable(); $('#ruleset a.downrule').enable().filter(':last').disable(); $('#ruleset a.uprule img').attr('src', '/img/nav/up.png') .first().attr('src', '/img/nav/up-grey.png'); $('#ruleset a.downrule img').attr('src', '/img/nav/down.png') .last().attr('src', '/img/nav/down-grey.png'); } function changed(c) { if (typeof(changed.last) == 'number' && c == changed.last) return; if (c) { $('#b_save,#b_revert').button('enable'); $('#pendingnote').show(); } else { $('#b_save,#b_revert').button('disable'); $('#pendingnote').hide(); } changed.last = c; } // Setters convert from config file format to display var setters = { noarg: function(cmd, a) { return ''; }, int: function(cmd, a) { var b = a.split(" "); if (b.length == 1) { op = '='; val = a; } else { op = b[0]; val = b[1]; } return op + ' ' + val; }, substr: function(cmd, a) { return a; }, 'string': function(cmd, a) { return a; }, select: function(cmd, a) { return schema.criterion[cmd].select[a]; }, textmatch: function(cmd, a) { return a.replace('~~', matchesp); }, intmatch: function(cmd, a) { return a.replace('~~', matchesp); } }; // Getters convert from display to config file format var getters = { noarg: function(cmd, a) { return ''; }, int: function(cmd, a) { var b = a.split(" "); if (b.length != 2) return a; if (b[0] == '=') return b[1]; return a; }, substr: function(cmd, a) { return a; }, 'string': function(cmd, a) { return a; }, select: function(cmd, a) { var c = schema.criterion[cmd].select; for (key in c) if (c[key] == a) return key; return 'UNKNOWNKEY (' + a + ')'; }, textmatch: function(cmd, a) { return a.replace(matchesp, '~~'); }, intmatch: function(cmd, a) { return a.replace(matchesp, '~~'); } }; function clauseconf(clause) { var s = ''; clause.find('tbody:first > tr.clause,tbody:first > tr.compositeclause') .each(function() { if ($(this).hasClass('compositeclause')) { cc = clauseconf($(this).find('table:first')); cmd = $(this).attr('cmd'); if (cc && cc.length) s += cmd + ' {' + cc + '} '; return; } cmd = $(this).find('th.cmd').attr('cmd'); negate = $(this).find('th.cmd').attr('negate'); c = schema.criterion[cmd]; val = $.trim($(this).find('td.val').html()); if (getters[c.type]) val = getters[c.type](cmd, val); if (negate == '1') s += '!'; s += cmd + ' ' + quot(val) + ' '; }); return s; } function ruleconf(rule) { var s = ''; if (rule.hasClass('ruledisabled')) s += '## '; if (rule.attr('type') == 'folder') s += 'folder '; else if (rule.attr('depth') > 0) s += 'recurse ' + rule.attr('depth') + ' '; s += clauseconf(rule); act = rule.find('tr.action th.cmd').attr('cmd'); arg = $.trim(rule.find('tr.action td.val').text()); if (schema.action[act].argtype == 'folder' && arg == mroot) arg = ''; if (act != 'continue') { switch (schema.action[act].argtype) { case 'none': s += 'action ' + act; break; case 'select': arg = $.trim( rule.find('tr.action td.val').attr('val')); s += 'action {' + act + ' ' + quot(arg) + '}'; break; case 'selectx': arg = $.trim( rule.find('tr.action td.val').attr('val')); opt = $.trim( rule.find('tr.action td.val').attr('opt')); if (opt) arg += ' ' + opt; s += 'action {' + act + ' ' + quot(arg) + '}'; break; default: s += 'action {' + act + ' ' + quot(arg) + '}'; break; } } return s; } function conffile() { var s = ''; $('div.rule').each(function(i) { comment = $(this).find('span.comment').text(); if (comment != 'Unnamed rule') s += '# ' + comment + '\n'; s += ruleconf($(this)) + '\n'; }); return s; } function rulerefresh(rule) { if (!showraw) rule.find('.raw').hide(); rule.find('.raw').html(ruleconf(rule)); rule.find('tr.clause th.title,tr.compositeclause th.title') .text('And:').first().text('If:'); rule.find('tr.compositeclause').each(function(e) { cmd = $(this).attr('cmd'); label = schema.criterion[cmd].label; $(this).find('table th.title').text(label + ':') .first().text('If:'); }); if (rule.find('tr.clause,tr.compositeclause').length < 1) { rule.find('tr.action th.title').text('Always:'); rule.find('tr.otherwise,div.criteria,div.arrow').hide(); } else { rule.find('tr.action th.title').text('Then:'); rule.find('tr.otherwise,div.criteria,div.arrow').show(); } if (rule.attr('type') == 'recurse') rule.find('.recursecomment .depth').text(rule.attr('depth') + ' level' + (rule.attr('depth') == 1 ? '' : 's')); } function critdesc(cmd, negate) { var c = schema.criterion[cmd]; if (!c) return 'Unknown (' + cmd + ')'; if (negate == '1' && c.idesc) return c.idesc; else if (negate == '1') return c.desc + ' is not'; else return c.desc; } function composite_criterion(c, data) { s = '
' + '' + '' + ' ' + '' + '' + ' ' + c.desc + ' |
' + conffile() + '') .dialog({ height: 'auto', width: 'auto', autoOpen: true, modal: true, buttons: { "Close": function() { $(this).dialog('close'); } } }); }); $('#b_test').button({icons: {primary: "ui-icon-check"}}); $('#b_run').button({icons: {primary: "ui-icon-play"}}); $('#b_test,#b_run') .on('click', function(e) { e.preventDefault(); var id = $(this).attr('id'); $('#testresults_inner').empty() .html(' Running rules... Please wait...'); if (id == 'b_test') { $('#dryrun_info').show(); dryrun = 1; } else { if (!confirm('Run ruleset now?')) return; $('#dryrun_info').hide(); dryrun = 0; } $('#testresults').dialog({ /* 'auto' is too small: use a big chunk of the available space */ height: $(window).height()*0.8, width: $(window).width()*0.75, draggable: true, resizable: true, autoOpen: true, buttons: { "Close": function() { $(this).dialog('close'); } } }); $.post('test.jim', { dir: $('span.dir').text(), dryrun: dryrun, data: conffile() }, function(data) { $('#testresults_inner').text(data); }); }); $('#b_raw').button({icons: {primary: "ui-icon-gear"}}) .on('click', function(e) { $('#ruleset div.raw').toggle('slow'); showraw = !showraw; $.get('save.jim?act=raw&val=' + (showraw ? 1 : 0)); }); $('#b_macro').button({disabled: true, icons: {primary: "ui-icon-plus"}}); $('#macros').on('click', '#b_macro', function(e) { e.preventDefault(); var set = $('#macroselect').val(); if (!set) return; var desc = macros[set].desc; $(this).dojConfirmAction({ question: 'Add ' + desc + '?', yesAnswer: 'Yes', cancelAnswer: 'No' }, function(el) { $('.jcaquestion').remove(); $.each(macros[set].rules, function(k, v) { addrule(last_ruleid + 1, v).hide().addClass('hl'); }); $('.hl').slideDown('slow', function() { $(this).removeClass('hl'); }); fixupdown(); changed(1); $('#macroselect').val(0); }); }); changed(0); function addcriterion(rule, target) { var type = rule.attr('type'); switch (type) { case 'folder': options = select_folder_criteria; break; default: options = select_file_criteria; break; } // Populate select box and reset form. $('#newcondition_cmd').empty(); $.each(options, function(k, v) { $('#newcondition_cmd').append( $('').attr('value', k).html(v) ); }); $('#newcondition_negate').prop('checked', false); $('#newcondition_cmd').trigger('change'); $('#newcondition').dialog({ height: 'auto', width: 'auto', draggable: true, resizable: false, autoOpen: true, position: { my: 'bottom left', at: 'top right', of: target, collision: 'fit' }, buttons: { "Add Condition": function() { $(this).dialog('close'); var val = $('#newcondition_cmd').val(); var negate = $('#newcondition_negate') .prop('checked') ? '1' : '0'; var obj = { cmd: val, negate: negate, arg: schema.criterion[val].def, criteria: [] }; target.find('tbody:first') .append(criterion(obj)); changed(1); rulerefresh(rule); }, "Cancel": function() { $(this).dialog('close'); } } }); } $('#ruleset') .on('click', 'a.editclause', function(e) { e.preventDefault(); edit_clause($(this).closest('tr.clause')); }) .on('click', 'a.addcriterion', function(e) { e.preventDefault(); var rule = $(this).closest('div.rule'); addcriterion(rule, rule.find('table.criteria')); }) .on('click', 'a.editcomment', function(e) { e.preventDefault(); edit_text($(this), 'Edit rule name', $(this).siblings('span.comment').text(), function(obj, text) { $(obj).siblings('span.comment').text(text); changed(1); }); }) .on('click', 'a.editdepth', function(e) { e.preventDefault(); var rule = $(this).closest('div.rule'); edit_plainint($(this), 'Edit recursion depth', 'Set recursion depth: ', rule.attr('depth'), 0, 16, function(obj, val) { if (val >= 0 && val < 16) { rule.attr('depth', val); if (val >= 1) { rule.attr('type', 'recurse'); rule.find('.recursecomment').show(); rule.find('.filecomment').hide(); } else { rule.attr('type', 'file'); rule.find('.recursecomment').hide(); rule.find('.filecomment').show(); } rulerefresh(rule); changed(1); } }); }) .on('click', 'a.uprule', function(e) { e.preventDefault(); if ($(this).hasClass('ui-state-disabled')) return false; var rule = $(this).closest('div.rule'); var target = $(rule).prev('div.rule'); if (!target || !target.length) return false; $(rule).addClass('hl').slideUp('slow', function() { $(this).insertBefore($(target)) .slideDown('slow', function() { $(this).removeClass('hl'); fixupdown(); changed(1); }); }); }) .on('click', 'a.downrule', function(e) { e.preventDefault(); if ($(this).hasClass('ui-state-disabled')) return false; var rule = $(this).closest('div.rule'); var target = $(rule).next('div.rule'); if (!target || !target.length) return false; $(rule).addClass('hl').slideUp('slow', function() { $(this).insertAfter($(target)) .slideDown('slow', function() { $(this).removeClass('hl'); fixupdown(); changed(1); }); }); }) .on('click', 'a.cprule', function(e) { e.preventDefault(); $(this).dojConfirmAction({ question: 'Duplicate rule?', yesAnswer: 'Yes', cancelAnswer: 'No' }, function(el) { $('.jcaquestion').remove(); var rule = $(el).closest('div.rule'); rule.clone() .attr('id', 'rule_' + ++last_ruleid) .addClass('hl').hide() .insertAfter(rule) .slideDown('slow', function() { $(this).removeClass('hl'); changed(1); }) .find('span.comment').append(' (copy)'); }); }) .on('click', 'a.enadisrule', function(e) { e.preventDefault(); var rule = $(this).closest('div.rule') .toggleClass('ruledisabled'); rule.find('span.disabledtext').toggleClass('hidden', !rule.hasClass('ruledisabled')); rulerefresh(rule); changed(1); }) .on('click', 'a.editaction', function(e) { e.preventDefault(); var rule = $(this).closest('div.rule'); var type = rule.attr('type'); switch (type) { case 'folder': options = select_folder_actions; break; default: options = select_file_actions; break; } $('#edit_action_act').empty(); $.each(options, function(k, v) { $('#edit_action_act').append( $('').attr('value', k).text(v) ); }); var cmd = rule.find('tr.action th.cmd').attr('cmd'); var arg = rule.find('tr.action td.val').html(); if (schema.action[cmd].argtype == 'none') arg = ''; if (schema.action[cmd].argtype == 'folder' && arg == mroot) arg = ''; $('#edit_action_act').val(cmd).trigger('change'); switch (schema.action[cmd].argtype) { case 'selectx': opt = rule.find('tr.action td.val').attr('opt'); $('#edit_action_select_arg').val(opt); // Pass-through... case 'select': arg = rule.find('tr.action td.val').attr('val'); $('#edit_action_select_field').val(arg); $.each(schema.action[cmd].select, function(k, v) { if (arg == v) $('#edit_action_select_field').val(k); }); break; default: $('#edit_action_arg').val(arg); break; } $('#edit_action').dialog({ height: 'auto', width: 'auto', draggable: false, resizable: false, autoOpen: true, position: { my: 'bottom left', at: 'top right', of: rule, collision: 'fit' }, buttons: { "Save": function() { cmd = $('#edit_action_act').val(); switch (schema.action[cmd].argtype) { case 'select': arg = $('#edit_action_select_field') .val(); break; case 'selectx': arg = $('#edit_action_select_field') .val(); opt = $.trim( $('#edit_action_select_arg').val() ); if (opt) arg += ' ' + opt; break; default: arg = $('#edit_action_arg').val(); break; } rule.find('table.action tbody').empty() .append(action({cmd: cmd, arg: arg})); $(this).dialog('close'); rulerefresh(rule); changed(1); }, "Close": function() { $(this).dialog('close'); } } }); }) .on('click', 'a.delclause', function(e) { e.preventDefault(); $(this).dojConfirmAction({ question: 'Delete condition?', yesAnswer: 'Yes', cancelAnswer: 'No' }, function(el) { var rule = $(el).closest('div.rule'); $(el).closest('tr.clause').fadeOut('slow', function() { $(this).remove(); rulerefresh(rule); changed(1); }); }); }) .on('click', 'a.delrule', function(e) { e.preventDefault(); $(this).dojConfirmAction({ question: 'Delete entire rule?', yesAnswer: 'Yes', cancelAnswer: 'No' }, function(el) { $(el).closest('div.rule') .addClass('hl') .slideUp('slow', function() { $(this).remove(); changed(1); fixupdown(); if ($('div.rule').length < 1) $('#ruleset').attr('empty', true) .html($('#empty_rulebase').html()); }); }); }) .on('click', 'a.delsubclause', function(e) { e.preventDefault(); $(this).dojConfirmAction({ question: 'Delete sub-condition?', yesAnswer: 'Yes', cancelAnswer: 'No' }, function(el) { var rule = $(el).closest('div.rule'); $(el).closest('tr.compositeclause') .fadeOut('slow', function() { $(this).remove(); rulerefresh(rule); changed(1); }); }); }) .on('click', 'a.addsubcriterion', function(e) { e.preventDefault(); var rule = $(this).closest('div.rule'); var clause = $(this).closest('table.compositeclause'); addcriterion(rule, clause); }) .on('dblclick', 'div.raw', function(e) { e.preventDefault(); $(this).toggleClass("rawvis"); }); $('#edit_action_act').on('change', function(e) { var cmd = $(this).val(); $('#edit_action_arg').show(); $('#edit_action_select_field').hide(); $('#edit_action_select_arg').hide(); switch (schema.action[cmd].argtype) { case 'none': $('#edit_action_arg').hide().disable(); break; case 'selectx': $('#edit_action_select_arg').empty().show(); // Fall-through... case 'select': $('#edit_action_arg').hide(); $('#edit_action_select_field').empty().show(); $.each(schema.action[cmd].select, function(k, v) { $('#edit_action_select_field').append( $('') .attr('value', k).text(v) ); }); break; default: $('#edit_action_arg').enable(); break; } $('.edit_action_help').hide(); $('#edit_action_help_' + schema.action[cmd].argtype).show(); if (schema.action[cmd].argtype == 'none') $('#edit_action_arg').disable(); else $('#edit_action_arg').enable(); $('.edit_action_help').hide(); $('#edit_action_help_' + schema.action[cmd].argtype).show(); }); $('#newcondition_cmd').on('change', function(e) { var cmd = $(this).val(); if (schema.criterion[cmd].negate) $('#newcondition_negate').enable(); else $('#newcondition_negate') .prop('checked', false) .disable(); }); // Set up macros $.each(macros, function(key, val) { $('#macroselect').append( $('').attr('value', key).text(val.desc) ); }); $('#macroselect').on('change', function(el) { if ($(this).val() == "0") $('#b_macro').button('disable'); else $('#b_macro').button('enable'); }); loadrules($('span.dir').text()); $(document).tooltip(); });