<commit_before>// Umbraco Live Editing - ItemEditing: Item Editing
var ItemEditing = null;

Type.registerNamespace("umbraco.presentation.LiveEditing");

/************************ ItemEditing class ************************/

// Creates a new instance of the ItemEditing class.
umbraco.presentation.LiveEditing.ItemEditing = function() {
    umbraco.presentation.LiveEditing.ItemEditing.initializeBase(this);
    this._inited = false;
    this._items = new Array();
    this._activeItem = null;
    this._editControl = null;
    this._submitControl = null;

    var _this = this;
    Sys.Debug.trace("Constructor, before init load");
    if (!this._inited) {
        _this.init();
    }
    Sys.Application.add_load(function() {
        _this.init();
    });
    Sys.Debug.trace("Constructor, after init load");

}

umbraco.presentation.LiveEditing.ItemEditing.prototype = {
    // Initializes this instance.
    init: function() {
        Sys.Debug.trace("In init...");
        if (!this._inited) {
            this._inited = true;
            Sys.Debug.trace("Live Editing - ItemEditing: Initialization.");
            Sys.Debug.assert(typeof (jQuery) == 'function', "jQuery is not loaded.");

            this.itemsEnable();

            var _this = this;
            LiveEditingToolbar.add_save(function(sender, args) { _this.delaySaveWhenEditing(args, "save"); });
            LiveEditingToolbar.add_saveAndPublish(function(sender, args) { _this.delaySaveWhenEditing(args, "saveAndPublish"); });

            this._inited = true;
            Sys.Debug.trace("Live Editing - ItemEditing: Ready.");
        }
        else {
            this.updateItems();
            this.updateControls();
        }
    },

    // Starts Live Editing the specified item.
    // This method is triggered by the server.
    startEdit: function(itemId) {
        Sys.Debug.trace("Live Editing - ItemEditing: Start editing of Item " + itemId + ".");

        this._activeItem = this._items[itemId];
        Sys.Debug.assert(this._activeItem != null, "Live Editing - ItemEditing: Could not find item with ID " + itemId + ".");
        this._editControl = this.getElementsByTagName("umbraco:control");
        Sys.Debug.assert(this._editControl.length > 0, "Live Editing - ItemEditing: Could not find the editor control.");
        //this._activeItem.jItem.fadeIn();
        this.moveChildControls(this._editControl, this._activeItem.jItem);

        // Only elements that are currently present, can cause item editing to stop.
        // This enables transparent use of dynamically created elements (such as context/dropdown menus)
        // as clicks on those elements will not trigger the stop edit signal.
        jQuery("*").each(function() { $(this).data("canStopEditing", true); });

        // raise event
        var handler = this.get_events().getHandler("startEdit");
        if (handler)
            handler(this, Sys.EventArgs.Empty);

        this.ignoreChildClicks(this._activeItem.jItem);

        LiveEditingToolbar.setDirty(true);
    },

    // Stops the editing of a specified item, and raises the stopEdit event.
    stopEdit: function() {
        if (this._activeItem != null) {
            Sys.Debug.trace("Live Editing - ItemEditing: Stop editing of " + this._activeItem.toString() + ".");

            // raise event
            var handler = this.get_events().getHandler("stopEdit");
            if (handler)
                handler(this, Sys.EventArgs.Empty);

            // submit changes
            Sys.Debug.assert(this._submitControl != null, "Live Editing - ItemEditing: Submit button not set.");
            this._submitControl.click();

            // hide control
            //this._activeItem.jItem.fadeOut();
            this._activeItem = null;
            this._submitControl = null;
            this._editControl = null;
        }
    },

    // Adds an event handler to the startEdit event.
    add_startEdit: function(handler) {
        this.get_events().addHandler("startEdit", handler);
    },

    // Removes an event handler from the startEdit event.
    remove_startEdit: function(handler) {
        this.get_events().removeHandler("startEdit", handler);
    },

    // Adds an event handler to the stopEdit event.
    add_stopEdit: function(handler) {
        this.get_events().addHandler("stopEdit", handler);
    },

    // Removes an event handler from the stopEdit event.
    remove_stopEdit: function(handler) {
        this.get_events().removeHandler("stopEdit", handler);
    },

    // Cancels the save method when an item is active, and postpones it to the next postback.
    delaySaveWhenEditing: function(args, type) {
        if (this._activeItem != null) {
            this.stopEdit();
            args.cancel = true;
            (function() {
                var f = function() {
                    Sys.Application.remove_load(f);
                    setTimeout(function() {
                        Sys.Debug.trace("Live Editing - Delayed Saving Changes to server");
                        UmbracoCommunicator.SendClientMessage(type, "");
                    }, 100);
                }
                Sys.Application.add_load(f);
            })();
        }
        else {
            Sys.Debug.trace("Live Editing - Saving Changes to server");
            if (!Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack()) {
                UmbracoCommunicator.SendClientMessage(type, "");
            }
            else {
                Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function() {
                    UmbracoCommunicator.SendClientMessage(type, "");
                });
            }
        }
    },

    // Enables Live Editing of items.
    itemsEnable: function() {
        var items = this.getElementsByTagName("umbraco:iteminfo");
        Sys.Debug.trace("  Found " + items.length + " editable Umbraco item(s).");

        // enhance items with edit functionality
        var _this = this;
        var i = 0;
        items.each(function() {
            var item = new umbraco.presentation.LiveEditing.activeItem($(this));
            _this._items[item.itemId] = item;
            Sys.Debug.trace("    " + (++i) + ". " + item.toString() + " is Live Editing enabled.");
        });
        // disable hyperlinks to make them clickable for Live Editing
        this.disableHyperlinks();

        // add "stop editing" handler when clicking outside the item
        var _this = this;
        jQuery(document).mousedown(function(event) {
            Sys.Debug.trace("DOCUMENT CLICKED");
            // the canStopEditing property is set in startEdit
            if (_this._activeItem != null && $(event.target).data("canStopEditing")) {
                if (!_this._activeItem.clicked)
                    _this.stopEdit();
                else
                    _this._activeItem.clicked = false;
            }
        });
        jQuery("#LiveEditingToolbar").mousedown(function() {
            Sys.Debug.trace("TOOLBAR CLICKED");
            if (_this._activeItem != null)
                _this._activeItem.clicked = true;
        });
    },

    // Update items that have changed.
    updateItems: function() {
        var itemUpdates = this.getElementsByTagName("umbraco:itemupdate");
        Sys.Debug.trace("Live Editing - ItemEditing: " + itemUpdates.length + " item update(s).");

        var _this = this;
        itemUpdates.each(function() {
            var itemUpdate = $(this);
            var itemId = itemUpdate.attr("itemId");
            var item = _this._items[itemId];

            if (item != null) {
                Sys.Debug.trace("  Updating " + item.toString() + ".");

                // remove old children and add updates ones
                _this.moveChildControls(itemUpdate, item.jItem);
                //item.jItem.fadeIn();

                // disable hyperlinks to make them clickable for Live Editing
                _this.disableHyperlinks();
            }
            else {
                itemUpdate.html("");
            }
        });
    },

    // Update controls that have changed.
    updateControls: function() {
        Sys.Debug.trace("Live Editing - ItemEditing: In updatecontrols");
        var controlUpdates = this.getElementsByTagName("umbraco:control");
        Sys.Debug.trace("Live Editing - ItemEditing: " + controlUpdates.length + " control update(s).");

        if (controlUpdates.length == 1) {
            if (this._activeItem != null && controlUpdates.children().length > 0) {
                Sys.Debug.trace("Live Editing - ItemEditing: updating edit control.");
                this.moveChildControls(controlUpdates, this._activeItem.jItem);
                this.ignoreChildClicks();
            }

            this._submitControl = controlUpdates.next();
            Sys.Debug.assert(this._submitControl.length > 0, "Live Editing - ItemEditing: Submit button not found.");
        }
    },

    // ignores clicks on child elements of the control
    ignoreChildClicks: function() {
        var _this = this;
        this._activeItem.jItem.children().mousedown(function(e) {
            _this._activeItem.clicked = true;
        });
    },

    // Moves the child controls from source into destination, overwriting existing elements.
    moveChildControls: function(source, dest) {
        Sys.Debug.trace("Live Editing - Moving Child Controls");

        //remove contents in the destination
        dest.html("");

        //add the source to the destination
        dest.append(source.html());

        //remove teh contents from the source
        source.html("");

    },

    // Gets a list of elements with the specified tagname including namespaced ones
    getElementsByTagName: function(tagname) {
        var found = jQuery("body").find("*").filter(function(index) {
            if (this.nodeType != 3) {
                var nn = this.nodeName.toLowerCase();
                var ftn = tagname.toLowerCase();
                var ln = (ftn.indexOf(":") > 0 ? ftn.substr(ftn.indexOf(":") + 1) : ftn);
                return (nn == ftn
                    || (typeof this.scopeName != "undefined" && nn == ln && this.scopeName.toLowerCase() == ftn.substr(0, ftn.indexOf(":"))));
            }
            return false;
        });
        Sys.Debug.trace("found " + found.length + " elements with selector: " + tagname);
        return found;
    },

    // Disables hyperlinks inside the specified element.
    disableHyperlinks: function() {
        jQuery("a").click(function() {
            return false;
        });
    }
}

umbraco.presentation.LiveEditing.ItemEditing.registerClass("umbraco.presentation.LiveEditing.ItemEditing", Sys.Component);

//an object to store the information for the active item
umbraco.presentation.LiveEditing.activeItem = function(item) {
    //error checking
    if (item != null && item.length != 1) {
        return null;
    }
    //create the object with values, wire up events and return it
    var obj = {
        jItem: item,
        nodeId: item.attr("nodeId"),
        fieldName: item.attr("name"),
        itemId: item.attr("itemId"),
        clicked: false,
        toString: function() {
            return "Item " + this.itemId + " (node " + this.nodeId + ": " + this.fieldName + ")";
        },
        // Activates an item for editing.
        activate: function() {
            ItemEditing._items[this.itemId] = this;
            if (this != ItemEditing._activeItem) {
                Sys.Debug.trace("Live Editing - ItemEditing: " + this.toString() + " was activated.");
                if (!Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack()) {
                    UmbracoCommunicator.SendClientMessage("edititem", this.itemId);
                }
                else {
                    var itemId = this.itemId;
                    Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function() {
                        if (itemId != 0) {
                            UmbracoCommunicator.SendClientMessage("edititem", itemId);
                            itemId = 0;
                        }
                    });
                }
                //this.jItem.fadeOut();
            }
        },
        // Item click handler.
        onClick: function(e) {
            if (ItemEditing._activeItem != null && ItemEditing._activeItem.itemId == this.itemId) {
                Sys.Debug.trace("Live Editing - ItemEditing: " + this.toString() + " click ignored because it is already active.");
            }
            else {
                Sys.Debug.trace("Live Editing - ItemEditing: " + this.toString() + " was clicked.");
                e.stopPropagation(); // disable click event propagation to parent elements
                this.activate();
            }
        }
    }

    //keep the scope on the click event method call
    obj.jItem.click(function(e) {
        obj.onClick.call(obj, e);
    });

    return obj;
}

