<commit_before>var ivids = {};

(function(ivids) {
    var player = null;
    var timeline;
    var videoId;
    var isYouTube;
    var questions = [];

    var selector;

    var BASELINE_WIDTH = 800;
    var BASELINE_HEIGHT = 600;
    var scaleWidth = 1;
    var scaleHeight = 1;

    function bootstrap(playerSelector, vidId, videoType, tline) {
        selector = playerSelector;
        timeline = tline;
        isYouTube = videoType;
        videoId = vidId;

        if (player !== null) {
            Popcorn.destroy(player);
            $(playerSelector).html("");
            removeAllQuestions();
        }

        if (tline !== undefined) {
            // The time line may be undefined, in this case the video should simply be displayed
            initQuestions();
            buildNavigation();
        }

        var constructor = (isYouTube) ? Popcorn.HTMLYouTubeVideoElement : Popcorn.HTMLVimeoVideoElement;
        var wrapper = constructor(playerSelector);
        wrapper.src = (isYouTube) ?
        "http://www.youtube.com/watch?v=" + videoId :
        "http://player.vimeo.com/video/" + videoId;
        player = Popcorn(wrapper);

        player.on("timeupdate", handleTimeUpdate);
        player.on("seeked", handleSeeked);
        player.on("play", function() {
            removeAllQuestions(); // Remove all questions when we continue playing
        });
        player.on("pause", function() {
            events.emit({
                kind: "PAUSE_VIDEO",
                video: document.location.href,
                timecode: player.currentTime()
            }, true);
        });
        player.on("loadstart", function() {
            initializeSize();
            console.log("loadstart?");
        });
        $(window).resize(function () { initializeSize() });
        setTimeout(function() { initializeSize(); }, 2000);
        initEventHandlers();
    }

    function initializeSize() {
        var maxWidth = -1;
        var maxHeight = -1;
        $(selector).children().each(function (index, element) {
            var $element = $(element);
            var height = $element.height();
            var width = $element.width();
            if (width > maxWidth) maxWidth = width;
            if (height > maxHeight) maxHeight = height;
        });
        console.log(maxWidth);
        console.log(maxHeight);
        $("#wrapper").width(maxWidth).height(maxHeight);
        scaleHeight = maxHeight / BASELINE_HEIGHT;
        scaleWidth = maxWidth / BASELINE_WIDTH;
        console.log(scaleHeight);
        console.log(scaleWidth);
    }

    ivids.initializeSize = initializeSize;

    function handleSeeked() {
        for (var i = questions.length - 1; i >= 0; i--) {
            questions[i].visible = false;
            questions[i].shown = false;
        }
        hideAllFields();
        removeAllQuestions();
        handleTimeUpdate();
    }

    function handleTimeUpdate() {
        var timestamp = player.currentTime();
        for (var i = questions.length - 1; i >= 0; i--) {
            var q = questions[i];
            if (q.timecode !== Math.round(timestamp) && q.visible) {
                removeAllQuestions();
                q.visible = false;
            } else if (q.timecode === Math.round(timestamp) && !q.visible && !q.shown) {
                // Will cause a seek event, which in turn will reset everything
                player.pause();
                q.visible = true;
                q.shown = true;
                for(var k = 0; k < q.fields.length; k++) {
                    var field = q.fields[k];
                    placeInputField(
                        field.name,
                        field.answer,
                        field.topoffset,
                        field.leftoffset);
                }
            }
        }
    }

    function initEventHandlers() {
        $("#checkAnswers").click(function (e) {
            e.preventDefault();
            var question = getVisibleQuestion();
            for (var i = 0; i < question.fields.length; i++) {
                var field = question.fields[i];
                var input = $("#" + field.name);
                var val = parseTex(input.mathquill("latex"));
                input.removeClass("correct error");
                var correct = validateAnswer(field, val);
                if (correct) {
                    input.addClass("correct");
                } else {
                    input.addClass("error");
                }
                if (val.length > 0) {
                    events.emit({
                        kind: "ANSWER_QUESTION",
                        answer: val,
                        correct: correct
                    });
                }
            }
            events.flush();
        });
        $("#frameOverlay").mousemove(function (event) {
            var parentOffset = $(this).parent().offset();
            var x = parseInt(event.pageX - parentOffset.left);
            var y = parseInt(event.pageY - parentOffset.top);
            var msg = x + ", " + y;
            $("#cursorPosition").text(msg);
        });
    }

    function initQuestions() {
        for (var i = timeline.length - 1; i >= 0; i--) {
            var item = timeline[i];
            questions = questions.concat(item.questions);
        }
    }

    function buildNavigation() {
        var nav = $("#videoNavigation");
        nav.html("

");
        for (var i = 0; i < timeline.length; i++) {
            var item = timeline[i];
            var nodeId = "navitem" + String(i);
            var node = $(createNavItem(item, nodeId));

            nav.append(node);
            $("#" + nodeId).click(handleNavigationClick(item));

            if (item.questions.length > 0) {
                var list = $("

");
                nav.append(list);
                for (var j = 0; j < item.questions.length; j++) {
                    var question = item.questions[j];
                    var questionId = "navitem" + String(i) + String(j);
                    var questionNode = $(createNavItem(question, questionId));

                    list.append(questionNode);
                    $("#" + questionId).click(handleNavigationClick(question));
                }
            }
        }
    }

    function handleNavigationClick(item) {
        return function(e) {
            var skippedAt = player.currentTime();
            e.preventDefault();
            player.currentTime(item.timecode);
            events.emit({
                kind: "SKIP_TO_CONTENT",
                video: document.location.href,
                label: item.title,
                videoTimeCode: player.currentTime(),
                skippedAt: skippedAt
            }, true);
        };
    }

    /**
     * @brief               Places a single input field used in questions.
     * @details
     *
     * @param fieldId       Type: String. The ID of the field.
     * @param evalFunction  Type: (string) => boolean. The function used to evaluate answers.
     * @param offsetTop     Type: Integer. Y offset relative to top-left corner of player.
     * @param offsetLeft    Type: Integer. X offset relative to top-left corner of player.
     */
    function placeInputField(fieldId, evalFunction, offsetTop, offsetLeft) {
        $("#wrapper").append(createInputField(fieldId));
        var field = $("#" + fieldId);
        field.css({
            position: "absolute",
            top: (offsetTop * scaleHeight) + "px",
            left: (offsetLeft * scaleWidth + 15) + "px",
            minWidth: 90 * scaleWidth,
            minHeight: 20 * scaleHeight
        });
        field.mathquill("editable");
    }

    function validateAnswer(field, value) {
        var answer = field.answer;
        switch (answer.type) {
            case "expression":
                var expectedValue = KAS.parse(answer.value);
                var givenAnswer = KAS.parse(value);
                var result = KAS.compare(expectedValue.expr, givenAnswer.expr, answer.options);
                return result.equal;
            case "between":
                var floatVal = parseFloat(value);
                return floatVal >= answer.min && floatVal <= answer.max;
            case "equal":
                if (answer.ignoreCase) {
                    value = value.toLowerCase();
                    answer.value = answer.value.toLowerCase();
                }
                console.log(answer);
                console.log(value);
                console.log(answer.value);
                console.log(answer.ignoreCase);
                return value === answer.value;
            case "in-list":
                return answer.value.indexOf(value) >= 0;
            case "in-expression-list":
                var givenAnswer = KAS.parse(value);
                for (var i = 0; i < answer.value.length; i++) {
                    var expr = KAS.parse(answer.value[i]); // TODO Answer should be cached
                    var result = KAS.compare(expr.expr, givenAnswer.expr, answer.options);
                    if (result.equal) return true;
                }
                return false;
            case "custom":
                // Custom validators are hopefully just a temporary feature, that is never going to be needed.
                // So much wrong with the following code snippet.
                if (answer.validator === undefined) {
                    var id = "temp_eval_func";
                    answer.validator = eval("function " + id + "() {" + answer.jsValidator + "\n}" + id + "();");
                }
                return answer.validator(value);
        }
    }

    function getVisibleQuestion() {
        for (var i = 0; i < timeline.length; i++) {
            var item = timeline[i];
            for (var j = 0; j < item.questions.length; j++) {
                var question = item.questions[j];
                if (question.visible) {
                    return question;
                }
            }
        }
        return null;
    }

    function removeAllQuestions() {
        $("#wrapper").find(".question").remove();
        hideAllFields();
    }

    function hideAllFields() {
        for (var i = questions.length - 1; i >= 0; i--) {
            questions[i].visible = false;
        }
    }

    function createInputField(id) {
        return '';
    }

    function createNavItem(item, id) {
        return '
' + formatTime(item.timecode) +  ' - ' +  item.title + '
';
    }

    function formatTimeUnit(unit) {
        if (unit < 10) return "0" + Math.floor(unit);
        return Math.floor(unit);
    }

    /**
     * @brief       Formats time into a human readable string.
     * @details     The returned string will be in the format [DD:][HH:]MM:SS
     *
     * @param time  number Time in seconds.
     * @return      string Time as a string
     */
    function formatTime(time) {
        var totalSecs = time;
        var totalMins = totalSecs / 60;
        var totalHours = totalMins / 60;
        var totalDays = totalHours / 24;

        var secs = totalSecs % 60;
        var mins = totalMins % 60;
        var hours = totalHours % 24;
        var result = "";

        if (totalDays >= 1) result += formatTimeUnit(totalDays) + ":";
        if (hours >= 1) result += formatTimeUnit(hours) + ":";
        result += formatTimeUnit(mins) + ":";
        result += formatTimeUnit(secs);
        return result;
    }

    ivids.bootstrap = bootstrap;
    ivids.player = function() { return player; };
    return ivids;
})(ivids);<commit_msg>The controls are back (Fixes issue #29)<commit_after>var ivids = {};

(function(ivids) {
    var player = null;
    var timeline;
    var videoId;
    var isYouTube;
    var questions = [];

    var selector;

    var BASELINE_WIDTH = 800;
    var BASELINE_HEIGHT = 600;
    var scaleWidth = 1;
    var scaleHeight = 1;

    function bootstrap(playerSelector, vidId, videoType, tline) {
        selector = playerSelector;
        timeline = tline;
        isYouTube = videoType;
        videoId = vidId;

        if (player !== null) {
            Popcorn.destroy(player);
            $(playerSelector).html("");
            removeAllQuestions();
        }

        if (tline !== undefined) {
            // The time line may be undefined, in this case the video should simply be displayed
            initQuestions();
            buildNavigation();
        }

        var constructor = (isYouTube) ? Popcorn.HTMLYouTubeVideoElement : Popcorn.HTMLVimeoVideoElement;
        var wrapper = constructor(playerSelector);
        wrapper.src = (isYouTube) ?
        "http://www.youtube.com/watch?v=" + videoId + "&controls=0" :
        "http://player.vimeo.com/video/" + videoId;
        player = Popcorn(wrapper);

        player.on("timeupdate", handleTimeUpdate);
        player.on("seeked", handleSeeked);
        player.on("play", function() {
            removeAllQuestions(); // Remove all questions when we continue playing
        });
        player.on("pause", function() {
            events.emit({
                kind: "PAUSE_VIDEO",
                video: document.location.href,
                timecode: player.currentTime()
            }, true);
        });
        player.on("loadstart", function() {
            initializeSize();
            console.log("loadstart?");
        });
        $(window).resize(function () { initializeSize() });
        setTimeout(function() { initializeSize(); }, 2000);
        initEventHandlers();
    }

    function initializeSize() {
        var maxWidth = -1;
        var maxHeight = -1;
        $(selector).children().each(function (index, element) {
            var $element = $(element);
            var height = $element.height();
            var width = $element.width();
            if (width > maxWidth) maxWidth = width;
            if (height > maxHeight) maxHeight = height;
        });
        console.log(maxWidth);
        console.log(maxHeight);
        $("#wrapper").width(maxWidth).height(maxHeight);
        scaleHeight = maxHeight / BASELINE_HEIGHT;
        scaleWidth = maxWidth / BASELINE_WIDTH;
        console.log(scaleHeight);
        console.log(scaleWidth);
    }

    ivids.initializeSize = initializeSize;

    function handleSeeked() {
        for (var i = questions.length - 1; i >= 0; i--) {
            questions[i].visible = false;
            questions[i].shown = false;
        }
        hideAllFields();
        removeAllQuestions();
        handleTimeUpdate();
    }

    function handleTimeUpdate() {
        var timestamp = player.currentTime();
        for (var i = questions.length - 1; i >= 0; i--) {
            var q = questions[i];
            if (q.timecode !== Math.round(timestamp) && q.visible) {
                removeAllQuestions();
                q.visible = false;
            } else if (q.timecode === Math.round(timestamp) && !q.visible && !q.shown) {
                // Will cause a seek event, which in turn will reset everything
                player.pause();
                q.visible = true;
                q.shown = true;
                for(var k = 0; k < q.fields.length; k++) {
                    var field = q.fields[k];
                    placeInputField(
                        field.name,
                        field.answer,
                        field.topoffset,
                        field.leftoffset);
                }
            }
        }
    }

    function initEventHandlers() {
        $("#checkAnswers").click(function (e) {
            e.preventDefault();
            var question = getVisibleQuestion();
            for (var i = 0; i < question.fields.length; i++) {
                var field = question.fields[i];
                var input = $("#" + field.name);
                var val = parseTex(input.mathquill("latex"));
                input.removeClass("correct error");
                var correct = validateAnswer(field, val);
                if (correct) {
                    input.addClass("correct");
                } else {
                    input.addClass("error");
                }
                if (val.length > 0) {
                    events.emit({
                        kind: "ANSWER_QUESTION",
                        answer: val,
                        correct: correct
                    });
                }
            }
            events.flush();
        });
        $("#frameOverlay").mousemove(function (event) {
            var parentOffset = $(this).parent().offset();
            var x = parseInt(event.pageX - parentOffset.left);
            var y = parseInt(event.pageY - parentOffset.top);
            var msg = x + ", " + y;
            $("#cursorPosition").text(msg);
        });
    }

    function initQuestions() {
        for (var i = timeline.length - 1; i >= 0; i--) {
            var item = timeline[i];
            questions = questions.concat(item.questions);
        }
    }

    function buildNavigation() {
        var nav = $("#videoNavigation");
        nav.html("

");
        for (var i = 0; i < timeline.length; i++) {
            var item = timeline[i];
            var nodeId = "navitem" + String(i);
            var node = $(createNavItem(item, nodeId));

            nav.append(node);
            $("#" + nodeId).click(handleNavigationClick(item));

            if (item.questions.length > 0) {
                var list = $("

");
                nav.append(list);
                for (var j = 0; j < item.questions.length; j++) {
                    var question = item.questions[j];
                    var questionId = "navitem" + String(i) + String(j);
                    var questionNode = $(createNavItem(question, questionId));

                    list.append(questionNode);
                    $("#" + questionId).click(handleNavigationClick(question));
                }
            }
        }
    }

    function handleNavigationClick(item) {
        return function(e) {
            var skippedAt = player.currentTime();
            e.preventDefault();
            player.currentTime(item.timecode);
            events.emit({
                kind: "SKIP_TO_CONTENT",
                video: document.location.href,
                label: item.title,
                videoTimeCode: player.currentTime(),
                skippedAt: skippedAt
            }, true);
        };
    }

    /**
     * @brief               Places a single input field used in questions.
     * @details
     *
     * @param fieldId       Type: String. The ID of the field.
     * @param evalFunction  Type: (string) => boolean. The function used to evaluate answers.
     * @param offsetTop     Type: Integer. Y offset relative to top-left corner of player.
     * @param offsetLeft    Type: Integer. X offset relative to top-left corner of player.
     */
    function placeInputField(fieldId, evalFunction, offsetTop, offsetLeft) {
        $("#wrapper").append(createInputField(fieldId));
        var field = $("#" + fieldId);
        field.css({
            position: "absolute",
            top: (offsetTop * scaleHeight) + "px",
            left: (offsetLeft * scaleWidth + 15) + "px",
            minWidth: 90 * scaleWidth,
            minHeight: 20 * scaleHeight
        });
        field.mathquill("editable");
    }

    function validateAnswer(field, value) {
        var answer = field.answer;
        switch (answer.type) {
            case "expression":
                var expectedValue = KAS.parse(answer.value);
                var givenAnswer = KAS.parse(value);
                var result = KAS.compare(expectedValue.expr, givenAnswer.expr, answer.options);
                return result.equal;
            case "between":
                var floatVal = parseFloat(value);
                return floatVal >= answer.min && floatVal <= answer.max;
            case "equal":
                if (answer.ignoreCase) {
                    value = value.toLowerCase();
                    answer.value = answer.value.toLowerCase();
                }
                console.log(answer);
                console.log(value);
                console.log(answer.value);
                console.log(answer.ignoreCase);
                return value === answer.value;
            case "in-list":
                return answer.value.indexOf(value) >= 0;
            case "in-expression-list":
                var givenAnswer = KAS.parse(value);
                for (var i = 0; i < answer.value.length; i++) {
                    var expr = KAS.parse(answer.value[i]); // TODO Answer should be cached
                    var result = KAS.compare(expr.expr, givenAnswer.expr, answer.options);
                    if (result.equal) return true;
                }
                return false;
            case "custom":
                // Custom validators are hopefully just a temporary feature, that is never going to be needed.
                // So much wrong with the following code snippet.
                if (answer.validator === undefined) {
                    var id = "temp_eval_func";
                    answer.validator = eval("function " + id + "() {" + answer.jsValidator + "\n}" + id + "();");
                }
                return answer.validator(value);
        }
    }

    function getVisibleQuestion() {
        for (var i = 0; i < timeline.length; i++) {
            var item = timeline[i];
            for (var j = 0; j < item.questions.length; j++) {
                var question = item.questions[j];
                if (question.visible) {
                    return question;
                }
            }
        }
        return null;
    }

    function removeAllQuestions() {
        $("#wrapper").find(".question").remove();
        hideAllFields();
    }

    function hideAllFields() {
        for (var i = questions.length - 1; i >= 0; i--) {
            questions[i].visible = false;
        }
    }

    function createInputField(id) {
        return '';
    }

    function createNavItem(item, id) {
        return '
' + formatTime(item.timecode) +  ' - ' +  item.title + '
';
    }

    function formatTimeUnit(unit) {
        if (unit < 10) return "0" + Math.floor(unit);
        return Math.floor(unit);
    }

    /**
     * @brief       Formats time into a human readable string.
     * @details     The returned string will be in the format [DD:][HH:]MM:SS
     *
     * @param time  number Time in seconds.
     * @return      string Time as a string
     */
    function formatTime(time) {
        var totalSecs = time;
        var totalMins = totalSecs / 60;
        var totalHours = totalMins / 60;
        var totalDays = totalHours / 24;

        var secs = totalSecs % 60;
        var mins = totalMins % 60;
        var hours = totalHours % 24;
        var result = "";

        if (totalDays >= 1) result += formatTimeUnit(totalDays) + ":";
        if (hours >= 1) result += formatTimeUnit(hours) + ":";
        result += formatTimeUnit(mins) + ":";
        result += formatTimeUnit(secs);
        return result;
    }

    ivids.bootstrap = bootstrap;
    ivids.player = function() { return player; };
    return ivids;
})(ivids);<|endoftext|>


<commit_before>(function($) {
$(function() {
	// This view type corresponds with the Drupal module setting
	var view_type = Drupal.settings.islandora_mirador_bookreader.view_type;
	switch(parseInt(view_type)) {
		case 1:
			view_type = "ImageView";
			break;
		case 2:
			view_type = "BookView";
			break;
		case 3:
			view_type = "ThumbnailsView";
			break;
		default:
			view_type = "ImageView";
	}
	//console.log("The view type from config is " + view_type + " <<<<");

	var json_path = Drupal.settings.islandora_mirador_bookreader.json_file_directory+'sc_manifest_list.json';

	$.getJSON(json_path, function(data) {

	// The manifest_url is dynamically generated based on the pid
	var pid = Drupal.settings.islandora_mirador_bookreader.pid;

	var base_url = Drupal.settings.islandora_mirador_bookreader.base_url;

	//put a base url
	var manifest_url = base_url + "/islandora/object/" + pid + "/datastream/SC/view";

	var current_manifest_url = base_url + "/islandora/object/" + current_pid + "/datastream/SC/view";

	// Get the current pid from the url
	var pathname = window.location.pathname;
		pathname = pathname.split("/");
	var current_pid = pathname[3];
		current_pid = current_pid.replace('paleography%3A', 'paleography:');

	// Create a new data array
	var new_data = [];

	// Grab the current object and put it into the beginning of the array
	// This is to make the Mirador viewer load faster

	$.each(data, function(idx, obj) {
		if(obj.manifestUri == current_manifest_url) {
			new_data.unshift(obj);
		} else { new_data.push(obj); }
	});

	// This is the main Mirador constructor. The settings corresponds to settings.js in the source code, see there for more help

		Mirador({
			"id": "mirador-bookreader",
			"data": new_data,
			//"data":[{ "manifestUri": manifest_url, "location": "University of Toronto"}],
			'mainMenuSettings': {
				'show':false,
				'buttons': { 'bookmark' : false }
			},
			"showAddFromURLBox":false,

			'buildPath' : '/sites/all/libraries/mirador/',

			'i18nPath' : '/sites/all/libraries/mirador/locales/',

			'imagesPath' : '/sites/all/libraries/mirador/images/',

			'logosPath' : '/sites/all/libraries/mirador/images/logos/',

			'logosLocation' : '/sites/all/libraries/mirador/images/logos/',

			'repoImages' : {
				'other': 'iiif_logo.png'
			},

			"windowObjects": [
				{
					"loadedManifest":manifest_url,
					"viewType":view_type,
					"annotationLayer":false,
					"displayLayout": true,
					"bottomPanel" : true,
					"sidePanel" : false,
					"overlayMetadata": false
				}
			]
		});
	}); //getJSON

});

})(jQuery);

function scrollToMetadata() {
        jQuery('html, body').animate({
                scrollTop: jQuery('.islandora-metadata').offset().top
        }, 1000);
}
<commit_msg>COL-737 fix<commit_after>(function($) {
$(function() {
	// This view type corresponds with the Drupal module setting
	var view_type = Drupal.settings.islandora_mirador_bookreader.view_type;
	switch(parseInt(view_type)) {
		case 1:
			view_type = "ImageView";
			break;
		case 2:
			view_type = "BookView";
			break;
		case 3:
			view_type = "ThumbnailsView";
			break;
		default:
			view_type = "ImageView";
	}
	//console.log("The view type from config is " + view_type + " <<<<");

	var json_path = Drupal.settings.islandora_mirador_bookreader.json_file_directory+'sc_manifest_list.json';

	$.getJSON(json_path, function(data) {

	// The manifest_url is dynamically generated based on the pid
	var pid = Drupal.settings.islandora_mirador_bookreader.pid;

	var base_url = Drupal.settings.islandora_mirador_bookreader.base_url;

	//put a base url
	var manifest_url = base_url + "/islandora/object/" + pid + "/datastream/SC/view";

	// Get the current pid from the url
	var pathname = window.location.pathname;
		pathname = pathname.split("/");
	var current_pid = pathname[3];
		current_pid = current_pid.replace('paleography%3A', 'paleography:');
	var current_manifest_url = base_url + "/islandora/object/" + current_pid + "/datastream/SC/view";

	// Create a new data array
	var new_data = [];

	// Grab the current object and put it into the beginning of the array
	// This is to make the Mirador viewer load faster

	$.each(data, function(idx, obj) {
		if(obj.manifestUri == current_manifest_url) {
		console.log(current_pid);
			new_data.unshift(obj);
		} else { new_data.push(obj); }
	});

	// This is the main Mirador constructor. The settings corresponds to settings.js in the source code, see there for more help

		Mirador({
			"id": "mirador-bookreader",
			"data": new_data,
			//"data":[{ "manifestUri": manifest_url, "location": "University of Toronto"}],
			'mainMenuSettings': {
				'show':false,
				'buttons': { 'bookmark' : false }
			},
			"showAddFromURLBox":false,

			'buildPath' : '/sites/all/libraries/mirador/',

			'i18nPath' : '/sites/all/libraries/mirador/locales/',

			'imagesPath' : '/sites/all/libraries/mirador/images/',

			'logosPath' : '/sites/all/libraries/mirador/images/logos/',

			'logosLocation' : '/sites/all/libraries/mirador/images/logos/',

			'repoImages' : {
				'other': 'iiif_logo.png'
			},

			"windowObjects": [
				{
					"loadedManifest":manifest_url,
					"viewType":view_type,
					"annotationLayer":false,
					"displayLayout": true,
					"bottomPanel" : true,
					"sidePanel" : false,
					"overlayMetadata": false
				}
			]
		});
	}); //getJSON

});

})(jQuery);

function scrollToMetadata() {
        jQuery('html, body').animate({
                scrollTop: jQuery('.islandora-metadata').offset().top
        }, 1000);
}
<|endoftext|>


<commit_before>$(function() {
	// This view type corresponds with the Drupal module setting
	var view_type = Drupal.settings.islandora_mirador_bookreader.view_type;
	switch(parseInt(view_type)) {
		case 1:
			view_type = "ImageView";
			break;
		case 2:
			view_type = "BookView";
			break;
		case 3:
			view_type = "ThumbnailsView";
			break;
		default:
			view_type = "ImageView";
	}
	//console.log("The view type from config is " + view_type + " <<<<");

	// The manifest_url is dynamically generated based on the pid
	var pid = Drupal.settings.islandora_mirador_bookreader.pid;
	var manifest_url = "https://paleographydev.library.utoronto.ca/islandora/object/" + pid + "/datastream/SC/";

	// This is the main Mirador constructor. The settings corresponds to settings.js in the source code, see there for more help
      Mirador({
        "id": "mirador-bookreader",
        "data": [
        { "manifestUri": manifest_url, "location": "University of Toronto"}
        //{ "manifestUri": "https://sz-paleographydev.library.utoronto.ca/sites/sz-paleographydev.library.utoronto.ca/files/json/toronto.json", "location": "University of Toronto"}
        ],
	'mainMenuSettings': {
		'show':false,
		'buttons':{
			'bookmark' : false
		}
	},
	"showAddFromURLBox":false,

	'buildPath' : '/sites/all/libraries/mirador/',

	'i18nPath' : '/sites/all/libraries/mirador/locales/',

	'imagesPath' : '/sites/all/libraries/mirador/images/',

	'logosPath' : '/sites/all/libraries/mirador/logos/',

	'logosLocation' : '/sites/all/libraries/mirador/images/logos/',

	'repoImages' : {
		'other': 'iiif_logo.png'
	},

        "windowObjects": [
		{
			"loadedManifest":manifest_url,
			"viewType":view_type,
			"annotationLayer":false,
			"displayLayout": false,
			"bottomPanel" : true,
			"sidePanel" : false
		}
	]
      });

	// Mirador loads its own jQuery version (1.9.1). We need to raise Drupal's jQuery version using the migrate library, if Drupal's behind
	$.getScript("https://code.jquery.com/jquery-migrate-1.2.1.js");
});
<commit_msg>Restored add object link<commit_after>$(function() {
	// This view type corresponds with the Drupal module setting
	var view_type = Drupal.settings.islandora_mirador_bookreader.view_type;
	switch(parseInt(view_type)) {
		case 1:
			view_type = "ImageView";
			break;
		case 2:
			view_type = "BookView";
			break;
		case 3:
			view_type = "ThumbnailsView";
			break;
		default:
			view_type = "ImageView";
	}
	//console.log("The view type from config is " + view_type + " <<<<");

	// The manifest_url is dynamically generated based on the pid
	var pid = Drupal.settings.islandora_mirador_bookreader.pid;
	var manifest_url = "https://paleographydev.library.utoronto.ca/islandora/object/" + pid + "/datastream/SC/";

	// This is the main Mirador constructor. The settings corresponds to settings.js in the source code, see there for more help
      Mirador({
        "id": "mirador-bookreader",
        "data": [
        { "manifestUri": manifest_url, "location": "University of Toronto"}
        //{ "manifestUri": "https://sz-paleographydev.library.utoronto.ca/sites/sz-paleographydev.library.utoronto.ca/files/json/toronto.json", "location": "University of Toronto"}
        ],
	'mainMenuSettings': {
		'show':false,
		'buttons':{
			'bookmark' : false
		}
	},
	"showAddFromURLBox":false,

	'buildPath' : '/sites/all/libraries/mirador/',

	'i18nPath' : '/sites/all/libraries/mirador/locales/',

	'imagesPath' : '/sites/all/libraries/mirador/images/',

	'logosPath' : '/sites/all/libraries/mirador/logos/',

	'logosLocation' : '/sites/all/libraries/mirador/images/logos/',

	'repoImages' : {
		'other': 'iiif_logo.png'
	},

        "windowObjects": [
		{
			"loadedManifest":manifest_url,
			"viewType":view_type,
			"annotationLayer":false,
			"displayLayout": true,
			"bottomPanel" : true,
			"sidePanel" : false
		}
	]
      });

	// Mirador loads its own jQuery version (1.9.1). We need to raise Drupal's jQuery version using the migrate library, if Drupal's behind
	$.getScript("https://code.jquery.com/jquery-migrate-1.2.1.js");
});
<|endoftext|>


<commit_before>/*!
 * jQuery FocusPoint; version: 1.0.0
 * Author: http://jonathonmenz.com
 * Source: https://github.com/jonom/jquery-focuspoint
 * Copyright (c) 2014 J. Menz; MIT License
 */
;
(function($) {
	$.fn.focusPoint = function(options) {
		var settings = $.extend({
			// These are the defaults.
			reCalcOnWindowResize: true
		}, options);
		return this.each(function() {
			//Initial adjustments
			var container = $(this);
			//Replace basic css positioning with more accurate version
			container.removeClass('focus-left-top focus-left-center focus-left-bottom focus-center-top focus-center-center focus-center-bottom focus-right-top focus-right-center focus-right-bottom');
			//Focus image in container
			container.adjustFocus();
			if (settings.reCalcOnWindowResize) {
				//Recalculate each time the window is resized
				$(window).resize(function() {
					container.adjustFocus();
				});
			}
		});
	};
	$.fn.adjustFocus = function() {
		return this.each(function() {
			//Adjust the focus of frame
			var containerW = $(this).width();
			var containerH = $(this).height();
			var image = $(this).find('img').first();
			var imageW = $(this).data('imageW');
			var imageH = $(this).data('imageH');
			if (!(containerW > 0 && containerH > 0 && imageW > 0 && imageH > 0)) {
				//Need dimensions to proceed
				return false;
			}
			//Which is over by more?
			wR = imageW / containerW;
			hR = imageH / containerH;
			//Minimise image while still filling space
			if (imageW > containerW && imageH > containerH) {
				if (wR > hR) {
					image.css('max-width', '');
					image.css('max-height', '100%');
				} else {
					image.css('max-width', '100%');
					image.css('max-height', '');
				}
			} else {
				image.css('max-width', '');
				image.css('max-height', '');
			}
			//Amount position will be shifted
			var hShift = 0;
			var vShift = 0;
			if (wR > hR) {
				//Container center in px
				var containerCenterX = Math.floor(containerW / 2);
				//Focus point of resize image in px
				var focusFactorX = (Number($(this).data('focus-x')) + 1) / 2;
				//Can't use width() as images may be display:none
				var scaledImageWidth = Math.floor(imageW / hR);
				var focusX = Math.floor(focusFactorX * scaledImageWidth);
				//console.log('x'+focusX);
				//Calculate difference beetween focus point and center
				var focusOffsetX = focusX - containerCenterX;
				//Reduce offset if necessary so image remains filled
				var xRemainder = scaledImageWidth - focusX;
				var containerXRemainder = containerW - containerCenterX;
				if (xRemainder < containerXRemainder) focusOffsetX -= containerXRemainder - xRemainder;
				if (focusOffsetX < 0) focusOffsetX = 0;
				//console.log('x'+focusOffsetX);
				//Shift to left
				hShift = focusOffsetX * -1;
			} else if (wR < hR) {
				//Container center in px
				var containerCenterY = Math.floor(containerH / 2);
				//Focus point of resize image in px
				var focusFactorY = (Number($(this).data('focus-y')) + 1) / 2;
				//Can't use width() as images may be display:none
				var scaledImageHeight = Math.floor(imageH / wR);
				var focusY = scaledImageHeight - Math.floor(focusFactorY * scaledImageHeight);
				//Calculate difference beetween focus point and center
				var focusOffsetY = focusY - containerCenterY;
				//Reduce offset if necessary so image remains filled
				var yRemainder = scaledImageHeight - focusY;
				var containerYRemainder = containerH - containerCenterY;
				if (yRemainder < containerYRemainder) focusOffsetY -= containerYRemainder - yRemainder;
				if (focusOffsetY < 0) focusOffsetY = 0;
				//Shift to top
				vShift = focusOffsetY * -1;
			}
			image.css('left', hShift + 'px');
			image.css('top', vShift + 'px');
		});
	};
})(jQuery);<commit_msg>added missing var<commit_after>/*!
 * jQuery FocusPoint; version: 1.0.0
 * Author: http://jonathonmenz.com
 * Source: https://github.com/jonom/jquery-focuspoint
 * Copyright (c) 2014 J. Menz; MIT License
 */
;
(function($) {
	$.fn.focusPoint = function(options) {
		var settings = $.extend({
			// These are the defaults.
			reCalcOnWindowResize: true
		}, options);
		return this.each(function() {
			//Initial adjustments
			var container = $(this);
			//Replace basic css positioning with more accurate version
			container.removeClass('focus-left-top focus-left-center focus-left-bottom focus-center-top focus-center-center focus-center-bottom focus-right-top focus-right-center focus-right-bottom');
			//Focus image in container
			container.adjustFocus();
			if (settings.reCalcOnWindowResize) {
				//Recalculate each time the window is resized
				$(window).resize(function() {
					container.adjustFocus();
				});
			}
		});
	};
	$.fn.adjustFocus = function() {
		return this.each(function() {
			//Adjust the focus of frame
			var containerW = $(this).width();
			var containerH = $(this).height();
			var image = $(this).find('img').first();
			var imageW = $(this).data('imageW');
			var imageH = $(this).data('imageH');
			if (!(containerW > 0 && containerH > 0 && imageW > 0 && imageH > 0)) {
				//Need dimensions to proceed
				return false;
			}
			//Which is over by more?
			var wR = imageW / containerW;
			var hR = imageH / containerH;
			//Minimise image while still filling space
			if (imageW > containerW && imageH > containerH) {
				if (wR > hR) {
					image.css('max-width', '');
					image.css('max-height', '100%');
				} else {
					image.css('max-width', '100%');
					image.css('max-height', '');
				}
			} else {
				image.css('max-width', '');
				image.css('max-height', '');
			}
			//Amount position will be shifted
			var hShift = 0;
			var vShift = 0;
			if (wR > hR) {
				//Container center in px
				var containerCenterX = Math.floor(containerW / 2);
				//Focus point of resize image in px
				var focusFactorX = (Number($(this).data('focus-x')) + 1) / 2;
				//Can't use width() as images may be display:none
				var scaledImageWidth = Math.floor(imageW / hR);
				var focusX = Math.floor(focusFactorX * scaledImageWidth);
				//console.log('x'+focusX);
				//Calculate difference beetween focus point and center
				var focusOffsetX = focusX - containerCenterX;
				//Reduce offset if necessary so image remains filled
				var xRemainder = scaledImageWidth - focusX;
				var containerXRemainder = containerW - containerCenterX;
				if (xRemainder < containerXRemainder) focusOffsetX -= containerXRemainder - xRemainder;
				if (focusOffsetX < 0) focusOffsetX = 0;
				//console.log('x'+focusOffsetX);
				//Shift to left
				hShift = focusOffsetX * -1;
			} else if (wR < hR) {
				//Container center in px
				var containerCenterY = Math.floor(containerH / 2);
				//Focus point of resize image in px
				var focusFactorY = (Number($(this).data('focus-y')) + 1) / 2;
				//Can't use width() as images may be display:none
				var scaledImageHeight = Math.floor(imageH / wR);
				var focusY = scaledImageHeight - Math.floor(focusFactorY * scaledImageHeight);
				//Calculate difference beetween focus point and center
				var focusOffsetY = focusY - containerCenterY;
				//Reduce offset if necessary so image remains filled
				var yRemainder = scaledImageHeight - focusY;
				var containerYRemainder = containerH - containerCenterY;
				if (yRemainder < containerYRemainder) focusOffsetY -= containerYRemainder - yRemainder;
				if (focusOffsetY < 0) focusOffsetY = 0;
				//Shift to top
				vShift = focusOffsetY * -1;
			}
			image.css('left', hShift + 'px');
			image.css('top', vShift + 'px');
		});
	};
})(jQuery);<|endoftext|>


<commit_before>/**
 * Knob - jQuery Plugin
 * Nice, configurable, backward compatible knob UI component
 *
 * Copyright (c) 2011 - 2013 Anthony Terrien

 * Version: 1.0.0 (23/11/2011)
 * Requires: jQuery v1.7+
 *
 * Under MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 */
$(function() {

    $.fn.knob = function( gopt ) {

        return this.each(

                    function() {

                        var $this = $(this);

                        if( $this.data('knobed') ) return $this;
                        $this.data('knobed',true);

                        var opt = $.extend(
                                        {
                                            'min' : $this.data('min') || 0
                                            ,'max' : $this.data('max') || 100
                                            ,'cursor' : $this.data('cursor')
                                            ,'thickness' : $this.data('thickness') || .3
                                            ,'width' : $this.data('width') || 200
                                            ,'displayInput' : $this.data('displayinput')==null || $this.data('displayinput')
                                            ,'fgColor' : $this.data('fgcolor') || '#87CEEB' //#222222'
                                            ,'bgColor' : $this.data('bgcolor') || '#EEEEEE'
                                            ,'readOnly' : $this.data('readonly')
                                            ,'draw' :
                                                    /**
                                                     * @param int a angle
                                                     * @param int v current value
                                                     * @param array opt plugin options
                                                     * @param context ctx Canvas context 2d
                                                     */
                                                    function( a, v, opt, ctx ) {
                                                            var sa = 1.5*Math.PI
                                                                ,ea = sa+a
                                                                ,r = opt.width/2
                                                                ,lw = r*opt.thickness;

                                                            ctx.clearRect(0, 0, opt.width, opt.width);
                                                            ctx.lineWidth = lw;

                                                            opt.cursor
                                                                && ( sa = ea-0.3 )
                                                                && ( ea = ea+0.3 );

                                                            ctx.beginPath();
                                                            ctx.strokeStyle = opt.fgColor;
                                                            ctx.arc( r, r, r-lw, sa, ea, false);
                                                            ctx.stroke();

                                                            ctx.beginPath();
                                                            ctx.strokeStyle = opt.bgColor;
                                                            ctx.arc(
                                                                        r, r, r-lw ,sa
                                                                        ,(v==opt.min && !opt.cursor)
                                                                            ? sa+0.0001
                                                                            : ea
                                                                        , true
                                                                    );
                                                            ctx.stroke();
                                                        }
                                            ,'change' :
                                                    /**
                                                     * @param int v Current value
                                                     */
                                                    function(v) {}
                                            ,'release' :
                                                    /**
                                                     * @param int v Current value
                                                     */
                                                    function(v) {}
                                        }
                                        ,gopt
                                    );

                        var c = $('<canvas width="'+opt.width+'" height="'+opt.width+'"></canvas>')
                            //,ipt = $('<input type="text">')
                            ,wd = $('

')
                            ,k;

                        $this.wrap( wd )
                        $this.before( c );

                        opt.displayInput
                        && $this.css(
                                    {
                                    'width' : opt.width/2+'px'
                                    ,'position' : 'absolute'
                                    ,'margin-top' : (opt.width*5/13)+'px'
                                    ,'margin-left' : '-'+3*opt.width/4+'px'
                                    ,'font-size' : opt.width/5+'px'
                                    ,'border' : 'none'
                                    ,'background' : 'none'
                                    ,'font-family' : 'Arial'
                                    ,'font-weight' : 'bold'
                                    ,'text-align' : 'center'
                                    ,'color' : 'lightgrey'
                                    ,'padding' : '0px'
                                    ,'-webkit-appearance': 'none'
                                    }
                                )
                        || $this.css(
                                    {
                                    'width' : '0px'
                                    , 'visibility' : 'hidden'
                                    }
                                );

                        k = new Knob( c, opt );
                        k.onChange = function(v) {
                                                    $this.val(v);
                                                    opt.change(v);
                                                 };
                        k.onRelease = opt.release;
                        k.set( parseInt($this.val()) || 0 );

                        if( !opt.readOnly ){
                            c.bind(
                                "mousedown touchstart"
                                ,function( e ) {
                                    e.preventDefault();
                                    k.startDrag( e );
                                }
                            );
                        }else{
                            $this.attr('readonly','readonly');
                        }

                        return $this;
                    }
                );
    }

    Knob = function( c, opt ) {

        var v = 0
            ,ctx = c[0].getContext("2d")
            ,a = Math.PI*0.0001
            ,PI2 = 2*Math.PI
            ,mx ,my ,x ,y
            ,_self = this;

        this.onChange = function() {}
        this.onRelease = function() {}

        this.set = function(_v) {
            a = (_v-opt.min)*PI2/(opt.max-opt.min);
            opt.draw( a, _v, opt, ctx );
        }

        this.get = function() {
            var b = a = Math.atan2( mx-x, -(my-y-opt.width/2) );
            (a<0) && (b=a+PI2);
            v = Math.round( b*(opt.max-opt.min)/PI2 ) + opt.min;
            return v = ( v>opt.max ) ? opt.max : v;
        }

        this.capture = function(e) {
            switch( e.type ){
                case 'mousemove' :
                case 'mousedown' :
                    mx = e.pageX;
                    my = e.pageY;
                    break;
                case 'touchmove' :
                case 'touchstart' :
                    mx = e.originalEvent.touches[0].pageX;
                    my = e.originalEvent.touches[0].pageY;
                    break;
            }

            this.onChange( _v = this.get() );
            this.set( _v );
        }

        this.startDrag = function(e) {

            var p = c.position();

            x = p.left+(opt.width/2);
            y = p.top;

            this.capture(e);

            $(document).bind(
                            "mousemove.knob touchmove.knob"
                            ,function(e) {
                                _self.capture(e);
                            }
                        )
                        .bind(
                            "mouseup.knob touchend.knob"
                            ,function() {
                                $(document).unbind('mousemove.knob touchmove.knob mouseup.knob touchend.knob');
                                _self.onRelease(v);
                            }
                        );
        }
    }

    $(".knob").knob();
});<commit_msg>onChange triggered only when necessary<commit_after>/**
 * Knob - jQuery Plugin
 * Nice, configurable, backward compatible knob UI component
 *
 * Copyright (c) 2011 - 2013 Anthony Terrien

 * Version: 1.0.0 (23/11/2011)
 * Requires: jQuery v1.7+
 *
 * Under MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 */
$(function() {

    $.fn.knob = function( gopt ) {

        return this.each(

                    function() {

                        var $this = $(this);

                        if( $this.data('knobed') ) return $this;
                        $this.data('knobed',true);

                        var opt = $.extend(
                                        {
                                            'min' : $this.data('min') || 0
                                            ,'max' : $this.data('max') || 100
                                            ,'cursor' : $this.data('cursor')
                                            ,'thickness' : $this.data('thickness') || .3
                                            ,'width' : $this.data('width') || 200
                                            ,'displayInput' : $this.data('displayinput')==null || $this.data('displayinput')
                                            ,'fgColor' : $this.data('fgcolor') || '#87CEEB' //#222222'
                                            ,'bgColor' : $this.data('bgcolor') || '#EEEEEE'
                                            ,'readOnly' : $this.data('readonly')
                                            ,'draw' :
                                                    /**
                                                     * @param int a angle
                                                     * @param int v current value
                                                     * @param array opt plugin options
                                                     * @param context ctx Canvas context 2d
                                                     */
                                                    function( a, v, opt, ctx ) {
                                                            var sa = 1.5*Math.PI
                                                                ,ea = sa+a
                                                                ,r = opt.width/2
                                                                ,lw = r*opt.thickness;

                                                            ctx.clearRect(0, 0, opt.width, opt.width);
                                                            ctx.lineWidth = lw;

                                                            opt.cursor
                                                                && ( sa = ea-0.3 )
                                                                && ( ea = ea+0.3 );

                                                            ctx.beginPath();
                                                            ctx.strokeStyle = opt.fgColor;
                                                            ctx.arc( r, r, r-lw, sa, ea, false);
                                                            ctx.stroke();

                                                            ctx.beginPath();
                                                            ctx.strokeStyle = opt.bgColor;
                                                            ctx.arc(
                                                                        r, r, r-lw ,sa
                                                                        ,(v==opt.min && !opt.cursor)
                                                                            ? sa+0.0001
                                                                            : ea
                                                                        , true
                                                                    );
                                                            ctx.stroke();
                                                        }
                                            ,'change' :
                                                    /**
                                                     * @param int v Current value
                                                     */
                                                    function(v) {}
                                            ,'release' :
                                                    /**
                                                     * @param int v Current value
                                                     */
                                                    function(v) {}
                                        }
                                        ,gopt
                                    );

                        var c = $('<canvas width="'+opt.width+'" height="'+opt.width+'"></canvas>')
                            //,ipt = $('<input type="text">')
                            ,wd = $('

')
                            ,k;

                        $this.wrap( wd )
                        $this.before( c );

                        opt.displayInput
                        && $this.css(
                                    {
                                    'width' : opt.width/2+'px'
                                    ,'position' : 'absolute'
                                    ,'margin-top' : (opt.width*5/13)+'px'
                                    ,'margin-left' : '-'+3*opt.width/4+'px'
                                    ,'font-size' : opt.width/5+'px'
                                    ,'border' : 'none'
                                    ,'background' : 'none'
                                    ,'font-family' : 'Arial'
                                    ,'font-weight' : 'bold'
                                    ,'text-align' : 'center'
                                    ,'color' : 'lightgrey'
                                    ,'padding' : '0px'
                                    ,'-webkit-appearance': 'none'
                                    }
                                )
                        || $this.css(
                                    {
                                    'width' : '0px'
                                    , 'visibility' : 'hidden'
                                    }
                                );

                        k = new Knob( c, opt );
                        k.onChange = function(v) {
                                                    $this.val(v);
                                                    opt.change(v);
                                                 };
                        k.onRelease = opt.release;
                        k.val( parseInt($this.val()) || 0 );

                        if( !opt.readOnly ){
                            c.bind(
                                "mousedown touchstart"
                                ,function( e ) {
                                    e.preventDefault();
                                    k.startDrag( e );
                                }
                            );
                        }else{
                            $this.attr('readonly','readonly');
                        }

                        return $this;
                    }
                );
    }

    Knob = function( c, opt ) {

        var v = 0
            ,ctx = c[0].getContext("2d")
            ,a = Math.PI*0.0001
            ,PI2 = 2*Math.PI
            ,mx ,my ,x ,y
            ,_self = this;

        this.onChange = function() {}
        this.onRelease = function() {}

        this.val = function(_v) {
            if(null!=_v){
                if( v==_v ) return;
                v=_v;
                this.onChange(_v);
                a = (_v-opt.min)*PI2/(opt.max-opt.min);
                opt.draw( a, _v, opt, ctx );
            }else{
                var b = a = Math.atan2( mx-x, -(my-y-opt.width/2) );
                (a<0) && (b=a+PI2);
                 _v = Math.round( b*(opt.max-opt.min)/PI2 ) + opt.min;
                return ( _v>opt.max ) ? opt.max : _v;
            }
        }

        this.capture = function(e) {
            switch( e.type ){
                case 'mousemove' :
                case 'mousedown' :
                    mx = e.pageX;
                    my = e.pageY;
                    break;
                case 'touchmove' :
                case 'touchstart' :
                    mx = e.originalEvent.touches[0].pageX;
                    my = e.originalEvent.touches[0].pageY;
                    break;
            }
            this.val( this.val() );
        }

        this.startDrag = function(e) {

            var p = c.position();

            x = p.left+(opt.width/2);
            y = p.top;

            this.capture(e);

            $(document).bind(
                            "mousemove.knob touchmove.knob"
                            ,function(e) {
                                _self.capture(e);
                            }
                        )
                        .bind(
                            "mouseup.knob touchend.knob"
                            ,function() {
                                $(document).unbind('mousemove.knob touchmove.knob mouseup.knob touchend.knob');
                                _self.onRelease(v);
                            }
                        );
        }
    }

    $(".knob").knob();
});<|endoftext|>


<commit_before>var layoutMenus = true;

angular.module('handd', ['ngRoute'])
.value('wikiUrl', 'http://wiki.hackersanddesigners.nl/mediawiki/api.php')
.filter('unsafe', function($sce) {
  return function(val) {
    return $sce.trustAsHtml(val);
  };
})

.service('Homepage', function(wikiUrl, $http) {
  var self = this;
  this.fetch = function(wikipage, callback) {
    var wikiApiUrl = wikiUrl+'?action=parse&page=' + encodeURIComponent(wikipage) + '&format=json&disableeditsection=true';
    $http.get(wikiApiUrl).then(function(res) {
      var obj = res.data;
      html = {
        'title' : obj.parse.title,
        'text' : obj.parse.text['*']
      };
      var semanticApiUrl = wikiUrl + '?action=browsebysubject&subject=' + encodeURIComponent(wikipage) + '&format=json';
      $http.get(semanticApiUrl).then(function(res) {
        var data = res.data.query.data;
        for(var i = 0; i < data.length; i++) {
          var item = data[i];
          html[item.property] = item.dataitem[0].item;
        }
        callback(html);
      });
    });
  };
})

.service('Ask', function(wikiUrl, $http, $q) {
  var self = this;
  this.fetchList = function(type, callback) {
    var objs = {};
    var promises = [];
    var query = '[[Category:Events]][[Type::' + type + ']]|?NameOfEvent|?OnDate|?Venue|?Time|sort=OnDate|order=descending';
    var url = wikiUrl + '?action=ask&query=' + query + '&format=json';
    //promises.push(
    $http.get(url).then(function(res) {
      //Aucallback(res.data);
      var data = res.data;
      var obj = data.query.results;
      if(!Array.isArray(obj)) {
        for (var attr in obj) { objs[attr] = obj[attr]; }
      }
      callback(objs);
    //}));
    });
    //$q.all(promises).then(function() {
    //});
  };
  this.fetchImages = function(callback) {
    var url = wikiUrl + '?action=query&list=allimages&ailimit=10&format=json'
    $http.get(url).then(function(res) {
      var data = res.data;
      callback(data.query.allimages);
    });
  };
})

.config(function($routeProvider) {
  $routeProvider
  .when('/', {
    controller:'HomepageController as homepage',
    templateUrl:'homepage.html',
    resolve: {
    }
  })
  .when('/:wikipage', {
    controller:'HomepageController as homepage',
    templateUrl:'homepage.html',
    resolve: {
    }
  })
})

.controller('HomepageController', function(Homepage, $scope, $routeParams) {
    var homepage = this;
    $scope.formatDate = function(dateStr) {
      var items = dateStr.split('/');
      return items[3] + '/' + items[2] + '/' + items[1];
    };
    $scope.formatStr = function(str) {
      str = str.replace(/_/g, ' ');
      str = str.slice(0, str.length - 3);
      return str;
    }
    var wikipage = $routeParams.wikipage || 'Hackers_&_Designers';
    Homepage.fetch(wikipage, function(html) {
      homepage.html = html;
    });
})

.controller('PicsController', function(Ask, $scope, $window, $document) {
  var w = window,
    d = document,
    e = d.documentElement,
    g = d.getElementsByTagName('body')[0],
    x = (d.innerWidth || e.clientWidth || g.clientWidth) - 160,
    y = d.innerHeight || w.innerHeight || e.clientHeight|| g.clientHeight;
  var _startX = 0;
  var _startY = 0;
  var _offsetX = 0;
  var _offsetY = 0;
  var _dragElement;
  var _oldZIndex = 0;
  var _zindex = 10;
  var photosInitialized = false;
  var extractNumber = function(value) {
    var n = parseInt(value);
    return n == null || isNaN(n) ? 0 : n;
  };

  var fadeOut = function() {
    document.getElementById('photos').style.display = 'none';
    document.getElementById('close').style.display = 'none';
  };

  document.querySelector('#close').onclick = fadeOut;

  var onMouseDown = function(e) {
    if (e == null) e = $window.event;
    var target = e.target != null ? e.target : e.srcElement;

    if ((e.button == 1 && $window.event != null ||
      e.button == 0) &&
      target.className.indexOf('drag') > -1) {
      _startX = e.clientX;
      _startY = e.clientY;
      _offsetX = extractNumber(target.style.left);
      _offsetY = extractNumber(target.style.top);
      _oldZIndex = target.style.zIndex;
      target.style.zIndex = 10000;
      _dragElement = target;
      document.onmousemove = onMouseMove;
      document.body.focus();
      document.onselectstart = function () { return false; };
      target.ondragstart = function() { return false; };
      return false;
    }
  };

  var onMouseMove = function(e) {
    if (e == null) var e = window.event;
    _dragElement.style.left = (_offsetX + e.clientX - _startX) + 'px';
    _dragElement.style.top = (_offsetY + e.clientY - _startY) + 'px';
    _dragElement.style.top + ')';
  };

  var onMouseUp = function(e) {
    if (_dragElement != null) {
      _dragElement.style.zIndex = ++_zindex;
      document.onmousemove = null;
      document.onselectstart = null;
      _dragElement.ondragstart = null;
      _dragElement = null;
    }
  };

  Ask.fetchImages(function(objs) {
    if(!photosInitialized) {
      photosInitialized = true;
      document.onmousedown = onMouseDown;
      document.onmouseup = onMouseUp;
    }
    document.getElementById('photos').style.display = 'block';
    document.getElementById('close').style.display = 'block';

    for(var i = 0; i < objs.length; i++) {
      var photo = objs[i];
      var div = document.querySelector('#photos');
      var image = document.createElement('img');
      image.src = photo.url;
      image.className = 'drag';
      image.style.top = '' + Math.random() * (y) + 'px';
      image.style.left = '' + (Math.random() * (x) - 160) + 'px';
      div.appendChild(image);
    }
  });
})

.controller('LeftNavController', function(Ask, $scope) {
  $scope.title = 'MEETUPS';
  $scope.showMenu = function($event) {
    angular.element($event.currentTarget).toggleClass('showing');
  };
  $scope.formatDate = function(dateStr) {
    var date = new Date(parseInt(dateStr) * 1000);
    return date.getDate() + '/' + (parseInt(date.getMonth()) + 1) + '/' + date.getFullYear();
  };
  Ask.fetchList('Meetup', function(objs) {
    $scope.events = objs;
  });
})

.controller('RightNavController', function(Ask, $scope) {
  $scope.title = 'SUMMERY ACADEMY';
  $scope.showMenu = function($event) {
    angular.element($event.currentTarget).toggleClass('showing');
  };
  $scope.formatDate = function(dateStr) {
    var date = new Date(parseInt(dateStr) * 1000);
    return date.getDate() + '/' + date.getMonth() + '/' + date.getFullYear();
  };
  Ask.fetchList('Summer Academy', function(objs) {
    $scope.events = objs;
  });
})

.directive('updateimages', function($timeout) {
  return {
    link: function(scope, element) {
      $timeout(function() {
        var images = element.find('img');
        for(var index in images) {
          var el = angular.element(images[index]);
          var wikiUrl = 'http://wiki.hackersanddesigners.nl';
          // Fix src attr - JBG
          var src = el.prop('src');
          if(src) {
            src = src.replace(/.*?:\/\//g, '');
            var str = '.*?/mediawiki';
            var re = new RegExp(str, 'g');
            src = src.replace(re, wikiUrl + '/mediawiki');
            el.attr('src', src);
          }

          // Fix srcset attr - JBG
          var srcset = el.prop('srcset');
          if(srcset) {
            srcset = srcset.replace(/.*?:\/\//g, '');
            var str = '/mediawiki';
            var re = new RegExp(str, 'g');
            srcset = srcset.replace(re, wikiUrl + '/mediawiki');
            el.attr('srcset', srcset);
          }
        }
      }, 1000);
    }
  };
})

.directive('updatelinks', function($timeout) {
  return {
    link: function(scope, element) {
      $timeout(function() {
        var links = element.find('a');
        for(var index in links) {
          var el = angular.element(links[index]);
          var href = el.prop('href');
          //dealing with these unruly anchorlinks
          if(href && href.indexOf('#') != -1) {
            el.prop('href', null);
            //Trying to get angular $scope.scrollTo() to work. No luck so far
//              var anchorLink = href.split('#')[1];
//              var linkToEl = 'scrollTo("' + anchorLink + '")';
//              console.log(linkToEl);
//              el.prop('ng-click', linkToEl);
          };
          if(href && href.indexOf('mediawiki') != -1) {
            var paths = href.split('/');
            var last = paths[paths.length - 1];
            el.prop('href', '#/' + last);
          };
          //removes href for files/images
          if (href && href.indexOf('File') != -1) {
            el.prop('href', null);
          };
        }
      }, 1000);
    }
  };
});
<commit_msg>images not clickable<commit_after>var layoutMenus = true;

angular.module('handd', ['ngRoute'])
.value('wikiUrl', 'http://wiki.hackersanddesigners.nl/mediawiki/api.php')
.filter('unsafe', function($sce) {
  return function(val) {
    return $sce.trustAsHtml(val);
  };
})

.service('Homepage', function(wikiUrl, $http) {
  var self = this;
  this.fetch = function(wikipage, callback) {
    var wikiApiUrl = wikiUrl+'?action=parse&page=' + encodeURIComponent(wikipage) + '&format=json&disableeditsection=true';
    $http.get(wikiApiUrl).then(function(res) {
      var obj = res.data;
      html = {
        'title' : obj.parse.title,
        'text' : obj.parse.text['*']
      };
      var semanticApiUrl = wikiUrl + '?action=browsebysubject&subject=' + encodeURIComponent(wikipage) + '&format=json';
      $http.get(semanticApiUrl).then(function(res) {
        var data = res.data.query.data;
        for(var i = 0; i < data.length; i++) {
          var item = data[i];
          html[item.property] = item.dataitem[0].item;
        }
        callback(html);
      });
    });
  };
})

.service('Ask', function(wikiUrl, $http, $q) {
  var self = this;
  this.fetchList = function(type, callback) {
    var objs = {};
    var promises = [];
    var query = '[[Category:Events]][[Type::' + type + ']]|?NameOfEvent|?OnDate|?Venue|?Time|sort=OnDate|order=descending';
    var url = wikiUrl + '?action=ask&query=' + query + '&format=json';
    //promises.push(
    $http.get(url).then(function(res) {
      //Aucallback(res.data);
      var data = res.data;
      var obj = data.query.results;
      if(!Array.isArray(obj)) {
        for (var attr in obj) { objs[attr] = obj[attr]; }
      }
      callback(objs);
    //}));
    });
    //$q.all(promises).then(function() {
    //});
  };
  this.fetchImages = function(callback) {
    var url = wikiUrl + '?action=query&list=allimages&ailimit=10&format=json&aisort=timestamp&aidir=newer'
    $http.get(url).then(function(res) {
      var data = res.data;
      callback(data.query.allimages);
    });
  };
})

.config(function($routeProvider) {
  $routeProvider
  .when('/', {
    controller:'HomepageController as homepage',
    templateUrl:'homepage.html',
    resolve: {
    }
  })
  .when('/:wikipage', {
    controller:'HomepageController as homepage',
    templateUrl:'homepage.html',
    resolve: {
    }
  })
})

.controller('HomepageController', function(Homepage, $scope, $routeParams) {
    var homepage = this;
    $scope.formatDate = function(dateStr) {
      var items = dateStr.split('/');
      return items[3] + '/' + items[2] + '/' + items[1];
    };
    $scope.formatStr = function(str) {
      str = str.replace(/_/g, ' ');
      str = str.slice(0, str.length - 3);
      return str;
    }
    var wikipage = $routeParams.wikipage || 'Hackers_&_Designers';
    Homepage.fetch(wikipage, function(html) {
      homepage.html = html;
    });
})

.controller('PicsController', function(Ask, $scope, $window, $document) {
  var w = window,
    d = document,
    e = d.documentElement,
    g = d.getElementsByTagName('body')[0],
    x = (d.innerWidth || e.clientWidth || g.clientWidth) - 160,
    y = d.innerHeight || w.innerHeight || e.clientHeight|| g.clientHeight;
  var _startX = 0;
  var _startY = 0;
  var _offsetX = 0;
  var _offsetY = 0;
  var _dragElement;
  var _oldZIndex = 0;
  var _zindex = 10;
  var photosInitialized = false;
  var extractNumber = function(value) {
    var n = parseInt(value);
    return n == null || isNaN(n) ? 0 : n;
  };

  var fadeOut = function() {
    document.getElementById('photos').style.display = 'none';
    document.getElementById('close').style.display = 'none';
  };

  document.querySelector('#close').onclick = fadeOut;

  var onMouseDown = function(e) {
    if (e == null) e = $window.event;
    var target = e.target != null ? e.target : e.srcElement;

    if ((e.button == 1 && $window.event != null ||
      e.button == 0) &&
      target.className.indexOf('drag') > -1) {
      _startX = e.clientX;
      _startY = e.clientY;
      _offsetX = extractNumber(target.style.left);
      _offsetY = extractNumber(target.style.top);
      _oldZIndex = target.style.zIndex;
      target.style.zIndex = 10000;
      _dragElement = target;
      document.onmousemove = onMouseMove;
      document.body.focus();
      document.onselectstart = function () { return false; };
      target.ondragstart = function() { return false; };
      return false;
    }
  };

  var onMouseMove = function(e) {
    if (e == null) var e = window.event;
    _dragElement.style.left = (_offsetX + e.clientX - _startX) + 'px';
    _dragElement.style.top = (_offsetY + e.clientY - _startY) + 'px';
    _dragElement.style.top + ')';
  };

  var onMouseUp = function(e) {
    if (_dragElement != null) {
      _dragElement.style.zIndex = ++_zindex;
      document.onmousemove = null;
      document.onselectstart = null;
      _dragElement.ondragstart = null;
      _dragElement = null;
    }
  };

  Ask.fetchImages(function(objs) {
    if(!photosInitialized) {
      photosInitialized = true;
      document.onmousedown = onMouseDown;
      document.onmouseup = onMouseUp;
    }
    document.getElementById('photos').style.display = 'block';
    document.getElementById('close').style.display = 'block';

    for(var i = 0; i < objs.length; i++) {
      var photo = objs[i];
      var div = document.querySelector('#photos');
      var image = document.createElement('img');
      image.src = photo.url;
      image.className = 'drag';
      image.style.top = '' + Math.random() * (y) + 'px';
      image.style.left = '' + (Math.random() * (x) - 160) + 'px';
      div.appendChild(image);
    }
  });
})

.controller('LeftNavController', function(Ask, $scope) {
  $scope.title = 'MEETUPS';
  $scope.showMenu = function($event) {
    angular.element($event.currentTarget).toggleClass('showing');
  };
  $scope.formatDate = function(dateStr) {
    var date = new Date(parseInt(dateStr) * 1000);
    return date.getDate() + '/' + (parseInt(date.getMonth()) + 1) + '/' + date.getFullYear();
  };
  Ask.fetchList('Meetup', function(objs) {
    $scope.events = objs;
  });
})

.controller('RightNavController', function(Ask, $scope) {
  $scope.title = 'SUMMERY ACADEMY';
  $scope.showMenu = function($event) {
    angular.element($event.currentTarget).toggleClass('showing');
  };
  $scope.formatDate = function(dateStr) {
    var date = new Date(parseInt(dateStr) * 1000);
    return date.getDate() + '/' + date.getMonth() + '/' + date.getFullYear();
  };
  Ask.fetchList('Summer Academy', function(objs) {
    $scope.events = objs;
  });
})

.directive('updateimages', function($timeout) {
  return {
    link: function(scope, element) {
      $timeout(function() {
        var images = element.find('img');
        for(var index in images) {
          var el = angular.element(images[index]);
          var wikiUrl = 'http://wiki.hackersanddesigners.nl';
          // Fix src attr - JBG
          var src = el.prop('src');
          if(src) {
            src = src.replace(/.*?:\/\//g, '');
            var str = '.*?/mediawiki';
            var re = new RegExp(str, 'g');
            src = src.replace(re, wikiUrl + '/mediawiki');
            el.attr('src', src);
          }

          // Fix srcset attr - JBG
          var srcset = el.prop('srcset');
          if(srcset) {
            srcset = srcset.replace(/.*?:\/\//g, '');
            var str = '/mediawiki';
            var re = new RegExp(str, 'g');
            srcset = srcset.replace(re, wikiUrl + '/mediawiki');
            el.attr('srcset', srcset);
          }
        }
      }, 1000);
    }
  };
})

.directive('updatelinks', function($timeout) {
  return {
    link: function(scope, element) {
      $timeout(function() {
        var links = element.find('a');
        for(var index in links) {
          var el = angular.element(links[index]);
          var href = el.prop('href');
          if(href && href.indexOf('File:') != -1) {
            el.removeAttr('href');
          } else if(href && href.indexOf('mediawiki') != -1) {
            var paths = href.split('/');
            var last = paths[paths.length - 1];
            el.prop('href', '#/' + last);
          };
        }
      }, 1000);
    }
  };
});
<|endoftext|>


<commit_before>var Util, DOM, CloudCmd;

(function (Util, DOM) {
    'use strict';

     CloudCmd.Listeners = new ListenersProto(CloudCmd, Util, DOM);

     function ListenersProto(CloudCmd, Util, DOM){
        var Storage             = DOM.Storage,
            Events              = DOM.Events,
            getConfig           = CloudCmd.getConfig;

        this.analytics          = function() {
            getConfig(function(config) {
                var analytics   = config.analytics,
                    online      = config.online;

                if (analytics && online) {
                    Events.addOnce('mousemove', function(){
                        var FIVE_SECONDS    = 5000,
                            lUrl            = CloudCmd.LIBDIRCLIENT + 'analytics.js';

                        setTimeout(function(){
                            DOM.jsload(lUrl);
                        }, FIVE_SECONDS);
                    });
                }
            });
        };

        this.init = function () {
            appStorage();
            contextMenu();
            dragndrop();
            unload();
            pop();
            online();
        };

        this.initKeysPanel          = function() {
            var i, lButton, id, n, f,
                lKeysPanel = {},

                lFuncs =[
                    null,
                    CloudCmd.Help,              /* f1  */
                    DOM.renameCurrent,          /* f2  */
                    CloudCmd.View,              /* f3  */
                    CloudCmd.Edit,              /* f4  */
                    DOM.copyCurrent,            /* f5  */
                    DOM.moveCurrent,            /* f6  */
                    DOM.promptNewDir,           /* f7  */
                    DOM.promptDeleteSelected,   /* f8  */
                    CloudCmd.Menu,              /* f9  */
                    CloudCmd.Config             /* f10 */
                ];

            n = lFuncs.length;
            for (i = 1; i <= n; i++) {
                id                  = 'f' + i,
                lButton             = DOM.getById(id);
                lKeysPanel[id]      = lButton;

                if (lButton)
                    if (i === 1 || i === 3 || i === 4 || i === 9 || i === 10 || i === 12)
                        Events.addOnce('click', lFuncs[i], lButton);
                    else
                        Events.addClick(lFuncs[i], lButton);
            }

            id                      = '~',
            lButton                 = DOM.getById(id);
            lKeysPanel[id]          = lButton;
            Events.addOnce('click', CloudCmd.Console, lButton);

            id                      = 'contact',
            lButton                 = DOM.getById(id);
            lKeysPanel[id]          = lButton;

            Events.addOnce('click', CloudCmd.Contact, lButton);

            return lKeysPanel;
        };

        /**
         * функция меняет ссыки на ajax-овые
         * @param pPanelID
         */
        this.changeLinks            = function(pPanelID) {
            /* назначаем кнопку очистить кэш и показываем её */
            var lClearStorage = DOM.getById('clear-storage');
                Events.addClick(Storage.clear, lClearStorage);

            /* меняем ссылки на ajax-запросы */
            var lPanel  = DOM.getById(pPanelID),
                a       = DOM.getByTag('a', lPanel),

                /* right mouse click function varible */
                lOnContextMenu_f = function(pEvent){
                    var lReturn_b   = true,
                        Key         = CloudCmd.Key;

                    Key && Key.unsetBind();

                    /* getting html element
                     * currentTarget - DOM event
                     * target        - jquery event
                     */
                    var lTarget = pEvent.currentTarget || pEvent.target;
                    DOM.setCurrentFile(lTarget);

                    if(Util.isFunction(CloudCmd.Menu)) {
                        CloudCmd.Menu({
                            x: pEvent.clientX,
                            y: pEvent.clientY
                        });

                        /* disabling browsers menu*/
                        lReturn_b = false;
                        DOM.Images.showLoad();
                    }

                    return lReturn_b;
                },

            /* drag and drop function varible
             * download file from browser to descktop
             * in Chrome (HTML5)
             */
                lOnDragStart_f = function(pEvent) {
                    var lElement    = pEvent.target,
                        lLink       = lElement.href,
                        lName       = lElement.textContent;

                    /* if it's directory - adding json extension */
                    if( DOM.isCurrentIsDir() ){
                        lName       += '.json';
                        lLink       += '?json';
                    }

                    pEvent.dataTransfer.setData("DownloadURL",
                        'application/octet-stream'  + ':' +
                        lName                       + ':' +
                        lLink);
                },

                lSetCurrentFile_f = function(pEvent){
                    var pElement    = pEvent.target,
                        lTag        = pElement.tagName;

                    if (lTag !== 'LI')
                        do {
                            pElement    = pElement.parentElement;
                            lTag        = pElement.tagName;
                        } while(lTag !== 'LI');

                    DOM.setCurrentFile(pElement);
                },

                lUrl                = CloudCmd.HOST,
                lLoadDirOnce        = CloudCmd.loadDir();

            /* ставим загрузку гифа на клик*/
            Events.addClick( CloudCmd.refresh, a[0].parentElement );

            /* start from 1 cous 0 is a refresh and it's setted up */
            for(var i = 1, n = a.length; i < n ; i++){
                /* убираем адрес хоста*/
                var ai              = a[i],
                    lLink           = Util.removeStr(ai.href, lUrl),
                    lLoadDir        = CloudCmd.loadDir(lLink),
                    /* устанавливаем обработчики на строку
                     * на двойное нажатие на левую кнопку мышки */
                    lLi = ai.parentElement.parentElement;

                /* if we in path - set click event */
                if (lLi.className === 'path')
                    Events.addClick( lLoadDir, ai );
                else {
                    Events.add({
                        'click'         : DOM.preventDefault,
                        'mousedown'     : lSetCurrentFile_f,
                        'contextmenu'   : lOnContextMenu_f
                        }, lLi);

                    Events.add('dragstart', lOnDragStart_f, ai);

                    /* если ссылка на папку, а не файл */
                    if(ai.target !== '_blank'){
                        Events.add({
                            'dblclick' : lLoadDirOnce,
                            'touchend' : lLoadDirOnce
                            }, lLi);
                    }

                    lLi.id = (ai.title ? ai.title : ai.textContent) +
                        '(' + pPanelID + ')';
                }
            }
        };

        function appStorage() {
            getConfig(function(config) {
                var isAppStorage  = config.appStorage,
                    appStorage    = window.applicationStorage;

                if (isAppStorage && appStorage)
                    Events.add('updateready', function() {
                        var ret = confirm('An update is available. Reload now?');

                        if (ret)
                            location.reload();

                    }, appStorage);
                });
        }

        function contextMenu() {
            Events.addContextMenu(function(pEvent){
                CloudCmd.Menu.ENABLED || DOM.preventDefault(pEvent);
            }, document);
        }

        function dragndrop() {
            var panels          = DOM.getByClass('panel'),
                i               = 0,
                n               = panels.length,
                preventDefault  = function (event) {
                    event.stopPropagation();
                    event.preventDefault();
                },
                toggle          = function () {
                    for (i = 0; i < n; i++)
                        DOM.toggleClass(panels[i], 'selected-panel');
                },
                onDrop          = function (event) {
                    var reader, file, files,
                         dir    = DOM.getCurrentDirPath(),
                         load   = function(file){
                            return function(event) {
                                var path    = dir + file.name,
                                    data    = event.target.result;

                                DOM.RESTful.save(path, data, CloudCmd.refresh);
                            };
                        };

                    preventDefault(event);
                    toggle();

                    files               = event.dataTransfer.files;

                    if (files.length) {
                        n               = files.length;

                        for (i = 0; i < n; i++) {
                            reader          = new FileReader();
                            file            = files[i];
                            Events.add('load', load(file), reader);
                            reader.readAsArrayBuffer(file);
                        }
                    }
                };

            Events.add(['dragenter', 'dragleave'], toggle);

            for (i = 0; i < n; i++) {
                Events.add('dragover', preventDefault, panels[i]);
                Events.add('drop', onDrop, panels[i]);
            }
        }

        function unload() {
            DOM.Events.add(['unload', 'beforeunload'], function (pEvent) {
                var lRet,
                    Key     = CloudCmd.Key,
                    lIsBind = Key && Key.isBind();

                if(!lIsBind) {
                    DOM.preventDefault(pEvent);
                    lRet = 'Please make sure that you saved all work.';
                }

                return lRet;
            });
        }

        function pop() {
            Events.add("popstate", function(pEvent) {
                var lPath   = pEvent.state + '?json';

                if (pEvent.state) {
                    lPath   = pEvent.state + '?json';
                    CloudCmd.ajaxLoad(lPath, {nohistory: true});
                } else
                    CloudCmd.route(location.hash);

                return true;
            });
        }

        function online() {
            var cssSet = Util.retFunc(DOM.cssSet, {
                    id      :'local-droids-font',
                    element : document.head,
                    inner   :   '@font-face {font-family: "Droid Sans Mono";'           +
                                'font-style: normal;font-weight: normal;'               +
                                'src: local("Droid Sans Mono"), local("DroidSansMono"),'+
                                ' url("/font/DroidSansMono.woff") format("woff");}'
                });

            if (navigator.onLine)
                Events.addOnce('offline', cssSet);
            else
                cssSet();
        }

     }

})(Util, DOM);
<commit_msg>refactor(listeners) changeLinks<commit_after>var Util, DOM, CloudCmd;

(function (Util, DOM) {
    'use strict';

     CloudCmd.Listeners = new ListenersProto(CloudCmd, Util, DOM);

     function ListenersProto(CloudCmd, Util, DOM){
        var Storage             = DOM.Storage,
            Events              = DOM.Events,
            getConfig           = CloudCmd.getConfig;

        this.analytics          = function() {
            getConfig(function(config) {
                var analytics   = config.analytics,
                    online      = config.online;

                if (analytics && online) {
                    Events.addOnce('mousemove', function(){
                        var FIVE_SECONDS    = 5000,
                            lUrl            = CloudCmd.LIBDIRCLIENT + 'analytics.js';

                        setTimeout(function(){
                            DOM.jsload(lUrl);
                        }, FIVE_SECONDS);
                    });
                }
            });
        };

        this.init = function () {
            appStorage();
            contextMenu();
            dragndrop();
            unload();
            pop();
            online();
        };

        this.initKeysPanel          = function() {
            var i, lButton, id, n, f,
                lKeysPanel = {},

                lFuncs =[
                    null,
                    CloudCmd.Help,              /* f1  */
                    DOM.renameCurrent,          /* f2  */
                    CloudCmd.View,              /* f3  */
                    CloudCmd.Edit,              /* f4  */
                    DOM.copyCurrent,            /* f5  */
                    DOM.moveCurrent,            /* f6  */
                    DOM.promptNewDir,           /* f7  */
                    DOM.promptDeleteSelected,   /* f8  */
                    CloudCmd.Menu,              /* f9  */
                    CloudCmd.Config             /* f10 */
                ];

            n = lFuncs.length;
            for (i = 1; i <= n; i++) {
                id                  = 'f' + i,
                lButton             = DOM.getById(id);
                lKeysPanel[id]      = lButton;

                if (lButton)
                    if (i === 1 || i === 3 || i === 4 || i === 9 || i === 10 || i === 12)
                        Events.addOnce('click', lFuncs[i], lButton);
                    else
                        Events.addClick(lFuncs[i], lButton);
            }

            id                      = '~',
            lButton                 = DOM.getById(id);
            lKeysPanel[id]          = lButton;
            Events.addOnce('click', CloudCmd.Console, lButton);

            id                      = 'contact',
            lButton                 = DOM.getById(id);
            lKeysPanel[id]          = lButton;

            Events.addOnce('click', CloudCmd.Contact, lButton);

            return lKeysPanel;
        };

        /**
         * функция меняет ссыки на ajax-овые
         * @param pPanelID
         */
        this.changeLinks            = function(pPanelID) {
            /* назначаем кнопку очистить кэш и показываем её */
            var lClearStorage = DOM.getById('clear-storage');
                Events.addClick(Storage.clear, lClearStorage);

            /* меняем ссылки на ajax-запросы */
            var lPanel  = DOM.getById(pPanelID),
                a       = DOM.getByTag('a', lPanel),

                /* right mouse click function varible */
                lOnContextMenu_f = function(pEvent){
                    var lReturn_b   = true,
                        Key         = CloudCmd.Key;

                    Key && Key.unsetBind();

                    /* getting html element
                     * currentTarget - DOM event
                     * target        - jquery event
                     */
                    var lTarget = pEvent.currentTarget || pEvent.target;
                    DOM.setCurrentFile(lTarget);

                    if(Util.isFunction(CloudCmd.Menu)) {
                        CloudCmd.Menu({
                            x: pEvent.clientX,
                            y: pEvent.clientY
                        });

                        /* disabling browsers menu*/
                        lReturn_b = false;
                        DOM.Images.showLoad();
                    }

                    return lReturn_b;
                },

            /* drag and drop function varible
             * download file from browser to descktop
             * in Chrome (HTML5)
             */
                lOnDragStart_f = function(pEvent) {
                    var lElement    = pEvent.target,
                        EXT         = 'json',
                        isDir       = DOM.isCurrentIsDir(),
                        lLink       = lElement.href,
                        lName       = lElement.textContent;

                    /* if it's directory - adding json extension */
                    if (isDir) {
                        lName       += '.' + EXT;
                        lLink       += '?' + EXT;
                    }

                    pEvent.dataTransfer.setData('DownloadURL',
                        'application/octet-stream'  + ':' +
                        lName                       + ':' +
                        lLink);
                },

                lSetCurrentFile_f = function(pEvent){
                    var pElement    = pEvent.target,
                        lTag        = pElement.tagName;

                    if (lTag !== 'LI')
                        do {
                            pElement    = pElement.parentElement;
                            lTag        = pElement.tagName;
                        } while(lTag !== 'LI');

                    DOM.setCurrentFile(pElement);
                },

                lUrl                = CloudCmd.HOST,
                lLoadDirOnce        = CloudCmd.loadDir();

            /* ставим загрузку гифа на клик*/
            Events.addClick( CloudCmd.refresh, a[0].parentElement );

            /* start from 1 cous 0 is a refresh and it's setted up */
            for(var i = 1, n = a.length; i < n ; i++){
                /* убираем адрес хоста*/
                var ai              = a[i],
                    lLink           = Util.removeStr(ai.href, lUrl),
                    lLoadDir        = CloudCmd.loadDir(lLink),
                    /* устанавливаем обработчики на строку
                     * на двойное нажатие на левую кнопку мышки */
                    lLi = ai.parentElement.parentElement;

                /* if we in path - set click event */
                if (lLi.className === 'path')
                    Events.addClick( lLoadDir, ai );
                else {
                    Events.add({
                        'click'         : DOM.preventDefault,
                        'mousedown'     : lSetCurrentFile_f,
                        'contextmenu'   : lOnContextMenu_f
                        }, lLi);

                    Events.add('dragstart', lOnDragStart_f, ai);

                    /* если ссылка на папку, а не файл */
                    if(ai.target !== '_blank'){
                        Events.add({
                            'dblclick' : lLoadDirOnce,
                            'touchend' : lLoadDirOnce
                            }, lLi);
                    }

                    lLi.id = (ai.title ? ai.title : ai.textContent) +
                        '(' + pPanelID + ')';
                }
            }
        };

        function appStorage() {
            getConfig(function(config) {
                var isAppStorage  = config.appStorage,
                    appStorage    = window.applicationStorage;

                if (isAppStorage && appStorage)
                    Events.add('updateready', function() {
                        var ret = confirm('An update is available. Reload now?');

                        if (ret)
                            location.reload();

                    }, appStorage);
                });
        }

        function contextMenu() {
            Events.addContextMenu(function(pEvent){
                CloudCmd.Menu.ENABLED || DOM.preventDefault(pEvent);
            }, document);
        }

        function dragndrop() {
            var panels          = DOM.getByClass('panel'),
                i               = 0,
                n               = panels.length,
                preventDefault  = function (event) {
                    event.stopPropagation();
                    event.preventDefault();
                },
                toggle          = function () {
                    for (i = 0; i < n; i++)
                        DOM.toggleClass(panels[i], 'selected-panel');
                },
                onDrop          = function (event) {
                    var reader, file, files,
                         dir    = DOM.getCurrentDirPath(),
                         load   = function(file){
                            return function(event) {
                                var path    = dir + file.name,
                                    data    = event.target.result;

                                DOM.RESTful.save(path, data, CloudCmd.refresh);
                            };
                        };

                    preventDefault(event);
                    toggle();

                    files               = event.dataTransfer.files;

                    if (files.length) {
                        n               = files.length;

                        for (i = 0; i < n; i++) {
                            reader          = new FileReader();
                            file            = files[i];
                            Events.add('load', load(file), reader);
                            reader.readAsArrayBuffer(file);
                        }
                    }
                };

            Events.add(['dragenter', 'dragleave'], toggle);

            for (i = 0; i < n; i++) {
                Events.add('dragover', preventDefault, panels[i]);
                Events.add('drop', onDrop, panels[i]);
            }
        }

        function unload() {
            DOM.Events.add(['unload', 'beforeunload'], function (pEvent) {
                var lRet,
                    Key     = CloudCmd.Key,
                    lIsBind = Key && Key.isBind();

                if(!lIsBind) {
                    DOM.preventDefault(pEvent);
                    lRet = 'Please make sure that you saved all work.';
                }

                return lRet;
            });
        }

        function pop() {
            Events.add("popstate", function(pEvent) {
                var lPath   = pEvent.state + '?json';

                if (pEvent.state) {
                    lPath   = pEvent.state + '?json';
                    CloudCmd.ajaxLoad(lPath, {nohistory: true});
                } else
                    CloudCmd.route(location.hash);

                return true;
            });
        }

        function online() {
            var cssSet = Util.retFunc(DOM.cssSet, {
                    id      :'local-droids-font',
                    element : document.head,
                    inner   :   '@font-face {font-family: "Droid Sans Mono";'           +
                                'font-style: normal;font-weight: normal;'               +
                                'src: local("Droid Sans Mono"), local("DroidSansMono"),'+
                                ' url("/font/DroidSansMono.woff") format("woff");}'
                });

            if (navigator.onLine)
                Events.addOnce('offline', cssSet);
            else
                cssSet();
        }

     }

})(Util, DOM);
<|endoftext|>