// the semi-colon before function invocation is a safety net against concatenated // scripts and/or other plugins which may not be closed properly. ;(function ($, window, document, undefined) { // constants var DEBUG_ENABLED = false; // logging also in IE if (Function.prototype.bind && console && typeof console.log == "object") { ["log", "info", "warn", "error", "assert", "dir", "clear", "profile", "profileEnd"].forEach(function (e) { console[e] = this.call(console[e], console) }, Function.prototype.bind) } var konsole = { log: function (e) { }, dir: function (e) { } }; if (typeof window.console != "undefined" && typeof window.console.log == "function") { konsole = window.console; if (DEBUG_ENABLED) konsole.log("konsole initialized") } function log() { if (DEBUG_ENABLED) konsole.log.apply(konsole, arguments) } /** * Preview. */ var ilPreview = function () { // constants var QTIP_NAMESPACE = "qtip"; var STATUS_NONE = "none"; var STATUS_CREATED = "created"; var STATUS_PENDING = "pending"; var STATUS_FAILED = "failed"; var HIDDEN_ACTION_CLASS = "ilPreviewActionHidden"; // variables var currentId = null; var previewVisible = false; var keyHandler = null; var mouseWheelHandler = null; var self = this; var isKeyPressed = false; var cache = {}; // jquery objects var $tooltip = null; var $previews = null; var $label = null; var $qtip = null; var $highlightedItem = null; // public properties this.texts = { preview: "Preview", showPreview: "Show Preview", close: "Close" }; this.initialHtml = null; this.previewSize = 280; this.highlightClass = "ilContainerListItemOuterHighlight"; /** * Initializes the preview. */ this.init = function () { $previews = $(".il_ContainerItemPreview"); log("Preview.init(): Previews=%s", $previews.length); }; /** * Adds a new object where files can be uploaded to. */ this.toggle = function (e, options) { log("Preview.toggle()"); var id = options.htmlId; // current element? if (id == null || currentId == id) { hideTooltip(); } else { e.stopPropagation(); e.preventDefault(); currentId = id; // lets show the new one showTooltip(e, options); previewVisible = true; } }; /** * Renders the preview for the calling object. */ this.render = function (e, options) { log("Preview.render()"); $("#preview_render_" + options.htmlId).addClass(HIDDEN_ACTION_CLASS); executeAction(options); }; /** * Deletes the preview for the calling object. */ this.delete = function (e, options) { log("Preview.delete()"); $("#preview_delete_" + options.htmlId).addClass(HIDDEN_ACTION_CLASS); executeAction(options); } /** * Executes an action as specified in the specified options. */ function executeAction(options) { // create new html and display loading animation var $html = $(self.initialHtml.replace("%%0%%", options.loadingText)); $html.find(".ilPreviewTextLoading").css("display", "inline-block"); // replace old content and set new id $("#" + options.htmlId).replaceWith($html); $html.attr("id", options.htmlId); // call url $.ajax( { url: options.url, type: "GET", dataType: "json", success: function (data) { log(" -> Action executed: id=%s, status=%s", options.id, data.status); // replace preview $html.replaceWith(data.html); // enable / disable actions if (data.status == STATUS_FAILED || data.status == STATUS_NONE) $("#preview_render_" + options.htmlId).removeClass(HIDDEN_ACTION_CLASS); else $("#preview_render_" + options.htmlId).addClass(HIDDEN_ACTION_CLASS); if (data.status == STATUS_CREATED) $("#preview_delete_" + options.htmlId).removeClass(HIDDEN_ACTION_CLASS); else $("#preview_delete_" + options.htmlId).addClass(HIDDEN_ACTION_CLASS); } }); } /** * Displays the specified content. */ function displayContent(options, content) { // was a different preview requested in the meantime? if (options.htmlId != currentId) return; // replace wait $tooltip.qtip("api").set("content.text", buildContent(content)); // initialize navigation initPreviews(); // show the tooltip if not showing already // thats generaly the case when content comes from the cache if (!$qtip.is(":visible")) $tooltip.qtip("show"); } /** * Shows the preview tooltip. */ function showTooltip(e, options) { // remove old event handlers removeEventHandlers(); // get preview label $label = $("#" + options.htmlId).find(".il_ContainerItemPreview"); // create tooltip initTooltip(); // load preview and show it loadPreview(options, function (content) { displayContent(options, content); }); } /** * Loads the preview asynchronously. */ function loadPreview(options, callback) { var idToLoad = currentId; // object already in cache? if (cache.hasOwnProperty(idToLoad)) { $tooltip.qtip("api").set("position.target", $label); callback(cache[idToLoad]); } else { var loading = self.initialHtml.replace("%%0%%", options.loadingText); // display spinner if needed if (options.status == STATUS_NONE) $(loading).find(".ilPreviewTextLoading").css("display", "inline-block"); $tooltip.qtip("api").set("content.text", buildContent(loading)); $tooltip.qtip("api").set("position.target", $label); // cache the loading text to prevent multiple server calls if // the tooltip is hidden and shown again while the request is running cache[idToLoad] = loading; initPreviews(); $tooltip.qtip("show"); $.ajax( { url: options.url, type: "GET", dataType: "json", success: function (data) { log(" -> Preview loaded: id=%s, status=%s", options.id, data.status); updateCache(options.htmlId, data.status, data.html); callback(data.html); updatePreviewIcon(options, data.status); } }); } highlightItem(options.htmlId); } /** * Updates the preview icon if the preview was renderered on demand. */ function updatePreviewIcon(options, newStatus) { // if previous status was none, update status if (options.status == STATUS_NONE && newStatus == STATUS_CREATED || newStatus == STATUS_FAILED) { $("#" + options.htmlId).find(".il_ContainerItemPreview") .removeClass("ilPreviewStatusNone") .children("a").prop("title", self.texts.showPreview); } } /** * Updates the cache of the specified item with the specified content. */ function updateCache(id, status, content) { // set cache if preview was created switch (status) { // delete cache entry that the request is done again case STATUS_PENDING: delete cache[id]; break; // cache response case STATUS_CREATED: case STATUS_FAILED: case STATUS_NONE: default: cache[id] = content; break; } } /** * Highlights the item with the specified id. */ function highlightItem(htmlId) { // remove old highlight if ($highlightedItem != null) { $highlightedItem.removeClass(self.highlightClass); $highlightedItem = null; } // highlight new item if (htmlId != null) { $highlightedItem = $("#" + htmlId); if ($highlightedItem.length == 1) $highlightedItem.addClass(self.highlightClass); else $highlightedItem = null; } } /** * Builds the content. */ function buildContent(content) { var html = "