// global instance of the ItemEditing class
function initializeGlobalItemEditing() {
    ItemEditing = new umbraco.presentation.LiveEditing.ItemEditing();
}<commit_msg>Fixes: 28077 - jquery + canvas issue<commit_after>// Umbraco Live Editing - ItemEditing: Item Editing
var ItemEditing = null;

Type.registerNamespace("umbraco.presentation.LiveEditing");

/************************ ItemEditing class ************************/

// Creates a new instance of the ItemEditing class.
umbraco.presentation.LiveEditing.ItemEditing = function() {
    umbraco.presentation.LiveEditing.ItemEditing.initializeBase(this);
    this._inited = false;
    this._items = new Array();
    this._activeItem = null;
    this._editControl = null;
    this._submitControl = null;

    var _this = this;
    Sys.Debug.trace("Constructor, before init load");
    if (!this._inited) {
        _this.init();
    }
    Sys.Application.add_load(function() {
        _this.init();
    });
    Sys.Debug.trace("Constructor, after init load");

}

umbraco.presentation.LiveEditing.ItemEditing.prototype = {
    // Initializes this instance.
    init: function() {
        Sys.Debug.trace("In init...");
        if (!this._inited) {
            this._inited = true;
            Sys.Debug.trace("Live Editing - ItemEditing: Initialization.");
            Sys.Debug.assert(typeof (jQuery) == 'function', "jQuery is not loaded.");

            this.itemsEnable();

            var _this = this;
            LiveEditingToolbar.add_save(function(sender, args) { _this.delaySaveWhenEditing(args, "save"); });
            LiveEditingToolbar.add_saveAndPublish(function(sender, args) { _this.delaySaveWhenEditing(args, "saveAndPublish"); });

            this._inited = true;
            Sys.Debug.trace("Live Editing - ItemEditing: Ready.");
        }
        else {
            this.updateItems();
            this.updateControls();
        }
    },

    // Starts Live Editing the specified item.
    // This method is triggered by the server.
    startEdit: function(itemId) {
        Sys.Debug.trace("Live Editing - ItemEditing: Start editing of Item " + itemId + ".");

        this._activeItem = this._items[itemId];
        Sys.Debug.assert(this._activeItem != null, "Live Editing - ItemEditing: Could not find item with ID " + itemId + ".");
        this._editControl = this.getElementsByTagName("umbraco:control");
        Sys.Debug.assert(this._editControl.length > 0, "Live Editing - ItemEditing: Could not find the editor control.");
        //this._activeItem.jItem.fadeIn();
        this.moveChildControls(this._editControl, this._activeItem.jItem);

        // Only elements that are currently present, can cause item editing to stop.
        // This enables transparent use of dynamically created elements (such as context/dropdown menus)
        // as clicks on those elements will not trigger the stop edit signal.
        jQuery("*").each(function () { jQuery(this).data("canStopEditing", true); });

        // raise event
        var handler = this.get_events().getHandler("startEdit");
        if (handler)
            handler(this, Sys.EventArgs.Empty);

        this.ignoreChildClicks(this._activeItem.jItem);

        LiveEditingToolbar.setDirty(true);
    },

    // Stops the editing of a specified item, and raises the stopEdit event.
    stopEdit: function() {
        if (this._activeItem != null) {
            Sys.Debug.trace("Live Editing - ItemEditing: Stop editing of " + this._activeItem.toString() + ".");

            // raise event
            var handler = this.get_events().getHandler("stopEdit");
            if (handler)
                handler(this, Sys.EventArgs.Empty);

            // submit changes
            Sys.Debug.assert(this._submitControl != null, "Live Editing - ItemEditing: Submit button not set.");
            this._submitControl.click();

            // hide control
            //this._activeItem.jItem.fadeOut();
            this._activeItem = null;
            this._submitControl = null;
            this._editControl = null;
        }
    },

    // Adds an event handler to the startEdit event.
    add_startEdit: function(handler) {
        this.get_events().addHandler("startEdit", handler);
    },

    // Removes an event handler from the startEdit event.
    remove_startEdit: function(handler) {
        this.get_events().removeHandler("startEdit", handler);
    },

    // Adds an event handler to the stopEdit event.
    add_stopEdit: function(handler) {
        this.get_events().addHandler("stopEdit", handler);
    },

    // Removes an event handler from the stopEdit event.
    remove_stopEdit: function(handler) {
        this.get_events().removeHandler("stopEdit", handler);
    },

    // Cancels the save method when an item is active, and postpones it to the next postback.
    delaySaveWhenEditing: function(args, type) {
        if (this._activeItem != null) {
            this.stopEdit();
            args.cancel = true;
            (function() {
                var f = function() {
                    Sys.Application.remove_load(f);
                    setTimeout(function() {
                        Sys.Debug.trace("Live Editing - Delayed Saving Changes to server");
                        UmbracoCommunicator.SendClientMessage(type, "");
                    }, 100);
                }
                Sys.Application.add_load(f);
            })();
        }
        else {
            Sys.Debug.trace("Live Editing - Saving Changes to server");
            if (!Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack()) {
                UmbracoCommunicator.SendClientMessage(type, "");
            }
            else {
                Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function() {
                    UmbracoCommunicator.SendClientMessage(type, "");
                });
            }
        }
    },

    // Enables Live Editing of items.
    itemsEnable: function() {
        var items = this.getElementsByTagName("umbraco:iteminfo");
        Sys.Debug.trace("  Found " + items.length + " editable Umbraco item(s).");

        // enhance items with edit functionality
        var _this = this;
        var i = 0;
        items.each(function() {
            var item = new umbraco.presentation.LiveEditing.activeItem(jQuery(this));
            _this._items[item.itemId] = item;
            Sys.Debug.trace("    " + (++i) + ". " + item.toString() + " is Live Editing enabled.");
        });
        // disable hyperlinks to make them clickable for Live Editing
        this.disableHyperlinks();

        // add "stop editing" handler when clicking outside the item
        var _this = this;
        jQuery(document).mousedown(function(event) {
            Sys.Debug.trace("DOCUMENT CLICKED");
            // the canStopEditing property is set in startEdit
            if (_this._activeItem != null && jQuery(event.target).data("canStopEditing")) {
                if (!_this._activeItem.clicked)
                    _this.stopEdit();
                else
                    _this._activeItem.clicked = false;
            }
        });
        jQuery("#LiveEditingToolbar").mousedown(function() {
            Sys.Debug.trace("TOOLBAR CLICKED");
            if (_this._activeItem != null)
                _this._activeItem.clicked = true;
        });
    },

    // Update items that have changed.
    updateItems: function() {
        var itemUpdates = this.getElementsByTagName("umbraco:itemupdate");
        Sys.Debug.trace("Live Editing - ItemEditing: " + itemUpdates.length + " item update(s).");

        var _this = this;
        itemUpdates.each(function() {
            var itemUpdate = jQuery(this);
            var itemId = itemUpdate.attr("itemId");
            var item = _this._items[itemId];

            if (item != null) {
                Sys.Debug.trace("  Updating " + item.toString() + ".");

                // remove old children and add updates ones
                _this.moveChildControls(itemUpdate, item.jItem);
                //item.jItem.fadeIn();

                // disable hyperlinks to make them clickable for Live Editing
                _this.disableHyperlinks();
            }
            else {
                itemUpdate.html("");
            }
        });
    },

    // Update controls that have changed.
    updateControls: function() {
        Sys.Debug.trace("Live Editing - ItemEditing: In updatecontrols");
        var controlUpdates = this.getElementsByTagName("umbraco:control");
        Sys.Debug.trace("Live Editing - ItemEditing: " + controlUpdates.length + " control update(s).");

        if (controlUpdates.length == 1) {
            if (this._activeItem != null && controlUpdates.children().length > 0) {
                Sys.Debug.trace("Live Editing - ItemEditing: updating edit control.");
                this.moveChildControls(controlUpdates, this._activeItem.jItem);
                this.ignoreChildClicks();
            }

            this._submitControl = controlUpdates.next();
            Sys.Debug.assert(this._submitControl.length > 0, "Live Editing - ItemEditing: Submit button not found.");
        }
    },

    // ignores clicks on child elements of the control
    ignoreChildClicks: function() {
        var _this = this;
        this._activeItem.jItem.children().mousedown(function(e) {
            _this._activeItem.clicked = true;
        });
    },

    // Moves the child controls from source into destination, overwriting existing elements.
    moveChildControls: function(source, dest) {
        Sys.Debug.trace("Live Editing - Moving Child Controls");

        //remove contents in the destination
        dest.html("");

        //add the source to the destination
        dest.append(source.html());

        //remove teh contents from the source
        source.html("");

    },

    // Gets a list of elements with the specified tagname including namespaced ones
    getElementsByTagName: function(tagname) {
        var found = jQuery("body").find("*").filter(function(index) {
            if (this.nodeType != 3) {
                var nn = this.nodeName.toLowerCase();
                var ftn = tagname.toLowerCase();
                var ln = (ftn.indexOf(":") > 0 ? ftn.substr(ftn.indexOf(":") + 1) : ftn);
                return (nn == ftn
                    || (typeof this.scopeName != "undefined" && nn == ln && this.scopeName.toLowerCase() == ftn.substr(0, ftn.indexOf(":"))));
            }
            return false;
        });
        Sys.Debug.trace("found " + found.length + " elements with selector: " + tagname);
        return found;
    },

    // Disables hyperlinks inside the specified element.
    disableHyperlinks: function() {
        jQuery("a").click(function() {
            return false;
        });
    }
}

umbraco.presentation.LiveEditing.ItemEditing.registerClass("umbraco.presentation.LiveEditing.ItemEditing", Sys.Component);

