提交 c286e59d 编写于 作者: J Jason Park

remove global vars

上级 a58a553c
...@@ -111,7 +111,7 @@ ...@@ -111,7 +111,7 @@
<script src="js/sigma/plugins/sigma.plugins.dragNodes.min.js"></script> <script src="js/sigma/plugins/sigma.plugins.dragNodes.min.js"></script>
<script src="js/ace/ace.js"></script> <script src="js/ace/ace.js"></script>
<script src="js/ace/ext-language_tools.js"></script> <script src="js/ace/ext-language_tools.js"></script>
<script src="js/module/tracer_manager.js"></script> <script src="js/tracer_manager.js"></script>
<script src="js/module/tracer.js"></script> <script src="js/module/tracer.js"></script>
<script src="js/module/log_tracer.js"></script> <script src="js/module/log_tracer.js"></script>
<script src="js/module/array2d.js"></script> <script src="js/module/array2d.js"></script>
......
...@@ -13,7 +13,7 @@ Array2DTracer.prototype = $.extend(true, Object.create(Tracer.prototype), { ...@@ -13,7 +13,7 @@ Array2DTracer.prototype = $.extend(true, Object.create(Tracer.prototype), {
this.$container.append(this.$table); this.$container.append(this.$table);
}, },
_notify: function (x, y, v) { _notify: function (x, y, v) {
tm.pushStep(this.capsule, { this.tm.pushStep(this.capsule, {
type: 'notify', type: 'notify',
x: x, x: x,
y: y, y: y,
...@@ -22,7 +22,7 @@ Array2DTracer.prototype = $.extend(true, Object.create(Tracer.prototype), { ...@@ -22,7 +22,7 @@ Array2DTracer.prototype = $.extend(true, Object.create(Tracer.prototype), {
return this; return this;
}, },
_denotify: function (x, y) { _denotify: function (x, y) {
tm.pushStep(this.capsule, { this.tm.pushStep(this.capsule, {
type: 'denotify', type: 'denotify',
x: x, x: x,
y: y y: y
...@@ -93,14 +93,14 @@ Array2DTracer.prototype = $.extend(true, Object.create(Tracer.prototype), { ...@@ -93,14 +93,14 @@ Array2DTracer.prototype = $.extend(true, Object.create(Tracer.prototype), {
type: type type: type
}; };
$.extend(step, coord); $.extend(step, coord);
tm.pushStep(this.capsule, step); this.tm.pushStep(this.capsule, step);
}, },
processStep: function (step, options) { processStep: function (step, options) {
switch (step.type) { switch (step.type) {
case 'notify': case 'notify':
if (step.v) { if (step.v) {
var $row = this.$table.find('.mtbl-row').eq(step.x); var $row = this.$table.find('.mtbl-row').eq(step.x);
$row.find('.mtbl-cell').eq(step.y).text(refineNumber(step.v)); $row.find('.mtbl-cell').eq(step.y).text(TracerUtil.refineNumber(step.v));
} }
case 'denotify': case 'denotify':
case 'select': case 'select':
...@@ -130,7 +130,7 @@ Array2DTracer.prototype = $.extend(true, Object.create(Tracer.prototype), { ...@@ -130,7 +130,7 @@ Array2DTracer.prototype = $.extend(true, Object.create(Tracer.prototype), {
if (Tracer.prototype.setData.apply(this, arguments)) { if (Tracer.prototype.setData.apply(this, arguments)) {
this.$table.find('.mtbl-row').each(function (i) { this.$table.find('.mtbl-row').each(function (i) {
$(this).children().each(function (j) { $(this).children().each(function (j) {
$(this).text(refineNumber(D[i][j])); $(this).text(TracerUtil.refineNumber(D[i][j]));
}); });
}); });
return true; return true;
...@@ -143,7 +143,7 @@ Array2DTracer.prototype = $.extend(true, Object.create(Tracer.prototype), { ...@@ -143,7 +143,7 @@ Array2DTracer.prototype = $.extend(true, Object.create(Tracer.prototype), {
for (var j = 0; j < D[i].length; j++) { for (var j = 0; j < D[i].length; j++) {
var $cell = $('<div class="mtbl-cell">') var $cell = $('<div class="mtbl-cell">')
.css(this.getCellCss()) .css(this.getCellCss())
.text(refineNumber(D[i][j])); .text(TracerUtil.refineNumber(D[i][j]));
$row.append($cell); $row.append($cell);
} }
} }
......
...@@ -46,15 +46,15 @@ DirectedGraphTracer.prototype = $.extend(true, Object.create(Tracer.prototype), ...@@ -46,15 +46,15 @@ DirectedGraphTracer.prototype = $.extend(true, Object.create(Tracer.prototype),
this.graph = this.capsule.graph = this.s.graph; this.graph = this.capsule.graph = this.s.graph;
}, },
_setTreeData: function (G, root) { _setTreeData: function (G, root) {
tm.pushStep(this.capsule, {type: 'setTreeData', arguments: arguments}); this.tm.pushStep(this.capsule, {type: 'setTreeData', arguments: arguments});
return this; return this;
}, },
_visit: function (target, source) { _visit: function (target, source) {
tm.pushStep(this.capsule, {type: 'visit', target: target, source: source}); this.tm.pushStep(this.capsule, {type: 'visit', target: target, source: source});
return this; return this;
}, },
_leave: function (target, source) { _leave: function (target, source) {
tm.pushStep(this.capsule, {type: 'leave', target: target, source: source}); this.tm.pushStep(this.capsule, {type: 'leave', target: target, source: source});
return this; return this;
}, },
processStep: function (step, options) { processStep: function (step, options) {
......
...@@ -13,7 +13,7 @@ LogTracer.prototype = $.extend(true, Object.create(Tracer.prototype), { ...@@ -13,7 +13,7 @@ LogTracer.prototype = $.extend(true, Object.create(Tracer.prototype), {
this.$container.append(this.$wrapper); this.$container.append(this.$wrapper);
}, },
_print: function (msg) { _print: function (msg) {
tm.pushStep(this.capsule, {type: 'print', msg: msg}); this.tm.pushStep(this.capsule, {type: 'print', msg: msg});
return this; return this;
}, },
processStep: function (step, options) { processStep: function (step, options) {
......
function Tracer(name) { function Tracer(name) {
this.module = this.constructor; this.module = this.constructor;
this.capsule = tm.allocate(this); this.capsule = this.tm.allocate(this);
$.extend(this, this.capsule); $.extend(this, this.capsule);
this.setName(name); this.setName(name);
return this.new; return this.new;
...@@ -8,23 +8,24 @@ function Tracer(name) { ...@@ -8,23 +8,24 @@ function Tracer(name) {
Tracer.prototype = { Tracer.prototype = {
constructor: Tracer, constructor: Tracer,
tm: null,
_setData: function () { _setData: function () {
var args = Array.prototype.slice.call(arguments); var args = Array.prototype.slice.call(arguments);
tm.pushStep(this.capsule, {type: 'setData', args: toJSON(args)}); this.tm.pushStep(this.capsule, {type: 'setData', args: TracerUtil.toJSON(args)});
return this; return this;
}, },
_clear: function () { _clear: function () {
tm.pushStep(this.capsule, {type: 'clear'}); this.tm.pushStep(this.capsule, {type: 'clear'});
return this; return this;
}, },
_wait: function () { _wait: function () {
tm.newStep(); this.tm.newStep();
return this; return this;
}, },
processStep: function (step, options) { processStep: function (step, options) {
switch (step.type) { switch (step.type) {
case 'setData': case 'setData':
this.setData.apply(this, fromJSON(step.args)); this.setData.apply(this, TracerUtil.fromJSON(step.args));
break; break;
case 'clear': case 'clear':
this.clear(); this.clear();
...@@ -42,7 +43,7 @@ Tracer.prototype = { ...@@ -42,7 +43,7 @@ Tracer.prototype = {
$name.text(name || this.defaultName); $name.text(name || this.defaultName);
}, },
setData: function () { setData: function () {
var data = toJSON(arguments); var data = TracerUtil.toJSON(arguments);
if (!this.new && this.lastData == data) return true; if (!this.new && this.lastData == data) return true;
this.new = this.capsule.new = false; this.new = this.capsule.new = false;
this.lastData = this.capsule.lastData = data; this.lastData = this.capsule.lastData = data;
......
...@@ -30,22 +30,22 @@ WeightedDirectedGraphTracer.prototype = $.extend(true, Object.create(DirectedGra ...@@ -30,22 +30,22 @@ WeightedDirectedGraphTracer.prototype = $.extend(true, Object.create(DirectedGra
}); });
}, },
_weight: function (target, weight) { _weight: function (target, weight) {
tm.pushStep(this.capsule, {type: 'weight', target: target, weight: weight}); this.tm.pushStep(this.capsule, {type: 'weight', target: target, weight: weight});
return this; return this;
}, },
_visit: function (target, source, weight) { _visit: function (target, source, weight) {
tm.pushStep(this.capsule, {type: 'visit', target: target, source: source, weight: weight}); this.tm.pushStep(this.capsule, {type: 'visit', target: target, source: source, weight: weight});
return this; return this;
}, },
_leave: function (target, source, weight) { _leave: function (target, source, weight) {
tm.pushStep(this.capsule, {type: 'leave', target: target, source: source, weight: weight}); this.tm.pushStep(this.capsule, {type: 'leave', target: target, source: source, weight: weight});
return this; return this;
}, },
processStep: function (step, options) { processStep: function (step, options) {
switch (step.type) { switch (step.type) {
case 'weight': case 'weight':
var targetNode = this.graph.nodes(this.n(step.target)); var targetNode = this.graph.nodes(this.n(step.target));
if (step.weight !== undefined) targetNode.weight = refineNumber(step.weight); if (step.weight !== undefined) targetNode.weight = TracerUtil.refineNumber(step.weight);
break; break;
case 'visit': case 'visit':
case 'leave': case 'leave':
...@@ -53,7 +53,7 @@ WeightedDirectedGraphTracer.prototype = $.extend(true, Object.create(DirectedGra ...@@ -53,7 +53,7 @@ WeightedDirectedGraphTracer.prototype = $.extend(true, Object.create(DirectedGra
var targetNode = this.graph.nodes(this.n(step.target)); var targetNode = this.graph.nodes(this.n(step.target));
var color = visit ? this.color.visited : this.color.left; var color = visit ? this.color.visited : this.color.left;
targetNode.color = color; targetNode.color = color;
if (step.weight !== undefined) targetNode.weight = refineNumber(step.weight); if (step.weight !== undefined) targetNode.weight = TracerUtil.refineNumber(step.weight);
if (step.source !== undefined) { if (step.source !== undefined) {
var edgeId = this.e(step.source, step.target); var edgeId = this.e(step.source, step.target);
var edge = this.graph.edges(edgeId); var edge = this.graph.edges(edgeId);
...@@ -97,7 +97,7 @@ WeightedDirectedGraphTracer.prototype = $.extend(true, Object.create(DirectedGra ...@@ -97,7 +97,7 @@ WeightedDirectedGraphTracer.prototype = $.extend(true, Object.create(DirectedGra
target: this.n(j), target: this.n(j),
color: this.color.default, color: this.color.default,
size: 1, size: 1,
weight: refineNumber(G[i][j]) weight: TracerUtil.refineNumber(G[i][j])
}); });
} }
} }
......
$.ajaxSetup({cache: false, dataType: "text"}); var executeData = function (tracerManager, data) {
try {
$(document).on('click', 'a', function (e) { tracerManager.deallocateAll();
e.preventDefault(); eval(data);
tracerManager.visualize();
if (!window.open($(this).attr('href'), '_blank')) { } catch (err) {
alert('Please allow popups for this site'); return err;
} finally {
tracerManager.removeUnallocated();
} }
});
$('.btn input').click(function (e) {
e.stopPropagation();
});
var tm = new TracerManager();
$('#interval').on('change', function () {
tm.interval = Number.parseFloat($(this).val() * 1000);
showInfoToast('Tracing interval has been set to ' + tm.interval / 1000 + ' second(s).');
});
var $module_container = $('.module_container');
ace.require("ace/ext/language_tools");
var initEditor = function (id) {
var editor = ace.edit(id);
editor.setOptions({
enableBasicAutocompletion: true,
enableSnippets: true,
enableLiveAutocompletion: true
});
editor.setTheme("ace/theme/tomorrow_night_eighties");
editor.session.setMode("ace/mode/javascript");
editor.$blockScrolling = Infinity;
return editor;
}; };
var dataEditor = initEditor('data'); var executeDataAndCode = function (tracerManager, data, code) {
var codeEditor = initEditor('code');
var lastFile = null;
dataEditor.on('change', function () {
var data = dataEditor.getValue();
if (lastFile) cachedFile[lastFile].data = data;
try { try {
tm.deallocateAll(); tracerManager.deallocateAll();
eval(data); eval(data);
tm.visualize(); eval(code);
tracerManager.visualize();
} catch (err) { } catch (err) {
return err;
} finally { } finally {
tm.removeUnallocated(); tracerManager.removeUnallocated();
} }
});
codeEditor.on('change', function () {
var code = codeEditor.getValue();
if (lastFile) cachedFile[lastFile].code = code;
});
var cachedFile = {};
var loading = false;
var isScratchPaper = function (category, algorithm) {
return category == null && algorithm == 'scratch_paper';
};
var getAlgorithmDir = function (category, algorithm) {
if (isScratchPaper(category, algorithm)) return './algorithm/scratch_paper/';
return './algorithm/' + category + '/' + algorithm + '/';
};
var getFileDir = function (category, algorithm, file) {
if (isScratchPaper(category, algorithm)) return './algorithm/scratch_paper/';
return './algorithm/' + category + '/' + algorithm + '/' + file + '/';
}; };
var loadFile = function (category, algorithm, file, explanation) { (function () {
if (checkLoading()) return; $.ajaxSetup({cache: false, dataType: "text"});
$('#explanation').html(explanation);
var dir = lastFile = getFileDir(category, algorithm, file); $(document).on('click', 'a', function (e) {
e.preventDefault();
if (cachedFile[dir] && cachedFile[dir].data !== undefined && cachedFile[dir].code !== undefined) { if (!window.open($(this).attr('href'), '_blank')) {
dataEditor.setValue(cachedFile[dir].data, -1); alert('Please allow popups for this site');
codeEditor.setValue(cachedFile[dir].code, -1); }
} else { });
loading = true; $('.btn input').click(function (e) {
cachedFile[dir] = {}; e.stopPropagation();
dataEditor.setValue(''); });
codeEditor.setValue('');
var onFail = function (jqXHR, textStatus, errorThrown) {
loading = false;
alert("AJAX call failed: " + textStatus + ", " + errorThrown);
};
$.get(dir + 'data.js', function (data) {
cachedFile[dir].data = data;
dataEditor.setValue(data, -1);
$.get(dir + 'code.js', function (code) { var tm = new TracerManager();
cachedFile[dir].code = code; Tracer.prototype.tm = tm;
codeEditor.setValue(code, -1);
$('#interval').on('change', function () {
tm.interval = Number.parseFloat($(this).val() * 1000);
showInfoToast('Tracing interval has been set to ' + tm.interval / 1000 + ' second(s).');
});
var $module_container = $('.module_container');
ace.require("ace/ext/language_tools");
var initEditor = function (id) {
var editor = ace.edit(id);
editor.setOptions({
enableBasicAutocompletion: true,
enableSnippets: true,
enableLiveAutocompletion: true
});
editor.setTheme("ace/theme/tomorrow_night_eighties");
editor.session.setMode("ace/mode/javascript");
editor.$blockScrolling = Infinity;
return editor;
};
var dataEditor = initEditor('data');
var codeEditor = initEditor('code');
var lastFile = null;
dataEditor.on('change', function () {
var data = dataEditor.getValue();
if (lastFile) cachedFile[lastFile].data = data;
executeData(tm, data);
});
codeEditor.on('change', function () {
var code = codeEditor.getValue();
if (lastFile) cachedFile[lastFile].code = code;
});
var cachedFile = {};
var loading = false;
var isScratchPaper = function (category, algorithm) {
return category == null && algorithm == 'scratch_paper';
};
var getAlgorithmDir = function (category, algorithm) {
if (isScratchPaper(category, algorithm)) return './algorithm/scratch_paper/';
return './algorithm/' + category + '/' + algorithm + '/';
};
var getFileDir = function (category, algorithm, file) {
if (isScratchPaper(category, algorithm)) return './algorithm/scratch_paper/';
return './algorithm/' + category + '/' + algorithm + '/' + file + '/';
};
var loadFile = function (category, algorithm, file, explanation) {
if (checkLoading()) return;
$('#explanation').html(explanation);
var dir = lastFile = getFileDir(category, algorithm, file);
if (cachedFile[dir] && cachedFile[dir].data !== undefined && cachedFile[dir].code !== undefined) {
dataEditor.setValue(cachedFile[dir].data, -1);
codeEditor.setValue(cachedFile[dir].code, -1);
} else {
loading = true;
cachedFile[dir] = {};
dataEditor.setValue('');
codeEditor.setValue('');
var onFail = function (jqXHR, textStatus, errorThrown) {
loading = false; loading = false;
alert("AJAX call failed: " + textStatus + ", " + errorThrown);
};
$.get(dir + 'data.js', function (data) {
cachedFile[dir].data = data;
dataEditor.setValue(data, -1);
$.get(dir + 'code.js', function (code) {
cachedFile[dir].code = code;
codeEditor.setValue(code, -1);
loading = false;
}).fail(onFail);
}).fail(onFail); }).fail(onFail);
}).fail(onFail); }
} };
}; var checkLoading = function () {
var checkLoading = function () { if (loading) {
if (loading) { showErrorToast('Wait until it completes loading of previous file.');
showErrorToast('Wait until it completes loading of previous file.'); return true;
return true; }
} return false;
return false; };
}; var showDescription = function (data) {
var showDescription = function (data) { var $container = $('#tab_desc > .wrapper');
var $container = $('#tab_desc > .wrapper'); $container.empty();
$container.empty(); for (var key in data) {
for (var key in data) { if (key) $container.append($('<h3>').html(key));
if (key) $container.append($('<h3>').html(key)); var value = data[key];
var value = data[key]; if (typeof value === "string") {
if (typeof value === "string") { $container.append($('<p>').html(value));
$container.append($('<p>').html(value)); } else if (Array.isArray(value)) {
} else if (Array.isArray(value)) { var $ul = $('<ul>');
var $ul = $('<ul>'); $container.append($ul);
$container.append($ul); value.forEach(function (li) {
value.forEach(function (li) { $ul.append($('<li>').html(li));
$ul.append($('<li>').html(li)); });
}); } else if (typeof value === "object") {
} else if (typeof value === "object") { var $ul = $('<ul>');
var $ul = $('<ul>'); $container.append($ul);
$container.append($ul); for (var prop in value) {
for (var prop in value) { $ul.append($('<li>').append($('<strong>').html(prop)).append(' ' + value[prop]));
$ul.append($('<li>').append($('<strong>').html(prop)).append(' ' + value[prop])); }
} }
} }
} };
}; var showAlgorithm = function (category, algorithm) {
var showAlgorithm = function (category, algorithm) { var $menu;
var $menu; var category_name;
var category_name; var algorithm_name;
var algorithm_name; if (isScratchPaper(category, algorithm)) {
if (isScratchPaper(category, algorithm)) { $menu = $('#scratch-paper');
$menu = $('#scratch-paper'); category_name = '';
category_name = ''; algorithm_name = 'Scratch Paper';
algorithm_name = 'Scratch Paper'; } else {
} else { $menu = $('[data-category="' + category + '"][data-algorithm="' + algorithm + '"]');
$menu = $('[data-category="' + category + '"][data-algorithm="' + algorithm + '"]'); category_name = list[category].name;
category_name = list[category].name; algorithm_name = list[category].list[algorithm];
algorithm_name = list[category].list[algorithm]; }
} $('.sidemenu button').removeClass('active');
$('.sidemenu button').removeClass('active'); $menu.addClass('active');
$menu.addClass('active'); $('#btn_desc').click();
$('#btn_desc').click();
$('#category').html(category_name); $('#category').html(category_name);
$('#algorithm').html(algorithm_name); $('#algorithm').html(algorithm_name);
$('#tab_desc > .wrapper').empty(); $('#tab_desc > .wrapper').empty();
$('.files_bar > .wrapper').empty(); $('.files_bar > .wrapper').empty();
$('#explanation').html(''); $('#explanation').html('');
lastFile = null; lastFile = null;
dataEditor.setValue(''); dataEditor.setValue('');
codeEditor.setValue(''); codeEditor.setValue('');
}; };
var showFiles = function (category, algorithm, files) { var showFiles = function (category, algorithm, files) {
$('.files_bar > .wrapper').empty(); $('.files_bar > .wrapper').empty();
var init = false; var init = false;
for (var file in files) { for (var file in files) {
(function (file, explanation) { (function (file, explanation) {
var $file = $('<button>').append(file).click(function () { var $file = $('<button>').append(file).click(function () {
loadFile(category, algorithm, file, explanation); loadFile(category, algorithm, file, explanation);
$('.files_bar > .wrapper > button').removeClass('active'); $('.files_bar > .wrapper > button').removeClass('active');
$(this).addClass('active'); $(this).addClass('active');
}); });
$('.files_bar > .wrapper').append($file); $('.files_bar > .wrapper').append($file);
if (!init) { if (!init) {
init = true; init = true;
$file.click(); $file.click();
} }
})(file, files[file]); })(file, files[file]);
}
$('.files_bar > .wrapper').scroll();
};
$('.files_bar > .btn-left').click(function () {
var $wrapper = $('.files_bar > .wrapper');
var clipWidth = $wrapper.width();
var scrollLeft = $wrapper.scrollLeft();
$($wrapper.children('button').get().reverse()).each(function () {
var left = $(this).position().left;
var right = left + $(this).outerWidth();
if (0 > left) {
$wrapper.scrollLeft(scrollLeft + right - clipWidth);
return false;
} }
$('.files_bar > .wrapper').scroll();
};
$('.files_bar > .btn-left').click(function () {
var $wrapper = $('.files_bar > .wrapper');
var clipWidth = $wrapper.width();
var scrollLeft = $wrapper.scrollLeft();
$($wrapper.children('button').get().reverse()).each(function () {
var left = $(this).position().left;
var right = left + $(this).outerWidth();
if (0 > left) {
$wrapper.scrollLeft(scrollLeft + right - clipWidth);
return false;
}
});
});
$('.files_bar > .btn-right').click(function () {
var $wrapper = $('.files_bar > .wrapper');
var clipWidth = $wrapper.width();
var scrollLeft = $wrapper.scrollLeft();
$wrapper.children('button').each(function () {
var left = $(this).position().left;
var right = left + $(this).outerWidth();
if (clipWidth < right) {
$wrapper.scrollLeft(scrollLeft + left);
return false;
}
});
}); });
}); $('.files_bar > .wrapper').scroll(function () {
$('.files_bar > .btn-right').click(function () { var definitelyBigger = function (x, y) {
var $wrapper = $('.files_bar > .wrapper'); return x > y + 2;
var clipWidth = $wrapper.width(); };
var scrollLeft = $wrapper.scrollLeft(); var $wrapper = $('.files_bar > .wrapper');
$wrapper.children('button').each(function () { var clipWidth = $wrapper.width();
var left = $(this).position().left; var $left = $wrapper.children('button:first-child');
var right = left + $(this).outerWidth(); var $right = $wrapper.children('button:last-child');
if (clipWidth < right) { var left = $left.position().left;
$wrapper.scrollLeft(scrollLeft + left); var right = $right.position().left + $right.outerWidth();
return false; if (definitelyBigger(0, left) && definitelyBigger(clipWidth, right)) {
var scrollLeft = $wrapper.scrollLeft();
$wrapper.scrollLeft(scrollLeft + clipWidth - right);
return;
} }
var lefter = definitelyBigger(0, left);
var righter = definitelyBigger(right, clipWidth);
$wrapper.toggleClass('shadow-left', lefter);
$wrapper.toggleClass('shadow-right', righter);
$('.files_bar > .btn-left').attr('disabled', !lefter);
$('.files_bar > .btn-right').attr('disabled', !righter);
}); });
}); var loadAlgorithm = function (category, algorithm) {
$('.files_bar > .wrapper').scroll(function () { if (checkLoading()) return;
var definitelyBigger = function (x, y) { showAlgorithm(category, algorithm);
return x > y + 2;
};
var $wrapper = $('.files_bar > .wrapper');
var clipWidth = $wrapper.width();
var $left = $wrapper.children('button:first-child');
var $right = $wrapper.children('button:last-child');
var left = $left.position().left;
var right = $right.position().left + $right.outerWidth();
if (definitelyBigger(0, left) && definitelyBigger(clipWidth, right)) {
var scrollLeft = $wrapper.scrollLeft();
$wrapper.scrollLeft(scrollLeft + clipWidth - right);
return;
}
var lefter = definitelyBigger(0, left);
var righter = definitelyBigger(right, clipWidth);
$wrapper.toggleClass('shadow-left', lefter);
$wrapper.toggleClass('shadow-right', righter);
$('.files_bar > .btn-left').attr('disabled', !lefter);
$('.files_bar > .btn-right').attr('disabled', !righter);
});
var loadAlgorithm = function (category, algorithm) {
if (checkLoading()) return;
showAlgorithm(category, algorithm);
var dir = getAlgorithmDir(category, algorithm); var dir = getAlgorithmDir(category, algorithm);
$.getJSON(dir + 'desc.json', function (data) { $.getJSON(dir + 'desc.json', function (data) {
var files = data.files; var files = data.files;
delete data.files; delete data.files;
showDescription(data); showDescription(data);
showFiles(category, algorithm, files); showFiles(category, algorithm, files);
});
};
var list = {};
var anyOpened = false;
$.getJSON('./algorithm/category.json', function (data) {
list = data;
for (var category in list) {
(function (category) {
var $category = $('<button class="category">')
.append('<i class="fa fa-fw fa-caret-right">')
.append(list[category].name);
$category.click(function () {
$('[data-category="' + category + '"]').toggleClass('collapse');
$(this).find('i.fa').toggleClass('fa-caret-right fa-caret-down');
});
$('#list').append($category);
var subList = list[category].list;
for (var algorithm in subList) {
(function (category, subList, algorithm) {
var $algorithm = $('<button class="indent collapse">')
.append(subList[algorithm])
.attr('data-algorithm', algorithm)
.attr('data-category', category)
.click(function () {
loadAlgorithm(category, algorithm);
});
$('#list').append($algorithm);
if (!anyOpened) {
anyOpened = true;
$algorithm.click();
}
})(category, subList, algorithm);
}
})(category);
}
});
$('#powered-by').click(function () {
$('#powered-by-list button').toggleClass('collapse');
});
$('#scratch-paper').click(function () {
loadAlgorithm(null, 'scratch_paper');
}); });
};
var list = {};
var anyOpened = false;
$.getJSON('./algorithm/category.json', function (data) {
list = data;
for (var category in list) {
(function (category) {
var $category = $('<button class="category">')
.append('<i class="fa fa-fw fa-caret-right">')
.append(list[category].name);
$category.click(function () {
$('[data-category="' + category + '"]').toggleClass('collapse');
$(this).find('i.fa').toggleClass('fa-caret-right fa-caret-down');
});
$('#list').append($category);
var subList = list[category].list;
for (var algorithm in subList) {
(function (category, subList, algorithm) {
var $algorithm = $('<button class="indent collapse">')
.append(subList[algorithm])
.attr('data-algorithm', algorithm)
.attr('data-category', category)
.click(function () {
loadAlgorithm(category, algorithm);
});
$('#list').append($algorithm);
if (!anyOpened) {
anyOpened = true;
$algorithm.click();
}
})(category, subList, algorithm);
}
})(category);
}
});
$('#powered-by').click(function () {
$('#powered-by-list button').toggleClass('collapse');
});
$('#scratch-paper').click(function () {
loadAlgorithm(null, 'scratch_paper');
});
var sidemenu_percent; var sidemenu_percent;
$('#navigation').click(function () { $('#navigation').click(function () {
var $sidemenu = $('.sidemenu'); var $sidemenu = $('.sidemenu');
var $workspace = $('.workspace'); var $workspace = $('.workspace');
$sidemenu.toggleClass('active'); $sidemenu.toggleClass('active');
$('.nav-dropdown').toggleClass('fa-caret-down fa-caret-up'); $('.nav-dropdown').toggleClass('fa-caret-down fa-caret-up');
if ($sidemenu.hasClass('active')) { if ($sidemenu.hasClass('active')) {
$sidemenu.css('right', (100 - sidemenu_percent) + '%'); $sidemenu.css('right', (100 - sidemenu_percent) + '%');
$workspace.css('left', sidemenu_percent + '%'); $workspace.css('left', sidemenu_percent + '%');
} else { } else {
sidemenu_percent = $workspace.position().left / $('body').width() * 100; sidemenu_percent = $workspace.position().left / $('body').width() * 100;
$sidemenu.css('right', 0); $sidemenu.css('right', 0);
$workspace.css('left', 0); $workspace.css('left', 0);
} }
tm.resize(); tm.resize();
}); });
var showErrorToast = function (err) { var showErrorToast = function (err) {
var $toast = $('<div class="toast error">').append(err); var $toast = $('<div class="toast error">').append(err);
$('.toast_container').append($toast); $('.toast_container').append($toast);
setTimeout(function () { setTimeout(function () {
$toast.fadeOut(function () { $toast.fadeOut(function () {
$toast.remove(); $toast.remove();
}); });
}, 3000); }, 3000);
}; };
var showInfoToast = function (info) { var showInfoToast = function (info) {
var $toast = $('<div class="toast info">').append(info); var $toast = $('<div class="toast info">').append(info);
$('.toast_container').append($toast); $('.toast_container').append($toast);
setTimeout(function () { setTimeout(function () {
$toast.fadeOut(function () { $toast.fadeOut(function () {
$toast.remove(); $toast.remove();
}); });
}, 3000); }, 3000);
}; };
$('#shared').mouseup(function () { $('#shared').mouseup(function () {
$(this).select(); $(this).select();
});
$('#btn_share').click(function () {
var $icon = $(this).find('.fa-share');
$icon.addClass('fa-spin fa-spin-faster');
shareScratchPaper(function (url) {
$icon.removeClass('fa-spin fa-spin-faster');
$('#shared').removeClass('collapse');
$('#shared').val(url);
showInfoToast('Shareable link is created.');
}); });
}); $('#btn_share').click(function () {
$('#btn_run').click(function () { var $icon = $(this).find('.fa-share');
$('#btn_trace').click(); $icon.addClass('fa-spin fa-spin-faster');
try { shareScratchPaper(function (url) {
tm.deallocateAll(); $icon.removeClass('fa-spin fa-spin-faster');
eval(dataEditor.getValue()); $('#shared').removeClass('collapse');
eval(codeEditor.getValue()); $('#shared').val(url);
tm.visualize(); showInfoToast('Shareable link is created.');
} catch (err) { });
console.error(err); });
showErrorToast(err); $('#btn_run').click(function () {
} finally { $('#btn_trace').click();
tm.removeUnallocated(); var data = dataEditor.getValue();
} var code = codeEditor.getValue();
}); var err = executeDataAndCode(tm, data, code);
$('#btn_pause').click(function () { if (err) {
if (tm.isPause()) { console.error(err);
tm.resumeStep(); showErrorToast(err);
} else { }
});
$('#btn_pause').click(function () {
if (tm.isPause()) {
tm.resumeStep();
} else {
tm.pauseStep();
}
});
$('#btn_prev').click(function () {
tm.pauseStep(); tm.pauseStep();
} tm.prevStep();
}); });
$('#btn_prev').click(function () { $('#btn_next').click(function () {
tm.pauseStep(); tm.pauseStep();
tm.prevStep(); tm.nextStep();
}); });
$('#btn_next').click(function () {
tm.pauseStep();
tm.nextStep();
});
$('#btn_desc').click(function () { $('#btn_desc').click(function () {
$('.tab_container > .tab').removeClass('active'); $('.tab_container > .tab').removeClass('active');
$('#tab_desc').addClass('active'); $('#tab_desc').addClass('active');
$('.tab_bar > button').removeClass('active'); $('.tab_bar > button').removeClass('active');
$(this).addClass('active'); $(this).addClass('active');
}); });
$('#btn_trace').click(function () { $('#btn_trace').click(function () {
$('.tab_container > .tab').removeClass('active'); $('.tab_container > .tab').removeClass('active');
$('#tab_module').addClass('active'); $('#tab_module').addClass('active');
$('.tab_bar > button').removeClass('active'); $('.tab_bar > button').removeClass('active');
$(this).addClass('active'); $(this).addClass('active');
}); });
$(window).resize(function () { $(window).resize(function () {
tm.resize(); tm.resize();
}); });
var dividers = [ var dividers = [
['v', $('.sidemenu'), $('.workspace')], ['v', $('.sidemenu'), $('.workspace')],
['v', $('.viewer_container'), $('.editor_container')], ['v', $('.viewer_container'), $('.editor_container')],
['h', $('.data_container'), $('.code_container')] ['h', $('.data_container'), $('.code_container')]
]; ];
for (var i = 0; i < dividers.length; i++) { for (var i = 0; i < dividers.length; i++) {
var divider = dividers[i]; var divider = dividers[i];
(function (divider) { (function (divider) {
var vertical = divider[0] == 'v'; var vertical = divider[0] == 'v';
var $first = divider[1]; var $first = divider[1];
var $second = divider[2]; var $second = divider[2];
var $parent = $first.parent(); var $parent = $first.parent();
var thickness = 5; var thickness = 5;
var $divider = $('<div class="divider">'); var $divider = $('<div class="divider">');
var dragging = false; var dragging = false;
if (vertical) { if (vertical) {
$divider.addClass('vertical'); $divider.addClass('vertical');
var _left = -thickness / 2; var _left = -thickness / 2;
$divider.css({ $divider.css({
top: 0, top: 0,
bottom: 0, bottom: 0,
left: _left, left: _left,
width: thickness width: thickness
}); });
var x; var x;
$divider.mousedown(function (e) { $divider.mousedown(function (e) {
x = e.pageX;
dragging = true;
});
$(document).mousemove(function (e) {
if (dragging) {
var new_left = $second.position().left + e.pageX - x;
var percent = new_left / $parent.width() * 100;
percent = Math.min(90, Math.max(10, percent));
$first.css('right', (100 - percent) + '%');
$second.css('left', percent + '%');
x = e.pageX; x = e.pageX;
tm.resize(); dragging = true;
$('.files_bar > .wrapper').scroll(); });
} $(document).mousemove(function (e) {
}); if (dragging) {
$(document).mouseup(function (e) { var new_left = $second.position().left + e.pageX - x;
dragging = false; var percent = new_left / $parent.width() * 100;
}); percent = Math.min(90, Math.max(10, percent));
} else { $first.css('right', (100 - percent) + '%');
$divider.addClass('horizontal'); $second.css('left', percent + '%');
var _top = -thickness / 2; x = e.pageX;
$divider.css({ tm.resize();
top: _top, $('.files_bar > .wrapper').scroll();
height: thickness, }
left: 0, });
right: 0 $(document).mouseup(function (e) {
}); dragging = false;
var y; });
$divider.mousedown(function (e) { } else {
y = e.pageY; $divider.addClass('horizontal');
dragging = true; var _top = -thickness / 2;
}); $divider.css({
$(document).mousemove(function (e) { top: _top,
if (dragging) { height: thickness,
var new_top = $second.position().top + e.pageY - y; left: 0,
var percent = new_top / $parent.height() * 100; right: 0
percent = Math.min(90, Math.max(10, percent)); });
$first.css('bottom', (100 - percent) + '%'); var y;
$second.css('top', percent + '%'); $divider.mousedown(function (e) {
y = e.pageY; y = e.pageY;
tm.resize(); dragging = true;
} });
}); $(document).mousemove(function (e) {
$(document).mouseup(function (e) { if (dragging) {
dragging = false; var new_top = $second.position().top + e.pageY - y;
}); var percent = new_top / $parent.height() * 100;
} percent = Math.min(90, Math.max(10, percent));
$first.css('bottom', (100 - percent) + '%');
$second.css('top', percent + '%');
y = e.pageY;
tm.resize();
}
});
$(document).mouseup(function (e) {
dragging = false;
});
}
$second.append($divider); $second.append($divider);
})(divider); })(divider);
} }
$module_container.on('mousedown', '.module_wrapper', function (e) { $module_container.on('mousedown', '.module_wrapper', function (e) {
tm.findOwner(this).mousedown(e); tm.findOwner(this).mousedown(e);
}); });
$module_container.on('mousemove', '.module_wrapper', function (e) { $module_container.on('mousemove', '.module_wrapper', function (e) {
tm.findOwner(this).mousemove(e); tm.findOwner(this).mousemove(e);
}); });
$(document).mouseup(function (e) { $(document).mouseup(function (e) {
tm.command('mouseup', e); tm.command('mouseup', e);
}); });
$module_container.on('DOMMouseScroll mousewheel', '.module_wrapper', function (e) { $module_container.on('DOMMouseScroll mousewheel', '.module_wrapper', function (e) {
tm.findOwner(this).mousewheel(e); tm.findOwner(this).mousewheel(e);
}); });
// Share scratch paper // Share scratch paper
var getParameterByName = function (name) { var getParameterByName = function (name) {
var url = window.location.href; var url = window.location.href;
name = name.replace(/[\[\]]/g, "\\$&"); name = name.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"), var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
results = regex.exec(url); results = regex.exec(url);
if (!results) return null; if (!results) return null;
if (!results[2]) return ''; if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, " ")); return decodeURIComponent(results[2].replace(/\+/g, " "));
};
var shareScratchPaper = function (callback) {
var gist = {
'description': 'temp',
'public': true,
'files': {
'code.js': {'content': codeEditor.getValue()},
'data.js': {'content': dataEditor.getValue()}
}
}; };
$.post('https://api.github.com/gists', JSON.stringify(gist), function (res) {
var data = JSON.parse(res);
if (callback) callback(location.protocol + '//' + location.host + location.pathname + '?scratch-paper=' + data.id);
});
};
var loadScratchPaper = function (gistID) { var shareScratchPaper = function (callback) {
anyOpened = true; var gist = {
$.get('https://api.github.com/gists/' + gistID, function (res) { 'description': 'temp',
var data = JSON.parse(res); 'public': true,
var category = null; 'files': {
var algorithm = 'scratch_paper'; 'code.js': {'content': codeEditor.getValue()},
var dir = getFileDir(category, algorithm, 'scratch_paper'); 'data.js': {'content': dataEditor.getValue()}
cachedFile[dir] = { }
data: data.files['data.js'].content,
code: data.files['code.js'].content,
'CREDIT.md': 'Shared by an anonymous user from http://parkjs814.github.io/AlgorithmVisualizer'
}; };
loadAlgorithm(category, algorithm); $.post('https://api.github.com/gists', JSON.stringify(gist), function (res) {
}); var data = JSON.parse(res);
}; if (callback) callback(location.protocol + '//' + location.host + location.pathname + '?scratch-paper=' + data.id);
});
var gistID = getParameterByName('scratch-paper'); };
if (gistID) {
loadScratchPaper(gistID);
}
var toJSON = function (obj) {
return JSON.stringify(obj, function (key, value) {
return value === Infinity ? "Infinity" : value;
});
};
var fromJSON = function (obj) { var loadScratchPaper = function (gistID) {
return JSON.parse(obj, function (key, value) { anyOpened = true;
return value === "Infinity" ? Infinity : value; $.get('https://api.github.com/gists/' + gistID, function (res) {
}); var data = JSON.parse(res);
}; var category = null;
var algorithm = 'scratch_paper';
var dir = getFileDir(category, algorithm, 'scratch_paper');
cachedFile[dir] = {
data: data.files['data.js'].content,
code: data.files['code.js'].content,
'CREDIT.md': 'Shared by an anonymous user from http://parkjs814.github.io/AlgorithmVisualizer'
};
loadAlgorithm(category, algorithm);
});
};
var refineNumber = function (number) { var gistID = getParameterByName('scratch-paper');
return number === Infinity ? '' : number; if (gistID) {
}; loadScratchPaper(gistID);
\ No newline at end of file }
})();
\ No newline at end of file
...@@ -10,7 +10,7 @@ var TracerManager = function () { ...@@ -10,7 +10,7 @@ var TracerManager = function () {
TracerManager.prototype = { TracerManager.prototype = {
add: function (tracer) { add: function (tracer) {
var $container = $('<section class="module_wrapper">'); var $container = $('<section class="module_wrapper">');
$module_container.append($container); $('.module_container').append($container);
var capsule = { var capsule = {
module: tracer.module, module: tracer.module,
tracer: tracer, tracer: tracer,
...@@ -176,4 +176,20 @@ TracerManager.prototype = { ...@@ -176,4 +176,20 @@ TracerManager.prototype = {
}); });
return selectedCapsule.tracer; return selectedCapsule.tracer;
} }
};
var TracerUtil = {
toJSON: function (obj) {
return JSON.stringify(obj, function (key, value) {
return value === Infinity ? "Infinity" : value;
});
},
fromJSON: function (obj) {
return JSON.parse(obj, function (key, value) {
return value === "Infinity" ? Infinity : value;
});
},
refineNumber: function (number) {
return number === Infinity ? '' : number;
}
}; };
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册