//an object to store the information for the active item
umbraco.presentation.LiveEditing.activeItem = function(item) {
    //error checking
    if (item != null && item.length != 1) {
        return null;
    }
    //create the object with values, wire up events and return it
    var obj = {
        jItem: item,
        nodeId: item.attr("nodeId"),
        fieldName: item.attr("name"),
        itemId: item.attr("itemId"),
        clicked: false,
        toString: function() {
            return "Item " + this.itemId + " (node " + this.nodeId + ": " + this.fieldName + ")";
        },
        // Activates an item for editing.
        activate: function() {
            ItemEditing._items[this.itemId] = this;
            if (this != ItemEditing._activeItem) {
                Sys.Debug.trace("Live Editing - ItemEditing: " + this.toString() + " was activated.");
                if (!Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack()) {
                    UmbracoCommunicator.SendClientMessage("edititem", this.itemId);
                }
                else {
                    var itemId = this.itemId;
                    Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function() {
                        if (itemId != 0) {
                            UmbracoCommunicator.SendClientMessage("edititem", itemId);
                            itemId = 0;
                        }
                    });
                }
                //this.jItem.fadeOut();
            }
        },
        // Item click handler.
        onClick: function(e) {
            if (ItemEditing._activeItem != null && ItemEditing._activeItem.itemId == this.itemId) {
                Sys.Debug.trace("Live Editing - ItemEditing: " + this.toString() + " click ignored because it is already active.");
            }
            else {
                Sys.Debug.trace("Live Editing - ItemEditing: " + this.toString() + " was clicked.");
                e.stopPropagation(); // disable click event propagation to parent elements
                this.activate();
            }
        }
    }

    //keep the scope on the click event method call
    obj.jItem.click(function(e) {
        obj.onClick.call(obj, e);
    });

    return obj;
}

// global instance of the ItemEditing class
function initializeGlobalItemEditing() {
    ItemEditing = new umbraco.presentation.LiveEditing.ItemEditing();
}<|endoftext|>


<commit_before>// Copyright 2010 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview Provides a soy renderer that allows registration of
 * injected data ("globals") that will be passed into the rendered
 * templates.
 *
 * There is also an interface {@link goog.soy.InjectedDataSupplier} that
 * user should implement to provide the injected data for a specific
 * application. The injected data format is a JavaScript object:
 *

 * {'dataKey': 'value', 'otherDataKey': 'otherValue'}
 *

 *
 * To use injected data, you need to enable the soy-to-js compiler
 * option {@code --isUsingIjData}. The injected data can then be
 * referred to in any soy templates as part of a magic "ij"
 * parameter. For example, {@code $ij.dataKey} will evaluate to
 * 'value' with the above injected data.
 *
 * @author henrywong@google.com (Henry Wong)
 * @author chrishenry@google.com (Chris Henry)
 */

goog.provide('goog.soy.InjectedDataSupplier');
goog.provide('goog.soy.Renderer');

goog.require('goog.asserts');
goog.require('goog.dom');
goog.require('goog.soy');
goog.require('goog.soy.data.SanitizedContent');
goog.require('goog.soy.data.SanitizedContentKind');

/**
 * Creates a new soy renderer. Note that the renderer will only be
 * guaranteed to work correctly within the document scope provided in
 * the DOM helper.
 *
 * @param {goog.soy.InjectedDataSupplier=} opt_injectedDataSupplier A supplier
 *     that provides an injected data.
 * @param {goog.dom.DomHelper=} opt_domHelper Optional DOM helper;
 *     defaults to that provided by {@code goog.dom.getDomHelper()}.
 * @constructor
 */
goog.soy.Renderer = function(opt_injectedDataSupplier, opt_domHelper) {
  /**
   * @type {goog.dom.DomHelper}
   * @private
   */
  this.dom_ = opt_domHelper || goog.dom.getDomHelper();

  /**
   * @type {goog.soy.InjectedDataSupplier}
   * @private
   */
  this.supplier_ = opt_injectedDataSupplier || null;
};

/**
 * Renders a Soy template into a single node or a document fragment.
 * Delegates to {@code goog.soy.renderAsFragment}.
 *
 * @param {Function} template The Soy template defining the element's content.
 * @param {Object=} opt_templateData The data for the template.
 * @return {!Node} The resulting node or document fragment.
 */
goog.soy.Renderer.prototype.renderAsFragment = function(template,
                                                        opt_templateData) {
  return goog.soy.renderAsFragment(template, opt_templateData,
                                   this.getInjectedData_(), this.dom_);
};

/**
 * Renders a Soy template into a single node. If the rendered HTML
 * string represents a single node, then that node is returned.
 * Otherwise, a DIV element is returned containing the rendered nodes.
 * Delegates to {@code goog.soy.renderAsElement}.
 *
 * @param {Function} template The Soy template defining the element's content.
 * @param {Object=} opt_templateData The data for the template.
 * @return {!Element} Rendered template contents, wrapped in a parent DIV
 *     element if necessary.
 */
goog.soy.Renderer.prototype.renderAsElement = function(template,
                                                       opt_templateData) {
  return goog.soy.renderAsElement(template, opt_templateData,
                                  this.getInjectedData_(), this.dom_);
};

/**
 * Renders a Soy template and then set the output string as the
 * innerHTML of the given element. Delegates to {@code goog.soy.renderElement}.
 *
 * @param {Element} element The element whose content we are rendering.
 * @param {Function} template The Soy template defining the element's content.
 * @param {Object=} opt_templateData The data for the template.
 */
goog.soy.Renderer.prototype.renderElement = function(element, template,
                                                     opt_templateData) {
  goog.soy.renderElement(
      element, template, opt_templateData, this.getInjectedData_());
};

/**
 * Renders a Soy template and returns the output string.
 * If the template is strict, it must be of kind HTML. To render strict
 * templates of other kinds, use {@code renderText} (for {@code kind="text"}) or
 * {@code renderStrict}.
 *
 * @param {Function} template The Soy template defining the element's content.
 * @param {Object=} opt_templateData The data for the template.
 * @return {string} The return value of rendering the template directly.
 */
goog.soy.Renderer.prototype.render = function(template, opt_templateData) {
  var result = template(
      opt_templateData || {}, undefined, this.getInjectedData_());
  goog.asserts.assert(!(result instanceof goog.soy.data.SanitizedContent) ||
      result.contentKind === goog.soy.data.SanitizedContentKind.HTML,
      'render was called with a strict template of kind other than "html"' +
          ' (consider using renderText or renderStrict)');
  return String(result);
};

/**
 * Renders a strict Soy template of kind="text" and returns the output string.
 * It is an error to use renderText on non-strict templates, or strict templates
 * of kinds other than "text".
 *
 * @param {Function} template The Soy template defining the element's content.
 * @param {Object=} opt_templateData The data for the template.
 * @return {string} The return value of rendering the template directly.
 */
goog.soy.Renderer.prototype.renderText = function(template, opt_templateData) {
  var result = template(
      opt_templateData || {}, undefined, this.getInjectedData_());
  goog.asserts.assertInstanceof(result, goog.soy.data.SanitizedContent,
      'renderText cannot be called on a non-strict soy template');
  goog.asserts.assert(
      result.contentKind === goog.soy.data.SanitizedContentKind.TEXT,
      'renderText was called with a template of kind other than "text"');
  return String(result);
};

/**
 * Renders a strict Soy template and returns the output SanitizedContent object.
 *
 * @param {function(Object.<string, *>, (null|undefined), Object.<string, *>):
 *     RETURN_TYPE} template The Soy template to render.
 * @param {Object=} opt_templateData The data for the template.
 * @param {goog.soy.data.SanitizedContentKind=} opt_kind The output kind to
 *     assert. If null, the template must be of kind="html" (i.e., opt_kind
 *     defaults to goog.soy.data.SanitizedContentKind.HTML).
 * @return {RETURN_TYPE} The SanitizedContent object. This return type is
 *     generic based on the return type of the template, such as
 *     soy.SanitizedHtml.
 * @template RETURN_TYPE
 */
goog.soy.Renderer.prototype.renderStrict = function(
    template, opt_templateData, opt_kind) {
  var result = template(
      opt_templateData || {}, undefined, this.getInjectedData_());
  goog.asserts.assertInstanceof(result, goog.soy.data.SanitizedContent,
      'renderStrict cannot be called on a non-strict soy template');
  goog.asserts.assert(
      result.contentKind ===
          (opt_kind || goog.soy.data.SanitizedContentKind.HTML),
      'renderStrict was called with the wrong kind of template');
  return result;
};

/**
 * Creates the injectedParams map if necessary and calls the configuration
 * service to prepopulate it.
 * @return {Object} The injected params.
 * @private
 */
goog.soy.Renderer.prototype.getInjectedData_ = function() {
  return this.supplier_ ? this.supplier_.getData() : {};
};

/**
 * An interface for a supplier that provides Soy injected data.
 * @interface
 */
goog.soy.InjectedDataSupplier = function() {};

/**
 * Gets the injected data. Implementation may assume that
 * {@code goog.soy.Renderer} will treat the returned data as
 * immutable.  The renderer will call this every time one of its
 * {@code render*} methods is called.
 * @return {Object} A key-value pair representing the injected data.
 */
goog.soy.InjectedDataSupplier.prototype.getData = function() {};
<commit_msg><commit_after>// Copyright 2010 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview Provides a soy renderer that allows registration of
 * injected data ("globals") that will be passed into the rendered
 * templates.
 *
 * There is also an interface {@link goog.soy.InjectedDataSupplier} that
 * user should implement to provide the injected data for a specific
 * application. The injected data format is a JavaScript object:
 *

 * {'dataKey': 'value', 'otherDataKey': 'otherValue'}
 *

 *
 * To use injected data, you need to enable the soy-to-js compiler
 * option {@code --isUsingIjData}. The injected data can then be
 * referred to in any soy templates as part of a magic "ij"
 * parameter. For example, {@code $ij.dataKey} will evaluate to
 * 'value' with the above injected data.
 *
 * @author henrywong@google.com (Henry Wong)
 * @author chrishenry@google.com (Chris Henry)
 */

goog.provide('goog.soy.InjectedDataSupplier');
goog.provide('goog.soy.Renderer');

goog.require('goog.asserts');
goog.require('goog.dom');
goog.require('goog.soy');
goog.require('goog.soy.data.SanitizedContent');
goog.require('goog.soy.data.SanitizedContentKind');

/**
 * Creates a new soy renderer. Note that the renderer will only be
 * guaranteed to work correctly within the document scope provided in
 * the DOM helper.
 *
 * @param {goog.soy.InjectedDataSupplier=} opt_injectedDataSupplier A supplier
 *     that provides an injected data.
 * @param {goog.dom.DomHelper=} opt_domHelper Optional DOM helper;
 *     defaults to that provided by {@code goog.dom.getDomHelper()}.
 * @constructor
 */
goog.soy.Renderer = function(opt_injectedDataSupplier, opt_domHelper) {
  /**
   * @type {goog.dom.DomHelper}
   * @private
   */
  this.dom_ = opt_domHelper || goog.dom.getDomHelper();

  /**
   * @type {goog.soy.InjectedDataSupplier}
   * @private
   */
  this.supplier_ = opt_injectedDataSupplier || null;

  /**
   * Map from template name to the data used to render that template.
   * @type {!goog.soy.Renderer.SavedTemplateRender}
   * @private
   */
  this.savedTemplateRenders_ = [];
};

/**
 * @typedef {Array.<{template: string, data: Object, ijData: Object}>}
 */
goog.soy.Renderer.SavedTemplateRender;

/**
 * Renders a Soy template into a single node or a document fragment.
 * Delegates to {@code goog.soy.renderAsFragment}.
 *
 * @param {Function} template The Soy template defining the element's content.
 * @param {Object=} opt_templateData The data for the template.
 * @return {!Node} The resulting node or document fragment.
 */
goog.soy.Renderer.prototype.renderAsFragment = function(template,
                                                        opt_templateData) {
  this.saveTemplateRender_(template, opt_templateData);
  return goog.soy.renderAsFragment(template, opt_templateData,
                                   this.getInjectedData_(), this.dom_);
};

/**
 * Renders a Soy template into a single node. If the rendered HTML
 * string represents a single node, then that node is returned.
 * Otherwise, a DIV element is returned containing the rendered nodes.
 * Delegates to {@code goog.soy.renderAsElement}.
 *
 * @param {Function} template The Soy template defining the element's content.
 * @param {Object=} opt_templateData The data for the template.
 * @return {!Element} Rendered template contents, wrapped in a parent DIV
 *     element if necessary.
 */
goog.soy.Renderer.prototype.renderAsElement = function(template,
                                                       opt_templateData) {
  return goog.soy.renderAsElement(template, opt_templateData,
                                  this.getInjectedData_(), this.dom_);
};

/**
 * Renders a Soy template and then set the output string as the
 * innerHTML of the given element. Delegates to {@code goog.soy.renderElement}.
 *
 * @param {Element} element The element whose content we are rendering.
 * @param {Function} template The Soy template defining the element's content.
 * @param {Object=} opt_templateData The data for the template.
 */
goog.soy.Renderer.prototype.renderElement = function(element, template,
                                                     opt_templateData) {
  this.saveTemplateRender_(template, opt_templateData);
  goog.soy.renderElement(
      element, template, opt_templateData, this.getInjectedData_());
};

/**
 * Renders a Soy template and returns the output string.
 * If the template is strict, it must be of kind HTML. To render strict
 * templates of other kinds, use {@code renderText} (for {@code kind="text"}) or
 * {@code renderStrict}.
 *
 * @param {Function} template The Soy template defining the element's content.
 * @param {Object=} opt_templateData The data for the template.
 * @return {string} The return value of rendering the template directly.
 */
goog.soy.Renderer.prototype.render = function(template, opt_templateData) {
  var result = template(
      opt_templateData || {}, undefined, this.getInjectedData_());
  goog.asserts.assert(!(result instanceof goog.soy.data.SanitizedContent) ||
      result.contentKind === goog.soy.data.SanitizedContentKind.HTML,
      'render was called with a strict template of kind other than "html"' +
          ' (consider using renderText or renderStrict)');
  this.saveTemplateRender_(template, opt_templateData);
  return String(result);
};

/**
 * Renders a strict Soy template of kind="text" and returns the output string.
 * It is an error to use renderText on non-strict templates, or strict templates
 * of kinds other than "text".
 *
 * @param {Function} template The Soy template defining the element's content.
 * @param {Object=} opt_templateData The data for the template.
 * @return {string} The return value of rendering the template directly.
 */
goog.soy.Renderer.prototype.renderText = function(template, opt_templateData) {
  var result = template(
      opt_templateData || {}, undefined, this.getInjectedData_());
  goog.asserts.assertInstanceof(result, goog.soy.data.SanitizedContent,
      'renderText cannot be called on a non-strict soy template');
  goog.asserts.assert(
      result.contentKind === goog.soy.data.SanitizedContentKind.TEXT,
      'renderText was called with a template of kind other than "text"');
  this.saveTemplateRender_(template, opt_templateData);
  return String(result);
};

/**
 * Renders a strict Soy template and returns the output SanitizedContent object.
 *
 * @param {function(Object.<string, *>, (null|undefined), Object.<string, *>):
 *     RETURN_TYPE} template The Soy template to render.
 * @param {Object=} opt_templateData The data for the template.
 * @param {goog.soy.data.SanitizedContentKind=} opt_kind The output kind to
 *     assert. If null, the template must be of kind="html" (i.e., opt_kind
 *     defaults to goog.soy.data.SanitizedContentKind.HTML).
 * @return {RETURN_TYPE} The SanitizedContent object. This return type is
 *     generic based on the return type of the template, such as
 *     soy.SanitizedHtml.
 * @template RETURN_TYPE
 */
goog.soy.Renderer.prototype.renderStrict = function(
    template, opt_templateData, opt_kind) {
  var result = template(
      opt_templateData || {}, undefined, this.getInjectedData_());
  goog.asserts.assertInstanceof(result, goog.soy.data.SanitizedContent,
      'renderStrict cannot be called on a non-strict soy template');
  goog.asserts.assert(
      result.contentKind ===
          (opt_kind || goog.soy.data.SanitizedContentKind.HTML),
      'renderStrict was called with the wrong kind of template');
  this.saveTemplateRender_(template, opt_templateData);
  return result;
};

/**
 * @return {!goog.soy.Renderer.SavedTemplateRender} Saved template data for
 *     the renders that have happened so far.
 */
goog.soy.Renderer.prototype.getSavedTemplateRenders = function() {
  return this.savedTemplateRenders_;
};

/**
 * Saves information about the current template render for debug purposes.
 * @param {Function} template The Soy template defining the element's content.
 * @param {Object=} opt_templateData The data for the template.
 * @private
 * @suppress {missingProperties} SoyJs compiler adds soyTemplateName to the
 *     template.
 */
goog.soy.Renderer.prototype.saveTemplateRender_ = function(
    template, opt_templateData) {
  if (goog.DEBUG) {
    this.savedTemplateRenders_.push({
      template: template.soyTemplateName,
      data: opt_templateData,
      ijData: this.getInjectedData_()
    });
  }
};

/**
 * Creates the injectedParams map if necessary and calls the configuration
 * service to prepopulate it.
 * @return {Object} The injected params.
 * @private
 */
goog.soy.Renderer.prototype.getInjectedData_ = function() {
  return this.supplier_ ? this.supplier_.getData() : {};
};

/**
 * An interface for a supplier that provides Soy injected data.
 * @interface
 */
goog.soy.InjectedDataSupplier = function() {};

/**
 * Gets the injected data. Implementation may assume that
v * {@code goog.soy.Renderer} will treat the returned data as
 * immutable.  The renderer will call this every time one of its
 * {@code render*} methods is called.
 * @return {Object} A key-value pair representing the injected data.
 */
goog.soy.InjectedDataSupplier.prototype.getData = function() {};
<|endoftext|>


<commit_before>moment.locale("fi");

function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie != "") {
        var cookies = document.cookie.split(";");
        for (var i = 0; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) == (name + "=")) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}
var csrftoken = getCookie("csrftoken");

$.ajaxSetup({
    beforeSend: function(xhr, settings) {
        if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }
    }
});

function switchVisibleContent(elem) {
  $(".content-box").slideUp(); // Hide all content boxes
  $("html, body").animate({ scrollTop: 0 }, "fast"); // Always scroll to top.
  $("#navbar").collapse("hide"); // Hide menu, if visible
  if (elem != "#main-content") {
    $(elem).slideDown();
  }
}

$(document).ready(function() {
  $(".animate-click").each(function () {
    $(this).data("original-bg-color", $(this).css("background-color"));
  });
  $(".animate-click").on("click", function () {
    $(this).stop(true).css("background-color", $(this).data("original-bg-color")).effect("highlight", {color: "#ffffff"}, 500);
  });

});
<commit_msg>Automatically close dialogs after one minute<commit_after>moment.locale("fi");

function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie != "") {
        var cookies = document.cookie.split(";");
        for (var i = 0; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) == (name + "=")) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}
var csrftoken = getCookie("csrftoken");

$.ajaxSetup({
    beforeSend: function(xhr, settings) {
        if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }
    }
});

var switch_visible_content_timeout;
var switch_visible_content_currently_active;

function switchToMainContent() {
  $(switch_visible_content_currently_active).find(".close").trigger("click");
  if (switch_visible_content_timeout) {
    switch_visible_content_timeout = clearTimeout(switch_visible_content_timeout);
  }
}

function switchVisibleContent(elem) {
  if (switch_visible_content_timeout) {
    switch_visible_content_timeout = clearTimeout(switch_visible_content_timeout);
  }
  $(".content-box").slideUp(); // Hide all content boxes
  $("html, body").animate({ scrollTop: 0 }, "fast"); // Always scroll to top.
  $("#navbar").collapse("hide"); // Hide menu, if visible
  if (elem != "#main-content") {
    switch_visible_content_currently_active = elem;
    switch_visible_content_timeout = setTimeout(switchToMainContent, 60 * 1000);
    $(elem).slideDown();
  }
}

$(document).ready(function() {
  $(".animate-click").each(function () {
    $(this).data("original-bg-color", $(this).css("background-color"));
  });
  $(".animate-click").on("click", function () {
    $(this).stop(true).css("background-color", $(this).data("original-bg-color")).effect("highlight", {color: "#ffffff"}, 500);
  });

});
<|endoftext|>


<commit_before>"use strict";
(function(window) {
    var config = {
      silent: false
    }
    var directives = {};

    /**
    * Converts attributes into key-value pairs
    * @param {Node} node
    * @return {Object} Key-Value pairs of Attributes
    */
    var extractAttrs = function(node) {
      var attrs = {};
      if(!node.attributes) return attrs;
      var rawAttrs = node.attributes;
      for(var i = 0; i < rawAttrs.length; i++) {
        attrs[rawAttrs[i].name] = rawAttrs[i].value
      }

      return attrs;
    }

    /**
    * Compiles a template with given data
    * @param {String} template
    * @param {Object} data
    * @return {String} Template with data rendered
    */
    var compileTemplate = function(template, data) {
      var code = template,
          re = /{{([A-Za-z0-9_.\[\]]+)}}/gi;
      code.replace(re, function(match, p) {
        code = code.replace(match, "` + data." + p + " + `");
      });
      var compile = new Function("data", "var out = `" + code + "`; return out");
      return compile(data);
    }

    /**
    * Gets Root Element
    * @param {String} html
    * @return {Node} Root Element
    */
    var getRootElement = function(html) {
      var dummy = document.createElement('div');
      dummy.innerHTML = html;
      return dummy.firstChild;
    }

    function Moon(opts) {
        var _el = opts.el;
        var _data = opts.data;
        var _methods = opts.methods;
        var self = this;
        this.$el = document.querySelector(_el);
        this.components = opts.components;
        this.dom = {type: this.$el.nodeName, children: [], node: this.$el};

        // Change state when $data is changed
        Object.defineProperty(this, '$data', {
            get: function() {
                return _data;
            },
            set: function(value) {
                _data = value;
                this.build(this.dom.children);
            }
        });

        /**
        * Logs a Message
        * @param {String} msg
        */
        this.log = function(msg) {
          if(!config.silent) console.log(msg);
        }

        /**
        * Throws an Error
        * @param {String} msg
        */
        this.error = function(msg) {
          console.log("Moon ERR: " + msg);
        }

        /**
        * Creates an object to be used in a Virtual DOM
        * @param {String} type
        * @param {Array} children
        * @param {String} val
        * @param {Object} props
        * @param {Node} node
        * @return {Object} Object usable in Virtual DOM
        */
        this.createElement = function(type, children, val, props, node) {
          return {type: type, children: children, val: val, props: props, node: node};
        }

        /**
        * Create Elements Recursively For all Children
        * @param {Array} children
        * @return {Array} Array of elements usable in Virtual DOM
        */
        this.recursiveChildren = function(children) {
          var recursiveChildrenArr = [];
          for(var i = 0; i < children.length; i++) {
            var child = children[i];
            recursiveChildrenArr.push(this.createElement(child.nodeName, this.recursiveChildren(child.childNodes), child.textContent, extractAttrs(child), child));
          }
          return recursiveChildrenArr;
        }

        /**
        * Creates Virtual DOM
        * @param {Node} node
        */
        this.createVirtualDOM = function(node) {
          var vdom = this.createElement(node.nodeName, this.recursiveChildren(node.childNodes), node.textContent, extractAttrs(node), node);
          this.dom = vdom;
        }

        /**
        * Turns Custom Components into their Corresponding Templates
        */
        this.componentsToHTML = function() {
          for(var component in this.components) {
            var componentsFound = document.getElementsByTagName(component);
            componentsFound = Array.prototype.slice.call(componentsFound);
            for(var i = 0; i < componentsFound.length; i++) {
              var componentFound = componentsFound[i];
              var componentProps = extractAttrs(componentFound);
              var componentDummy = document.createElement('div');
              componentDummy.innerHTML = this.components[component].template;
              componentDummy = componentDummy.firstChild;

              for(var attr in componentProps) {
                componentDummy.setAttribute(attr, componentProps[attr]);
              }

              componentFound.outerHTML = componentDummy.outerHTML;
            }
          }
        }

        /**
        * Sets Value in Data
        * @param {String} key
        * @param {String} val
        */
        this.set = function(key, val) {
          this.$data[key] = val;
          this.build(this.dom.children);
        }

        /**
        * Gets Value in Data
        * @param {String} key
        * @return {String} Value of key in data
        */
        this.get = function(key) {
          return this.$data[key];
        }

        /**
        * Makes an AJAX Request
        * @param {String} method
        * @param {String} url
        * @param {Object} params
        * @param {Function} cb
        */
        this.ajax = function(method, url, params, cb) {
          var xmlHttp = new XMLHttpRequest();
          method = method.toUpperCase();
          if(typeof params === "function") {
            cb = params;
          }
          var urlParams = "?";
          if(method === "POST") {
            http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            for(var param in params) {
              urlParams += param + "=" + params[param] + "&";
            }
          }
          xmlHttp.onreadystatechange = function() {
          if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
            cb(JSON.parse(xmlHttp.responseText));
          }
          xmlHttp.open(method, url, true);
          xmlHttp.send(method === "POST" ? urlParams : null);
        }

        /**
        * Calls a method
        * @param {String} method
        */
        this.method = function(method) {
          _methods[method]();
        }

        // Default Directives
        directives["m-if"] = function(el, val, vdom) {
          var evaluated = new Function("return " + val);
          if(!evaluated()) {
            el.textContent = "";
          } else {
            el.textContent = compileTemplate(vdom.val, self.$data);
          }
        }

        directives["m-on"] = function(el, val, vdom) {
          var splitVal = val.split(":");
          var eventToCall = splitVal[0];
          var methodToCall = splitVal[1];
          el.addEventListener(eventToCall, function() {
            self.method(methodToCall);
          });
          el.removeAttribute("m-on");
          delete vdom.props["m-on"];
        }

        directives["m-model"] = function(el, val, vdom) {
          el.value = self.get(val);
          el.addEventListener("input", function() {
            self.set(val, el.value);
          });
          el.removeAttribute("m-model");
          delete vdom.props["m-model"];
        }

        directives["m-once"] = function(el, val, vdom) {
          vdom.val = el.textContent;
          for(var child in vdom.children) {
            vdom.children[child].val = compileTemplate(vdom.children[child].val, self.$data);
          }
        }

        // directives["m-for"] = function(el, val, vdom) {
        //   var splitVal = val.split(" in ");
        //   var alias = splitVal[0];
        //   var arr = self.get(splitVal[1]);
        //   var clone = el.cloneNode(true);
        //   var oldVal = vdom.val;
        //   var compilable = vdom.val.replace(new RegExp(alias, "gi"), splitVal[1] + '[0]');
        //   vdom.val = compileTemplate(compilable, self.$data);
        //   el.innerHTML = vdom.val;
        //   for(var i = 1; i < arr.length; i++) {
        //     var newClone = clone.cloneNode(true);
        //     var compilable = oldVal.replace(new RegExp(alias, "gi"), splitVal[1] + '[' + i + ']');
        //     newClone.innerHTML = compileTemplate(compilable, self.$data);
        //     var parent = el.parentNode;
        //     parent.appendChild(newClone);
        //   }
        //   vdom.val = el.textContent;
        //   delete vdom.props["m-for"];
        // }

        /**
        * Builds the DOM With Data
        * @param {Array} children
        */
        this.build = function(children) {
          for(var i = 0; i < children.length; i++) {
            var el = children[i];

            if(el.type === "#text") {
              el.node.textContent = compileTemplate(el.val, this.$data);
            } else if(el.props) {
              for(var prop in el.props) {
                var propVal = el.props[prop];
                var compiledProperty = compileTemplate(propVal, this.$data);
                var directive = directives[prop];
                if(directive) {
                  directive(el.node, compiledProperty, el);
                }

                el.node.setAttribute(prop, compiledProperty);
              }
            }

            this.build(el.children);
          }
        }

        /**
        * Initializes Moon
        */
        this.init = function() {
          this.log("======= Moon =======");
          this.componentsToHTML();
          this.createVirtualDOM(this.$el);
          this.build(this.dom.children);
        }

        // Initialize 🎉
        this.init();
    }

    /**
    * Sets the Configuration of Moon
    * @param {Object} opts
    */
    Moon.config = function(opts) {
      if(opts.silent) {
        config.silent = opts.silent;
      }
    }

    /**
    * Runs an external Plugin
    * @param {Object} plugin
    */
    Moon.use = function(plugin) {
      plugin.init(Moon);
    }

    /**
    * Creates a Directive
    * @param {String} name
    * @param {Function} action
    */
    Moon.directive = function(name, action) {
      directives["m-" + name] = action;
    }

    window.Moon = Moon;
    window.$ = function(el) {
      el = document.querySelectorAll(el);
      return el.length === 1 ? el[0] : el;
    }

})(window);
<commit_msg>use the utility<commit_after>"use strict";
(function(window) {
    var config = {
      silent: false
    }
    var directives = {};

    /**
    * Converts attributes into key-value pairs
    * @param {Node} node
    * @return {Object} Key-Value pairs of Attributes
    */
    var extractAttrs = function(node) {
      var attrs = {};
      if(!node.attributes) return attrs;
      var rawAttrs = node.attributes;
      for(var i = 0; i < rawAttrs.length; i++) {
        attrs[rawAttrs[i].name] = rawAttrs[i].value
      }

      return attrs;
    }

    /**
    * Compiles a template with given data
    * @param {String} template
    * @param {Object} data
    * @return {String} Template with data rendered
    */
    var compileTemplate = function(template, data) {
      var code = template,
          re = /{{([A-Za-z0-9_.\[\]]+)}}/gi;
      code.replace(re, function(match, p) {
        code = code.replace(match, "` + data." + p + " + `");
      });
      var compile = new Function("data", "var out = `" + code + "`; return out");
      return compile(data);
    }

    /**
    * Gets Root Element
    * @param {String} html
    * @return {Node} Root Element
    */
    var getRootElement = function(html) {
      var dummy = document.createElement('div');
      dummy.innerHTML = html;
      return dummy.firstChild;
    }

    function Moon(opts) {
        var _el = opts.el;
        var _data = opts.data;
        var _methods = opts.methods;
        var self = this;
        this.$el = document.querySelector(_el);
        this.components = opts.components;
        this.dom = {type: this.$el.nodeName, children: [], node: this.$el};

        // Change state when $data is changed
        Object.defineProperty(this, '$data', {
            get: function() {
                return _data;
            },
            set: function(value) {
                _data = value;
                this.build(this.dom.children);
            }
        });

        /**
        * Logs a Message
        * @param {String} msg
        */
        this.log = function(msg) {
          if(!config.silent) console.log(msg);
        }

        /**
        * Throws an Error
        * @param {String} msg
        */
        this.error = function(msg) {
          console.log("Moon ERR: " + msg);
        }

        /**
        * Creates an object to be used in a Virtual DOM
        * @param {String} type
        * @param {Array} children
        * @param {String} val
        * @param {Object} props
        * @param {Node} node
        * @return {Object} Object usable in Virtual DOM
        */
        this.createElement = function(type, children, val, props, node) {
          return {type: type, children: children, val: val, props: props, node: node};
        }

        /**
        * Create Elements Recursively For all Children
        * @param {Array} children
        * @return {Array} Array of elements usable in Virtual DOM
        */
        this.recursiveChildren = function(children) {
          var recursiveChildrenArr = [];
          for(var i = 0; i < children.length; i++) {
            var child = children[i];
            recursiveChildrenArr.push(this.createElement(child.nodeName, this.recursiveChildren(child.childNodes), child.textContent, extractAttrs(child), child));
          }
          return recursiveChildrenArr;
        }

        /**
        * Creates Virtual DOM
        * @param {Node} node
        */
        this.createVirtualDOM = function(node) {
          var vdom = this.createElement(node.nodeName, this.recursiveChildren(node.childNodes), node.textContent, extractAttrs(node), node);
          this.dom = vdom;
        }

        /**
        * Turns Custom Components into their Corresponding Templates
        */
        this.componentsToHTML = function() {
          for(var component in this.components) {
            var componentsFound = document.getElementsByTagName(component);
            componentsFound = Array.prototype.slice.call(componentsFound);
            for(var i = 0; i < componentsFound.length; i++) {
              var componentFound = componentsFound[i];
              var componentProps = extractAttrs(componentFound);
              var componentDummy = getRootElement(this.components[component].template);
              for(var attr in componentProps) {
                componentDummy.setAttribute(attr, componentProps[attr]);
              }

              componentFound.outerHTML = componentDummy.outerHTML;
            }
          }
        }

        /**
        * Sets Value in Data
        * @param {String} key
        * @param {String} val
        */
        this.set = function(key, val) {
          this.$data[key] = val;
          this.build(this.dom.children);
        }

        /**
        * Gets Value in Data
        * @param {String} key
        * @return {String} Value of key in data
        */
        this.get = function(key) {
          return this.$data[key];
        }

        /**
        * Makes an AJAX Request
        * @param {String} method
        * @param {String} url
        * @param {Object} params
        * @param {Function} cb
        */
        this.ajax = function(method, url, params, cb) {
          var xmlHttp = new XMLHttpRequest();
          method = method.toUpperCase();
          if(typeof params === "function") {
            cb = params;
          }
          var urlParams = "?";
          if(method === "POST") {
            http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            for(var param in params) {
              urlParams += param + "=" + params[param] + "&";
            }
          }
          xmlHttp.onreadystatechange = function() {
          if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
            cb(JSON.parse(xmlHttp.responseText));
          }
          xmlHttp.open(method, url, true);
          xmlHttp.send(method === "POST" ? urlParams : null);
        }

        /**
        * Calls a method
        * @param {String} method
        */
        this.method = function(method) {
          _methods[method]();
        }

        // Default Directives
        directives["m-if"] = function(el, val, vdom) {
          var evaluated = new Function("return " + val);
          if(!evaluated()) {
            el.textContent = "";
          } else {
            el.textContent = compileTemplate(vdom.val, self.$data);
          }
        }

        directives["m-on"] = function(el, val, vdom) {
          var splitVal = val.split(":");
          var eventToCall = splitVal[0];
          var methodToCall = splitVal[1];
          el.addEventListener(eventToCall, function() {
            self.method(methodToCall);
          });
          el.removeAttribute("m-on");
          delete vdom.props["m-on"];
        }

        directives["m-model"] = function(el, val, vdom) {
          el.value = self.get(val);
          el.addEventListener("input", function() {
            self.set(val, el.value);
          });
          el.removeAttribute("m-model");
          delete vdom.props["m-model"];
        }

        directives["m-once"] = function(el, val, vdom) {
          vdom.val = el.textContent;
          for(var child in vdom.children) {
            vdom.children[child].val = compileTemplate(vdom.children[child].val, self.$data);
          }
        }

        // directives["m-for"] = function(el, val, vdom) {
        //   var splitVal = val.split(" in ");
        //   var alias = splitVal[0];
        //   var arr = self.get(splitVal[1]);
        //   var clone = el.cloneNode(true);
        //   var oldVal = vdom.val;
        //   var compilable = vdom.val.replace(new RegExp(alias, "gi"), splitVal[1] + '[0]');
        //   vdom.val = compileTemplate(compilable, self.$data);
        //   el.innerHTML = vdom.val;
        //   for(var i = 1; i < arr.length; i++) {
        //     var newClone = clone.cloneNode(true);
        //     var compilable = oldVal.replace(new RegExp(alias, "gi"), splitVal[1] + '[' + i + ']');
        //     newClone.innerHTML = compileTemplate(compilable, self.$data);
        //     var parent = el.parentNode;
        //     parent.appendChild(newClone);
        //   }
        //   vdom.val = el.textContent;
        //   delete vdom.props["m-for"];
        // }

        /**
        * Builds the DOM With Data
        * @param {Array} children
        */
        this.build = function(children) {
          for(var i = 0; i < children.length; i++) {
            var el = children[i];

            if(el.type === "#text") {
              el.node.textContent = compileTemplate(el.val, this.$data);
            } else if(el.props) {
              for(var prop in el.props) {
                var propVal = el.props[prop];
                var compiledProperty = compileTemplate(propVal, this.$data);
                var directive = directives[prop];
                if(directive) {
                  directive(el.node, compiledProperty, el);
                }

                el.node.setAttribute(prop, compiledProperty);
              }
            }

            this.build(el.children);
          }
        }

        /**
        * Initializes Moon
        */
        this.init = function() {
          this.log("======= Moon =======");
          this.componentsToHTML();
          this.createVirtualDOM(this.$el);
          this.build(this.dom.children);
        }

        // Initialize 🎉
        this.init();
    }

    /**
    * Sets the Configuration of Moon
    * @param {Object} opts
    */
    Moon.config = function(opts) {
      if(opts.silent) {
        config.silent = opts.silent;
      }
    }

    /**
    * Runs an external Plugin
    * @param {Object} plugin
    */
    Moon.use = function(plugin) {
      plugin.init(Moon);
    }

    /**
    * Creates a Directive
    * @param {String} name
    * @param {Function} action
    */
    Moon.directive = function(name, action) {
      directives["m-" + name] = action;
    }

    window.Moon = Moon;
    window.$ = function(el) {
      el = document.querySelectorAll(el);
      return el.length === 1 ? el[0] : el;
    }

})(window);
<|endoftext|>


<commit_before>import { dmetTable } from '../../extensions/dmet';
import CloudVariable from '../../extensions/CloudVariable';
import _throttle from 'lodash/throttle';

class DataTableSource {
    #id;
    #name;
    #data;
    #object;
    #isCloud = false;
    #cloudDate = null;
    #chart = [];
    #cloudVariable = CloudVariable.getInstance();
    #source;
    modal;
    tab = 'summary';

    constructor(source = {}) {
        const {
            name,
            id = Entry.generateHash(),
            object = null,
            chart,
            data,
            tab = 'summary',
            fields = [],
        } = source;
        this.#name = name;
        this.#id = id;
        this.#object = object;
        this.#source = source;
        this.#data = new dmetTable(source);
        this.#chart = chart || [];
        this.tab = tab;
        // 정지시 data 초기화.
        Entry.addEventListener('stop', () => {
            this.#data.from({
                ...source,
                data: this.#data.origin,
                fields: this.#data.originFields,
            });
        });

        const apply = () => {
            if (this.modal && this.modal.isShow) {
                this.modal.setData({
                    source: {
                        chart: this.chart,
                        fields: this.fields,
                        origin: this.rows,
                        tab: this.tab,
                    },
                });
            }
        };
        this.applyChart = _throttle(apply, 1000);
    }

    get rows() {
        return this.array.map(({ value }) => value);
    }

    get id() {
        return this.#id;
    }

    get name() {
        return this.#name;
    }

    set name(name) {
        this.#name = name;
    }

    get fields() {
        return this.#data.fields;
    }

    get array() {
        const { array } = this.#data;
        return array;
    }

    get chart() {
        return this.#chart;
    }

    get origin() {
        return this.#data.origin;
    }

    setArray({ chart, data, fields, name }) {
        this.#chart = chart;
        this.#name = name;
        this.#source = { ...this.#source, fields, data, name };
        this.#data.from(this.#source);
    }

    getValue(index) {
        return this.#data.getValue(index);
    }

    isExist(index) {
        const isExist = this.getValue(index);
        return !!(isExist === 0 || isExist === null || isExist);
    }

    appendRow(data) {
        return new Promise(async (resolve, reject) => {
            try {
                const appendOp = this.#data.getOperation({ type: 'appendRow', data });
                this.#data.exec(appendOp);
                resolve();
                this.applyChart();
            } catch (e) {
                reject(e);
            }
        });
    }

    appendCol(data) {
        return new Promise(async (resolve, reject) => {
            try {
                const appendOp = this.#data.getOperation({ type: 'appendCol', data });
                this.#data.exec(appendOp);
                resolve();
                this.applyChart();
            } catch (e) {
                reject(e);
            }
        });
    }

    insertRow(index, data) {
        return new Promise(async (resolve, reject) => {
            try {
                const insertOp = this.#data.getOperation({ type: 'insertRow', index, data });
                this.#data.exec(insertOp);
                resolve();
                this.applyChart();
            } catch (e) {
                reject(e);
            }
        });
    }

    insertCol(index, data) {
        return new Promise(async (resolve, reject) => {
            try {
                const insertOp = this.#data.getOperation({ type: 'insertCol', index, data });
                this.#data.exec(insertOp);
                resolve();
                this.applyChart();
            } catch (e) {
                reject(e);
            }
        });
    }

    deleteCol(index) {
        return new Promise(async (resolve, reject) => {
            try {
                const deleteOp = this.#data.getOperation({ type: 'deleteCol', index });
                this.#data.exec(deleteOp);
                resolve();
                this.applyChart();
            } catch (e) {
                reject(e);
            }
        });
    }

    deleteRow(index) {
        return new Promise(async (resolve, reject) => {
            try {
                const deleteOp = this.#data.getOperation({ type: 'deleteRow', index });
                this.#data.exec(deleteOp);
                resolve();
                this.applyChart();
            } catch (e) {
                reject(e);
            }
        });
    }

    replaceValue(index, data) {
        return new Promise(async (resolve, reject) => {
            try {
                const replaceOp = this.#data.getOperation({ type: 'replace', index, data });
                this.#data.exec(replaceOp);
                resolve();
                this.applyChart();
            } catch (e) {
                reject(e);
            }
        });
    }

    toJSON() {
        return {
            _id: this.#data._id,
            id: this.#id,
            project: Entry.projectId,
            fields: this.fields,
            name: this.#name,
            object: this.#object,
            data: this.array,
            origin: this.#data.origin,
            chart: this.#chart,
            isCloud: this.#isCloud,
            cloudDate: this.#cloudDate,
        };
    }
}

export default DataTableSource;
<commit_msg>[#11472] 이슈 처리.<commit_after>import { dmetTable } from '../../extensions/dmet';
import CloudVariable from '../../extensions/CloudVariable';
import _throttle from 'lodash/throttle';

class DataTableSource {
    #id;
    #name;
    #data;
    #object;
    #isCloud = false;
    #cloudDate = null;
    #chart = [];
    #cloudVariable = CloudVariable.getInstance();
    #source;
    modal;
    tab = 'summary';

    constructor(source = {}) {
        const {
            name,
            id = Entry.generateHash(),
            object = null,
            chart,
            data,
            tab = 'summary',
            fields = [],
        } = source;
        this.#name = name;
        this.#id = id;
        this.#object = object;
        this.#source = source;
        this.#data = new dmetTable(source);
        this.#chart = chart || [];
        this.tab = tab;
        // 정지시 data 초기화.
        Entry.addEventListener('stop', () => {
            this.modal = null;
            this.#data.from({
                ...source,
                data: this.#data.origin,
                fields: this.#data.originFields,
            });
        });

        const apply = () => {
            if (this.modal && this.modal.isShow) {
                this.modal.setData({
                    source: {
                        chart: this.chart,
                        fields: this.fields,
                        origin: this.rows,
                        tab: this.tab,
                    },
                });
            }
        };
        this.applyChart = _throttle(apply, 1000);
    }

    get rows() {
        return this.array.map(({ value }) => value);
    }

    get id() {
        return this.#id;
    }

    get name() {
        return this.#name;
    }

    set name(name) {
        this.#name = name;
    }

    get fields() {
        return this.#data.fields;
    }

    get array() {
        const { array } = this.#data;
        return array;
    }

    get chart() {
        return this.#chart;
    }

    get origin() {
        return this.#data.origin;
    }

    setArray({ chart, data, fields, name }) {
        this.#chart = chart;
        this.#name = name;
        this.#source = { ...this.#source, fields, data, name };
        this.#data.from(this.#source);
    }

    getValue(index) {
        return this.#data.getValue(index);
    }

    isExist(index) {
        const isExist = this.getValue(index);
        return !!(isExist === 0 || isExist === null || isExist);
    }

    appendRow(data) {
        return new Promise(async (resolve, reject) => {
            try {
                const appendOp = this.#data.getOperation({ type: 'appendRow', data });
                this.#data.exec(appendOp);
                resolve();
                this.applyChart();
            } catch (e) {
                reject(e);
            }
        });
    }

    appendCol(data) {
        return new Promise(async (resolve, reject) => {
            try {
                const appendOp = this.#data.getOperation({ type: 'appendCol', data });
                this.#data.exec(appendOp);
                resolve();
                this.applyChart();
            } catch (e) {
                reject(e);
            }
        });
    }

    insertRow(index, data) {
        return new Promise(async (resolve, reject) => {
            try {
                const insertOp = this.#data.getOperation({ type: 'insertRow', index, data });
                this.#data.exec(insertOp);
                resolve();
                this.applyChart();
            } catch (e) {
                reject(e);
            }
        });
    }

    insertCol(index, data) {
        return new Promise(async (resolve, reject) => {
            try {
                const insertOp = this.#data.getOperation({ type: 'insertCol', index, data });
                this.#data.exec(insertOp);
                resolve();
                this.applyChart();
            } catch (e) {
                reject(e);
            }
        });
    }

    deleteCol(index) {
        return new Promise(async (resolve, reject) => {
            try {
                const deleteOp = this.#data.getOperation({ type: 'deleteCol', index });
                this.#data.exec(deleteOp);
                resolve();
                this.applyChart();
            } catch (e) {
                reject(e);
            }
        });
    }

    deleteRow(index) {
        return new Promise(async (resolve, reject) => {
            try {
                const deleteOp = this.#data.getOperation({ type: 'deleteRow', index });
                this.#data.exec(deleteOp);
                resolve();
                this.applyChart();
            } catch (e) {
                reject(e);
            }
        });
    }

    replaceValue(index, data) {
        return new Promise(async (resolve, reject) => {
            try {
                const replaceOp = this.#data.getOperation({ type: 'replace', index, data });
                this.#data.exec(replaceOp);
                resolve();
                this.applyChart();
            } catch (e) {
                reject(e);
            }
        });
    }

    toJSON() {
        return {
            _id: this.#data._id,
            id: this.#id,
            project: Entry.projectId,
            fields: this.fields,
            name: this.#name,
            object: this.#object,
            data: this.array,
            origin: this.#data.origin,
            chart: this.#chart,
            isCloud: this.#isCloud,
            cloudDate: this.#cloudDate,
        };
    }
}

export default DataTableSource;
<|endoftext|>


<commit_before>import { getSelectedAlgorithm } from './utils.js';
import {
  secretInput,
  secretBase64Checkbox,
} from '../dom-elements.js';

import log from 'loglevel';
import tippy from 'tippy.js';
import b64u from 'base64url';

export function minSecretLengthCheck(event) {
  const alg = getSelectedAlgorithm();
  if(alg.indexOf('HS') !== 0) {
    log.error(`Secret input tooltip handler for wrong algorithm: ${alg}`);
    return;
  }

  const algBits = parseInt(alg.substr(2));
  const inputBits = secretBase64Checkbox.checked ?
    b64u.decode(secretInput.value).length * 8 :
    Buffer.from(secretInput.value).length * 8;

  if(inputBits < algBits) {
    if(!secretInput._tippy.state.visible) {
      secretInput._tippy.show();
    }
  } else {
    secretInput._tippy.hide();
  }
}

export function setupSecretLengthTooltip() {
  tippy(secretInput, {
    trigger: 'manual',
    placement: 'right',
    arrow: true,
    arrowTransform: 'scale(0.75)',
    size: 'large'
  });
}
<commit_msg>Fix Base64 encoded secret length check<commit_after>import { getSelectedAlgorithm } from "./utils.js";
import { secretInput, secretBase64Checkbox } from "../dom-elements.js";

import log from "loglevel";
import tippy from "tippy.js";
import b64u from "base64url";

export function minSecretLengthCheck(event) {
    const alg = getSelectedAlgorithm();
    if (alg.indexOf("HS") !== 0) {
        log.error(`Secret input tooltip handler for wrong algorithm: ${alg}`);
        return;
    }

    const algBits = parseInt(alg.substr(2));
    const inputBits = secretBase64Checkbox.checked ?
        b64u.toBuffer(secretInput.value).length * 8 :
        Buffer.from(secretInput.value).length * 8;

    if (inputBits < algBits) {
        if (!secretInput._tippy.state.visible) {
            secretInput._tippy.show();
        }
    } else {
        secretInput._tippy.hide();
    }
}

export function setupSecretLengthTooltip() {
    tippy(secretInput, {
        trigger: "manual",
        placement: "right",
        arrow: true,
        arrowTransform: "scale(0.75)",
        size: "large",
    });
}<|endoftext|>


<commit_before>"use strict";
(function(window) {
    function Moon(opts) {
        var _el = opts.el;
        var _data = opts.data;
        var _methods = opts.methods;
        var directives = {};
        this.$el = document.getElementById(_el);
        this.components = opts.components;
        this.dom = {type: this.$el.nodeName, children: [], node: this.$el};

        // Change state when $data is changed
        Object.defineProperty(this, '$data', {
            get: function() {
                return _data;
            },
            set: function(value) {
                _data = value;
                this.build(this.dom.children);
            }
        });

        // Utility: Raw Attributes -> Key Value Pairs
        var extractAttrs = function(node) {
          var attrs = {};
          if(!node.attributes) return attrs;
          var rawAttrs = node.attributes;
          for(var i = 0; i < rawAttrs.length; i++) {
            attrs[rawAttrs[i].name] = rawAttrs[i].value
          }

          return attrs;
        }

        // Utility: Compile a template and return html
        var compileTemplate = function(template, data) {
          var code = template,
              re = /{{([.]?\w+)}}/gi;
          code.replace(re, function(match, p) {
            code = code.replace(match, "` + data." + p + " + `");
          });
          var compile = new Function("data", "var out = `" + code + "`; return out");
          return compile(data);
        }

        // Utility: Create Elements Recursively For all Children
        this.recursiveChildren = function(children) {
          var recursiveChildrenArr = [];
          for(var i = 0; i < children.length; i++) {
            var child = children[i];
            recursiveChildrenArr.push(this.createElement(child.nodeName, this.recursiveChildren(child.childNodes), child.textContent, extractAttrs(child), child));
          }
          return recursiveChildrenArr;
        }

        // Utility: Create Virtual DOM Instance
        this.createVirtualDOM = function(node) {
          var vdom = this.createElement(node.nodeName, this.recursiveChildren(node.childNodes), node.textContent, extractAttrs(node), node);
          this.dom = vdom;
        }

        // Build the DOM with $data
        this.build = function(children) {
          for(var i = 0; i < children.length; i++) {
            var el = children[i];

            if(el.type === "#text") {
              el.node.textContent = compileTemplate(el.val, this.$data);
            } else {
              for(var prop in el.props) {
                var propVal = el.props[prop];
                var compiledProperty = compileTemplate(propVal, this.$data);
                var directive = directives[prop];
                if(directive) {
                  directive(el.node, compiledProperty);
                }

                el.node.setAttribute(prop, compiledProperty);
              }
            }

            if(this.components[el.type.toLowerCase()]) {
              var component = this.components[el.type.toLowerCase()];
            }

            this.build(el.children);
          }
        }

        // Create Virtual DOM Object from Params
        this.createElement = function(type, children, val, props, node) {
          return {type: type, children: children, val: val, props: props, node: node};
        }

        // Set any value in $data
        this.set = function(key, val) {
          this.$data[key] = val;
          this.build(this.dom.children);
        }

        // Get any value in $data
        this.get = function(key) {
          return this.$data[key];
        }

        // Make AJAX GET/POST requests
        this.ajax = function(method, url, params, cb) {
          var xmlHttp = new XMLHttpRequest();
          method = method.toUpperCase();
          if(typeof params === "function") {
            cb = params;
          }
          var urlParams = "?";
          if(method === "POST") {
            http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            for(var param in params) {
              urlParams += param + "=" + params[param] + "&";
            }
          }
          xmlHttp.onreadystatechange = function() {
          if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
            cb(JSON.parse(xmlHttp.responseText));
          }
          xmlHttp.open(method, url, true);
          xmlHttp.send(method === "POST" ? urlParams : null);
        }

        // Call a method defined in _methods
        this.method = function(method) {
          _methods[method]();
        }

        // Directive Initialization
        this.directive = function(name, action) {
          directives["m-" + name] = action;
          this.build(this.dom.children);
        }

        // Default Directives
        var dirSelf = this;
        directives["m-if"] = function(el, val) {
          var evaluated = new Function("return " + val);
          if(!evaluated) {
            el.textContent = "";
          }
        }

        // Initialize
        this.createVirtualDOM(this.$el);
        this.build(this.dom.children);
    }

    window.Moon = Moon;
    window.$ = function(el) {
      el = document.querySelectorAll(el);
      return el.length === 1 ? el[0] : el;
    }

})(window);
<commit_msg>set template and html<commit_after>"use strict";
(function(window) {
    function Moon(opts) {
        var _el = opts.el;
        var _data = opts.data;
        var _methods = opts.methods;
        var directives = {};
        this.$el = document.getElementById(_el);
        this.components = opts.components;
        this.dom = {type: this.$el.nodeName, children: [], node: this.$el};

        // Change state when $data is changed
        Object.defineProperty(this, '$data', {
            get: function() {
                return _data;
            },
            set: function(value) {
                _data = value;
                this.build(this.dom.children);
            }
        });

        // Utility: Raw Attributes -> Key Value Pairs
        var extractAttrs = function(node) {
          var attrs = {};
          if(!node.attributes) return attrs;
          var rawAttrs = node.attributes;
          for(var i = 0; i < rawAttrs.length; i++) {
            attrs[rawAttrs[i].name] = rawAttrs[i].value
          }

          return attrs;
        }

        // Utility: Compile a template and return html
        var compileTemplate = function(template, data) {
          var code = template,
              re = /{{([.]?\w+)}}/gi;
          code.replace(re, function(match, p) {
            code = code.replace(match, "` + data." + p + " + `");
          });
          var compile = new Function("data", "var out = `" + code + "`; return out");
          return compile(data);
        }

        // Utility: Create Elements Recursively For all Children
        this.recursiveChildren = function(children) {
          var recursiveChildrenArr = [];
          for(var i = 0; i < children.length; i++) {
            var child = children[i];
            recursiveChildrenArr.push(this.createElement(child.nodeName, this.recursiveChildren(child.childNodes), child.textContent, extractAttrs(child), child));
          }
          return recursiveChildrenArr;
        }

        // Utility: Create Virtual DOM Instance
        this.createVirtualDOM = function(node) {
          var vdom = this.createElement(node.nodeName, this.recursiveChildren(node.childNodes), node.textContent, extractAttrs(node), node);
          this.dom = vdom;
        }

        // Build the DOM with $data
        this.build = function(children) {
          for(var i = 0; i < children.length; i++) {
            var el = children[i];

            if(el.type === "#text") {
              el.node.textContent = compileTemplate(el.val, this.$data);
            } else {
              for(var prop in el.props) {
                var propVal = el.props[prop];
                var compiledProperty = compileTemplate(propVal, this.$data);
                var directive = directives[prop];
                if(directive) {
                  directive(el.node, compiledProperty);
                }

                el.node.setAttribute(prop, compiledProperty);
              }
            }

            if(this.components[el.type.toLowerCase()]) {
              var component = this.components[el.type.toLowerCase()];
              el.innerHTML = component.template;
              this.build(el.children);
            }

            this.build(el.children);
          }
        }

        // Create Virtual DOM Object from Params
        this.createElement = function(type, children, val, props, node) {
          return {type: type, children: children, val: val, props: props, node: node};
        }

        // Set any value in $data
        this.set = function(key, val) {
          this.$data[key] = val;
          this.build(this.dom.children);
        }

        // Get any value in $data
        this.get = function(key) {
          return this.$data[key];
        }

        // Make AJAX GET/POST requests
        this.ajax = function(method, url, params, cb) {
          var xmlHttp = new XMLHttpRequest();
          method = method.toUpperCase();
          if(typeof params === "function") {
            cb = params;
          }
          var urlParams = "?";
          if(method === "POST") {
            http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            for(var param in params) {
              urlParams += param + "=" + params[param] + "&";
            }
          }
          xmlHttp.onreadystatechange = function() {
          if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
            cb(JSON.parse(xmlHttp.responseText));
          }
          xmlHttp.open(method, url, true);
          xmlHttp.send(method === "POST" ? urlParams : null);
        }

        // Call a method defined in _methods
        this.method = function(method) {
          _methods[method]();
        }

        // Directive Initialization
        this.directive = function(name, action) {
          directives["m-" + name] = action;
          this.build(this.dom.children);
        }

        // Default Directives
        var dirSelf = this;
        directives["m-if"] = function(el, val) {
          var evaluated = new Function("return " + val);
          if(!evaluated) {
            el.textContent = "";
          }
        }

        // Initialize
        this.createVirtualDOM(this.$el);
        this.build(this.dom.children);
    }

    window.Moon = Moon;
    window.$ = function(el) {
      el = document.querySelectorAll(el);
      return el.length === 1 ? el[0] : el;
    }

})(window);
<|endoftext|>


<commit_before>// $Revision$

Ensembl.Panel.MultiSelector = Ensembl.Panel.extend({
  constructor: function (id, params) {
    this.base(id);
    this.urlParam = params.urlParam;

    Ensembl.EventManager.register('updateConfiguration', this, this.updateSelection);
    Ensembl.EventManager.register('modalPanelResize', this, this.style);
  },

  init: function () {
    var myself = this;

    this.base();

    this.initialSelection = '';
    this.selection = [];

    this.elLk.content = $('.modal_wrapper', this.el);
    this.elLk.list = $('.multi_selector_list', this.elLk.content);

    var ul = $('ul', this.elLk.list);
    var spans = $('span', ul)

    this.elLk.spans = spans.filter(':not(.switch)');
    this.elLk.form = $('form', this.elLk.content);
    this.elLk.included = ul.filter('.included');
    this.elLk.excluded = ul.filter('.excluded');

    this.setSelection(true);

    this.elLk.included.sortable({
      containment: myself.elLk.included.parent(),
      stop: function () { myself.setSelection(); }
    });

    this.buttonWidth = spans.filter('.switch').click(function () {
      var li = $(this).parent();

      if (li.parent().hasClass('included')) {
        var excluded = $('li', myself.elLk.excluded);
        var i = excluded.length;

        while (i--) {
          if ($(excluded[i]).text() < li.text()) {
            $(excluded[i]).after(li);
            break;
          }
        }

        // item to be added is closer to the start of the alphabet than anything in the excluded list
        if (i == -1) {
          myself.elLk.excluded.prepend(li);
        }

        myself.setSelection();

        excluded = null;
      } else {
        myself.elLk.included.append(li);
        myself.selection.push(li.attr('className'));
      }

      li = null;
    }).width();

    this.style();

    ul = null;
  },

  style: function () {
    var width = 0;

    this.elLk.spans.each(function () {
      var w = $(this).width();

      if (w > width) {
        width = w;
      }
    });

    this.elLk.list.width('');
    this.elLk.list.width(this.elLk.list.width() < width + this.buttonWidth ? '100%' : '');
  },

  setSelection: function (init) {
    this.selection = $.map($('li', this.elLk.included), function (li, i) {
      return li.className;
    });

    if (init === true) {
      this.initialSelection = this.selection.join(',');
    }
  },

  updateSelection: function () {
    var params = [];
    var i;

    for (i = 0; i < this.selection.length; i++) {
      params.push(this.urlParam + (i + 1) + '=' + this.selection[i]);
    }

    if (this.selection.join(',') != this.initialSelection) {
      Ensembl.redirect(this.elLk.form.attr('action') + '?' + Ensembl.cleanURL(this.elLk.form.serialize() + ';' + params.join(';')));
    }

    return true;
  }
});<commit_msg>fix styling<commit_after>// $Revision$

Ensembl.Panel.MultiSelector = Ensembl.Panel.extend({
  constructor: function (id, params) {
    this.base(id);
    this.urlParam = params.urlParam;

    Ensembl.EventManager.register('updateConfiguration', this, this.updateSelection);
    Ensembl.EventManager.register('modalPanelResize', this, this.style);
  },

  init: function () {
    var myself = this;

    this.base();

    this.initialSelection = '';
    this.selection = [];

    this.elLk.content = $('.modal_wrapper', this.el);
    this.elLk.list = $('.multi_selector_list', this.elLk.content);

    var ul = $('ul', this.elLk.list);
    var spans = $('span', ul)

    this.elLk.spans = spans.filter(':not(.switch)');
    this.elLk.form = $('form', this.elLk.content);
    this.elLk.included = ul.filter('.included');
    this.elLk.excluded = ul.filter('.excluded');

    this.setSelection(true);

    this.elLk.included.sortable({
      containment: myself.elLk.included.parent(),
      stop: function () { myself.setSelection(); }
    });

    this.buttonWidth = spans.filter('.switch').click(function () {
      var li = $(this).parent();

      if (li.parent().hasClass('included')) {
        var excluded = $('li', myself.elLk.excluded);
        var i = excluded.length;

        while (i--) {
          if ($(excluded[i]).text() < li.text()) {
            $(excluded[i]).after(li);
            break;
          }
        }

        // item to be added is closer to the start of the alphabet than anything in the excluded list
        if (i == -1) {
          myself.elLk.excluded.prepend(li);
        }

        myself.setSelection();

        excluded = null;
      } else {
        myself.elLk.included.append(li);
        myself.selection.push(li.attr('className'));
      }

      li = null;
    }).width();

    this.style();

    ul = null;
  },

  style: function () {
    var width = 0;

    this.elLk.spans.each(function () {
      var w = $(this).width();

      if (w > width) {
        width = w;
      }
    });

    this.elLk.list.width('');
    this.elLk.list.width(this.elLk.list.width() <= width + this.buttonWidth ? '100%' : '');
  },

  setSelection: function (init) {
    this.selection = $.map($('li', this.elLk.included), function (li, i) {
      return li.className;
    });

    if (init === true) {
      this.initialSelection = this.selection.join(',');
    }
  },

  updateSelection: function () {
    var params = [];
    var i;

    for (i = 0; i < this.selection.length; i++) {
      params.push(this.urlParam + (i + 1) + '=' + this.selection[i]);
    }

    if (this.selection.join(',') != this.initialSelection) {
      Ensembl.redirect(this.elLk.form.attr('action') + '?' + Ensembl.cleanURL(this.elLk.form.serialize() + ';' + params.join(';')));
    }

    return true;
  }
});<|endoftext|>