<commit_before>define(['js/ui/View', 'js/core/Bindable', 'js/core/List', 'js/data/Collection', 'underscore'], function (View, _) {

    /***
     * defines an ItemsView which can show parts of data
     */
    return View.inherit('js.ui.VirtualScrollView', {
        defaults: {
            scrollTop: 0,
            scrollLeft: 0,
            updateHeightPolicy: 'in',
            updateWidthPolicy: 'in',
            componentClass: 'scroll-container',
            vertical: true,
            horizontal: false,
            mouseTracking: false
        },
        ctor: function () {
            this.callBase();

            this.$mouseWheelMult = 1;

            // TODO: put this in stage or somewhere else
            var userAgent = this.get(this.$stage.$window, "navigator.userAgent");
            if (userAgent) {
                this.$isChrome = userAgent.toLowerCase().indexOf('chrome') > -1;
                this.$isFirefox = userAgent.toLowerCase().indexOf('firefox') > -1;
                if (this.$isChrome) {
                    this.$mouseWheelMult = 0.1;
                }

            }

            this.$speed = {x: 0, y: 0};
            this.$currentPos = {x: 0, y: 0};
            this.$newPos = {x: 0, y: 0};
            this.$mousePos = {x: 0, y: 0};
            this.$trackedPos = {x: 0, y: 0};
            this.$isPositiv = {x: false, y: false};
            this.$isOutOfBounce = {x: false, y: false};
            this.$mult = {x: 0, y: 0};
            this.$delta = {width: 0, height: 0};
            this.$isMouseDown = false;
            this.$isScrolling = false;
            this.$t = (new Date()).getTime();
            this.$currentT = {x: 0, y: 0};
            this.$keepInBounceInterval = null;
            this.$trackSpeedInterval = null;
            this.$speedInterval = {x: null, y: null};
            this.$propertyMap = {
                x: "offsetWidth",
                y: "offsetHeight"
            };
            this.$axisScrollMap = {
                x: 'scrollLeft',
                y: 'scrollTop'
            };
            this.$fixAxis = {x: false, y: false};
            this.$transformProperty = null;
            this.$blockMouseWheelTimeout = null;
            this.$blockMouseWheel = false;
        },
        _getTransformProperty: function getTransformProperty(element) {
            // Note that in some versions of IE9 it is critical that
            // msTransform appear in this list before MozTransform
            var properties = [
                'transform',
                'WebkitTransform',
                'msTransform',
                'MozTransform',
                'OTransform'
            ];
            var p;
            while (p = properties.shift()) {
                if (typeof element.style[p] !== 'undefined') {
                    return p;
                }
            }
            return false;
        },
        _startTracking: function (x, y) {
            if (this.$speedInterval.x) {
                clearInterval(this.$speedInterval.x);
            }
            if (this.$speedInterval.y) {
                clearInterval(this.$speedInterval.y);
            }

            this.$t = new Date().getTime();
            this.$mousePos.x = x;
            this.$mousePos.y = y;

            this.$isMouseDown = true;
        },
        _initSpeedInterval: function (axis, dt) {
            if (this.$speedInterval[axis]) {
                clearInterval(this.$speedInterval[axis]);
            }

            this.$speed[axis] = (this.$trackedPos[axis] - this.$newPos[axis]) / dt;

            if (this.$speed[axis] !== 0) {

                var sub = this.$speed[axis] * 0.02;
                var d;
                this.$isPositiv[axis] = this.$speed[axis] >= 0;

                var self = this;
                this.$speedInterval[axis] = setInterval(function () {
                    if (self.$isOutOfBounce[axis] || self.$isPositiv[axis] && self.$speed[axis] <= 0 || !self.$isPositiv[axis] && self.$speed[axis] >= 0) {
                        clearInterval(self.$speedInterval[axis]);
                    }
                    d = (self.$speed[axis] * ((new Date().getTime()) - self.$currentT[axis]));
                    if (axis == "x") {
                        self._moveBy(d, 0);
                    } else {
                        self._moveBy(0, d);
                    }

                    self.$speed[axis] = self.$speed[axis] - sub;

                    self.$currentT[axis] = new Date().getTime();
                }, 1);
            }
        },
        _stopTracking: function () {
            this.$isMouseDown = false;

            this.$currentT.x = this.$currentT.y = new Date().getTime();

            var dt = this.$currentT.x - this.$t;

            if (this.$.horizontal) {
                this._initSpeedInterval("x", dt);
            }

            if (this.$.vertical) {
                this._initSpeedInterval("y", dt);
            }
        },
        _getScrollContainer: function () {
            var scrollContainer = this.get('$scrollContainer');
            if (!scrollContainer) {
                throw "implement _getScrollContainer or set cid='$scrollContainer'";
            }
            return scrollContainer;
        },
        render: function () {
            var el = this.callBase();
            this.$scrollPane = this._getScrollContainer();
            // this.$scrollPane = el.childNodes[0];

            this.$transformProperty = this._getTransformProperty(el);

            var self = this;

            var spanMap = this.$propertyMap;
            var delta;
            var keepInBounce = function (axis) {
                delta = self.$el[spanMap[axis]] - self.$scrollPane[spanMap[axis]];
                if (delta < 0 && !self.$isMouseDown && !self.$isScrolling && (self.$newPos[axis] > 0 || self.$newPos[axis] < delta)) {
                    self.$isOutOfBounce[axis] = true;
                    self.$mult[axis] = (self.$newPos[axis] > 0 ? -1 : 1);
                    self.$newPos[axis] = self.$newPos[axis] + 0.03 * self.$el[spanMap[axis]] * self.$mult[axis];
                    if (self.$newPos[axis] < 0 && self.$mult[axis] < 0) self.$newPos[axis] = 0;
                    if (self.$newPos[axis] > delta && self.$mult[axis] > 0) self.$newPos[axis] = delta;

                    self.updatePosition(self.$newPos.x, self.$newPos.y);
//                    self._setCssTranslate(self.$newPos.x, self.$newPos.y);
                    self.$currentPos[axis] = self.$newPos[axis];
                } else {
                    self.$isOutOfBounce[axis] = false;
                }
            };

//
            this.$keepInBounceInterval = setInterval(function () {
                if (self.$.horizontal) {
                    keepInBounce("x");
                }
                if (self.$.vertical) {
                    keepInBounce("y");
                }
            }, 20);
//
            this.$trackSpeedInterval = setInterval(function () {
                if (self.$isMouseDown) {
                    self.$t = (new Date().getTime());
                }
                self.$trackedPos.x = self.$newPos.x;
                self.$trackedPos.y = self.$newPos.y;

            }, 100);

            return el;
        },
        _calculateDelta: function (val, axis) {
            if (val === 0 || !this.$isMouseDown) {
                return val;
            }
            var delta = this.$el[this.$propertyMap[axis]] - this.$scrollPane[this.$propertyMap[axis]];

            if (val > 0) {
                if (this.$mousePos[axis] > this.$el[this.$propertyMap[axis]] || delta > 0) {

                    return 0;
                } else if (this.$currentPos[axis] > 0 || this.$currentPos[axis] < delta) {
                    return val * ((this.$el[this.$propertyMap[axis]] - this.$mousePos[axis]) / this.$el[this.$propertyMap[axis]]);
                }

            } else {
                if (this.$mousePos[axis] < 0 || delta > 0) {
                    return 0;
                } else if (this.$currentPos[axis] > 0 || this.$currentPos[axis] < delta) {
                    return val * (( this.$mousePos[axis]) / this.$el[this.$propertyMap[axis]]);
                }
            }

            return val;

        },
        _moveBy: function (dx, dy) {
            var ndx = this._calculateDelta(dx * this.$.horizontal, "x");
            var ndy = this._calculateDelta(dy * this.$.vertical, "y");

            if (Math.abs(dx) > Math.abs(dy)) {
                ndy = 0;
            } else {
                ndx = 0;
            }

            this.$newPos.x = this.$currentPos.x - ndx;
            this.$newPos.y = this.$currentPos.y - ndy;

            this.updatePosition(this.$newPos.x, this.$newPos.y);
//            this._setCssTranslate(this.$newPos.x, this.$newPos.y);

            this.$currentPos.x = this.$newPos.x;
            this.$currentPos.y = this.$newPos.y;
        },
        _onWheel: function (e) {

        },
        _posToCss: function (x, y) {
            return 'translate3d(' + x + "px," + y + "px,0px)";
        },
        updatePosition: function (x, y) {
//            this.set({
//                scrollLeft: x,
//                scrollTop: y
//            });
            this._setCssTranslate(-x, -y);
        },
        _setCssTranslate: function (x, y) {
            if (this.$scrollPane.isRendered()) {
                this.$scrollPane.$el.style[this.$transformProperty] = this._posToCss(x, y);
            }
        },
        _bindDomEvents: function (el) {
            this.callBase();

            var self = this;

            if (el.hasOwnProperty('ontouchstart')) {
                // were on a mobile device

                this.bindDomEvent('touchstart', function (e) {
                    if (e.touches.length == 1) {
                        self._startTracking(e.touches[0].clientX, e.touches[0].clientY);
                        e.preventDefault();
                    }
                });
                this.bindDomEvent('touchmove', function (e) {
                    if (e.touches.length == 1) {
                        if (self.$isMouseDown) {
                            if (self._moveBy(e.touches[0].clientX - self.$mousePos.x, e.touches[0].clientY - self.$mousePos.y)) {
                                e.stopPropagation();
                            }
                            self.$mousePos.x = e.touches[0].clientX;
                            self.$mousePos.y = e.touches[0].clientY;
                        }
                    }
                });
                this.bindDomEvent('touchend', function (e) {
                    self._stopTracking();
                });
            } else {
                if (this.$.mouseTracking) {
                    this.bindDomEvent('mousemove', function (e) {
                        if (self.$isMouseDown) {

                            self._moveBy(e.clientX - self.$mousePos.x, e.clientY - self.$mousePos.y);
                            self.$mousePos.x = e.clientX;
                            self.$mousePos.y = e.clientY;

                            e.preventDefault();
                        }
                    });
                    this.bindDomEvent('mousedown', function (e) {
                        self._startTracking(e.clientX, e.clientY);
                    });
                    this.bindDomEvent('mouseup', function (e) {
                        self._stopTracking();
                    });
                }

                var onWheel = function (e) {
                    e = e || window.event; // for IE

                    var deltaX = 0,
                        deltaY = 0;

                    // check target and scroll
                    if (e.wheelDeltaX) {
                        deltaX = e.wheelDeltaX * 2;
                    }

                    if (e.wheelDeltaY) {
                        deltaY = e.wheelDeltaY * 2;
                    }

                    var delta = e.detail ? e.detail * (-3) : e.wheelDelta;

                    if (e.axis && e.axis == 1) {
                        deltaX = delta * self.$mouseWheelMult;
                    } else {
                        deltaY = delta * self.$mouseWheelMult;
                    }

                    // TODO: fix scrolling out of border
//                            if(self.$isOutOfBounce["y"]){
//                                self.$blockMouseWheel = true;
//                                self.$border = self.$currentPos;
//                            }else if(deltaY < self.$border){
//                                self.$blockMouseWheel = false;
//                            }
                    if (!self.$blockMouseWheel) {
                        self._moveBy(-deltaX, -deltaY);
                    }
                    e.preventDefault();

                };

//                this.bindDomEvent("DOMMouseScroll", onWheel, false);
//                this.bindDomEvent("mousewheel", onWheel, false);
            }

        }
    });
});
<commit_msg>removed named function expression<commit_after>define(['js/ui/View', 'js/core/Bindable', 'js/core/List', 'js/data/Collection', 'underscore'], function (View, _) {

    /***
     * defines an ItemsView which can show parts of data
     */
    return View.inherit('js.ui.VirtualScrollView', {
        defaults: {
            scrollTop: 0,
            scrollLeft: 0,
            updateHeightPolicy: 'in',
            updateWidthPolicy: 'in',
            componentClass: 'scroll-container',
            vertical: true,
            horizontal: false,
            mouseTracking: false
        },
        ctor: function () {
            this.callBase();

            this.$mouseWheelMult = 1;

            // TODO: put this in stage or somewhere else
            var userAgent = this.get(this.$stage.$window, "navigator.userAgent");
            if (userAgent) {
                this.$isChrome = userAgent.toLowerCase().indexOf('chrome') > -1;
                this.$isFirefox = userAgent.toLowerCase().indexOf('firefox') > -1;
                if (this.$isChrome) {
                    this.$mouseWheelMult = 0.1;
                }

            }

            this.$speed = {x: 0, y: 0};
            this.$currentPos = {x: 0, y: 0};
            this.$newPos = {x: 0, y: 0};
            this.$mousePos = {x: 0, y: 0};
            this.$trackedPos = {x: 0, y: 0};
            this.$isPositiv = {x: false, y: false};
            this.$isOutOfBounce = {x: false, y: false};
            this.$mult = {x: 0, y: 0};
            this.$delta = {width: 0, height: 0};
            this.$isMouseDown = false;
            this.$isScrolling = false;
            this.$t = (new Date()).getTime();
            this.$currentT = {x: 0, y: 0};
            this.$keepInBounceInterval = null;
            this.$trackSpeedInterval = null;
            this.$speedInterval = {x: null, y: null};
            this.$propertyMap = {
                x: "offsetWidth",
                y: "offsetHeight"
            };
            this.$axisScrollMap = {
                x: 'scrollLeft',
                y: 'scrollTop'
            };
            this.$fixAxis = {x: false, y: false};
            this.$transformProperty = null;
            this.$blockMouseWheelTimeout = null;
            this.$blockMouseWheel = false;
        },
        _getTransformProperty: function (element) {
            // Note that in some versions of IE9 it is critical that
            // msTransform appear in this list before MozTransform
            var properties = [
                'transform',
                'WebkitTransform',
                'msTransform',
                'MozTransform',
                'OTransform'
            ];
            var p;
            while (p = properties.shift()) {
                if (typeof element.style[p] !== 'undefined') {
                    return p;
                }
            }
            return false;
        },
        _startTracking: function (x, y) {
            if (this.$speedInterval.x) {
                clearInterval(this.$speedInterval.x);
            }
            if (this.$speedInterval.y) {
                clearInterval(this.$speedInterval.y);
            }

            this.$t = new Date().getTime();
            this.$mousePos.x = x;
            this.$mousePos.y = y;

            this.$isMouseDown = true;
        },
        _initSpeedInterval: function (axis, dt) {
            if (this.$speedInterval[axis]) {
                clearInterval(this.$speedInterval[axis]);
            }

            this.$speed[axis] = (this.$trackedPos[axis] - this.$newPos[axis]) / dt;

            if (this.$speed[axis] !== 0) {

                var sub = this.$speed[axis] * 0.02;
                var d;
                this.$isPositiv[axis] = this.$speed[axis] >= 0;

                var self = this;
                this.$speedInterval[axis] = setInterval(function () {
                    if (self.$isOutOfBounce[axis] || self.$isPositiv[axis] && self.$speed[axis] <= 0 || !self.$isPositiv[axis] && self.$speed[axis] >= 0) {
                        clearInterval(self.$speedInterval[axis]);
                    }
                    d = (self.$speed[axis] * ((new Date().getTime()) - self.$currentT[axis]));
                    if (axis == "x") {
                        self._moveBy(d, 0);
                    } else {
                        self._moveBy(0, d);
                    }

                    self.$speed[axis] = self.$speed[axis] - sub;

                    self.$currentT[axis] = new Date().getTime();
                }, 1);
            }
        },
        _stopTracking: function () {
            this.$isMouseDown = false;

            this.$currentT.x = this.$currentT.y = new Date().getTime();

            var dt = this.$currentT.x - this.$t;

            if (this.$.horizontal) {
                this._initSpeedInterval("x", dt);
            }

            if (this.$.vertical) {
                this._initSpeedInterval("y", dt);
            }
        },
        _getScrollContainer: function () {
            var scrollContainer = this.get('$scrollContainer');
            if (!scrollContainer) {
                throw "implement _getScrollContainer or set cid='$scrollContainer'";
            }
            return scrollContainer;
        },
        render: function () {
            var el = this.callBase();
            this.$scrollPane = this._getScrollContainer();
            // this.$scrollPane = el.childNodes[0];

            this.$transformProperty = this._getTransformProperty(el);

            var self = this;

            var spanMap = this.$propertyMap;
            var delta;
            var keepInBounce = function (axis) {
                delta = self.$el[spanMap[axis]] - self.$scrollPane[spanMap[axis]];
                if (delta < 0 && !self.$isMouseDown && !self.$isScrolling && (self.$newPos[axis] > 0 || self.$newPos[axis] < delta)) {
                    self.$isOutOfBounce[axis] = true;
                    self.$mult[axis] = (self.$newPos[axis] > 0 ? -1 : 1);
                    self.$newPos[axis] = self.$newPos[axis] + 0.03 * self.$el[spanMap[axis]] * self.$mult[axis];
                    if (self.$newPos[axis] < 0 && self.$mult[axis] < 0) {
                        self.$newPos[axis] = 0;
                    }

                    if (self.$newPos[axis] > delta && self.$mult[axis] > 0) {
                        self.$newPos[axis] = delta;
                    }

                    self.updatePosition(self.$newPos.x, self.$newPos.y);
//                    self._setCssTranslate(self.$newPos.x, self.$newPos.y);
                    self.$currentPos[axis] = self.$newPos[axis];
                } else {
                    self.$isOutOfBounce[axis] = false;
                }
            };

//
            this.$keepInBounceInterval = setInterval(function () {
                if (self.$.horizontal) {
                    keepInBounce("x");
                }
                if (self.$.vertical) {
                    keepInBounce("y");
                }
            }, 20);
//
            this.$trackSpeedInterval = setInterval(function () {
                if (self.$isMouseDown) {
                    self.$t = (new Date().getTime());
                }
                self.$trackedPos.x = self.$newPos.x;
                self.$trackedPos.y = self.$newPos.y;

            }, 100);

            return el;
        },
        _calculateDelta: function (val, axis) {
            if (val === 0 || !this.$isMouseDown) {
                return val;
            }
            var delta = this.$el[this.$propertyMap[axis]] - this.$scrollPane[this.$propertyMap[axis]];

            if (val > 0) {
                if (this.$mousePos[axis] > this.$el[this.$propertyMap[axis]] || delta > 0) {

                    return 0;
                } else if (this.$currentPos[axis] > 0 || this.$currentPos[axis] < delta) {
                    return val * ((this.$el[this.$propertyMap[axis]] - this.$mousePos[axis]) / this.$el[this.$propertyMap[axis]]);
                }

            } else {
                if (this.$mousePos[axis] < 0 || delta > 0) {
                    return 0;
                } else if (this.$currentPos[axis] > 0 || this.$currentPos[axis] < delta) {
                    return val * (( this.$mousePos[axis]) / this.$el[this.$propertyMap[axis]]);
                }
            }

            return val;

        },
        _moveBy: function (dx, dy) {
            var ndx = this._calculateDelta(dx * this.$.horizontal, "x");
            var ndy = this._calculateDelta(dy * this.$.vertical, "y");

            if (Math.abs(dx) > Math.abs(dy)) {
                ndy = 0;
            } else {
                ndx = 0;
            }

            this.$newPos.x = this.$currentPos.x - ndx;
            this.$newPos.y = this.$currentPos.y - ndy;

            this.updatePosition(this.$newPos.x, this.$newPos.y);
//            this._setCssTranslate(this.$newPos.x, this.$newPos.y);

            this.$currentPos.x = this.$newPos.x;
            this.$currentPos.y = this.$newPos.y;
        },
        _onWheel: function (e) {

        },
        _posToCss: function (x, y) {
            return 'translate3d(' + x + "px," + y + "px,0px)";
        },
        updatePosition: function (x, y) {
//            this.set({
//                scrollLeft: x,
//                scrollTop: y
//            });
            this._setCssTranslate(-x, -y);
        },
        _setCssTranslate: function (x, y) {
            if (this.$scrollPane.isRendered()) {
                this.$scrollPane.$el.style[this.$transformProperty] = this._posToCss(x, y);
            }
        },
        _bindDomEvents: function (el) {
            this.callBase();

            var self = this;

            if (el.hasOwnProperty('ontouchstart')) {
                // were on a mobile device

                this.bindDomEvent('touchstart', function (e) {
                    if (e.touches.length == 1) {
                        self._startTracking(e.touches[0].clientX, e.touches[0].clientY);
                        e.preventDefault();
                    }
                });
                this.bindDomEvent('touchmove', function (e) {
                    if (e.touches.length == 1) {
                        if (self.$isMouseDown) {
                            if (self._moveBy(e.touches[0].clientX - self.$mousePos.x, e.touches[0].clientY - self.$mousePos.y)) {
                                e.stopPropagation();
                            }
                            self.$mousePos.x = e.touches[0].clientX;
                            self.$mousePos.y = e.touches[0].clientY;
                        }
                    }
                });
                this.bindDomEvent('touchend', function (e) {
                    self._stopTracking();
                });
            } else {
                if (this.$.mouseTracking) {
                    this.bindDomEvent('mousemove', function (e) {
                        if (self.$isMouseDown) {

                            self._moveBy(e.clientX - self.$mousePos.x, e.clientY - self.$mousePos.y);
                            self.$mousePos.x = e.clientX;
                            self.$mousePos.y = e.clientY;

                            e.preventDefault();
                        }
                    });
                    this.bindDomEvent('mousedown', function (e) {
                        self._startTracking(e.clientX, e.clientY);
                    });
                    this.bindDomEvent('mouseup', function (e) {
                        self._stopTracking();
                    });
                }

                var onWheel = function (e) {
                    e = e || window.event; // for IE

                    var deltaX = 0,
                        deltaY = 0;

                    // check target and scroll
                    if (e.wheelDeltaX) {
                        deltaX = e.wheelDeltaX * 2;
                    }

                    if (e.wheelDeltaY) {
                        deltaY = e.wheelDeltaY * 2;
                    }

                    var delta = e.detail ? e.detail * (-3) : e.wheelDelta;

                    if (e.axis && e.axis == 1) {
                        deltaX = delta * self.$mouseWheelMult;
                    } else {
                        deltaY = delta * self.$mouseWheelMult;
                    }

                    // TODO: fix scrolling out of border
//                            if(self.$isOutOfBounce["y"]){
//                                self.$blockMouseWheel = true;
//                                self.$border = self.$currentPos;
//                            }else if(deltaY < self.$border){
//                                self.$blockMouseWheel = false;
//                            }
                    if (!self.$blockMouseWheel) {
                        self._moveBy(-deltaX, -deltaY);
                    }
                    e.preventDefault();

                };

//                this.bindDomEvent("DOMMouseScroll", onWheel, false);
//                this.bindDomEvent("mousewheel", onWheel, false);
            }

        }
    });
});
<|endoftext|>


<commit_before>import setDate from './set-date'

function setDuration ({
  weeks,
  days,
  hours,
  minutes,
  seconds
}) {
  let formattedString = 'P'
  formattedString += weeks ? `${weeks}W` : ''
  formattedString += days ? `${days}D` : ''
  formattedString += 'T'
  formattedString += hours ? `${hours}H` : ''
  formattedString += minutes ? `${minutes}M` : ''
  formattedString += seconds ? `${seconds}S` : ''

  return formattedString
}

export default function setAlarm(attributes = {}) {
  const {
    action,
    repeat,
    description,
    duration,
    attach,
    trigger,
    summary
  } = attributes

  let formattedString = 'BEGIN:VALARM\r\n'
  formattedString += `ACTION:${action}\r\n`
  formattedString += repeat ? `REPEAT:${repeat}\r\n` : ''
  formattedString += description ? `DESCRIPTION:${description}\r\n` : ''
  formattedString += duration ? `DURATION:${setDuration(duration)}\r\n` : ''
  formattedString += attach ? `ATTACH;FMTTYPE=audio/basic:${attach}\r\n` : ''
  formattedString += trigger ? `TRIGGER;VALUE=DATE-TIME:${setDate(trigger)}\r\n` : ''
  formattedString += summary ? `SUMMARY:${summary}\r\n` : ''
  formattedString += 'END:VALARM\r\n'

  return formattedString
}

// Example:  A duration of 15 days, 5 hours, and 20 seconds would be:

// P15DT5H0M20S

// A duration of 7 weeks would be:

// P7W<commit_msg>Alarm action in upper case fix<commit_after>import setDate from './set-date'

function setDuration ({
  weeks,
  days,
  hours,
  minutes,
  seconds
}) {
  let formattedString = 'P'
  formattedString += weeks ? `${weeks}W` : ''
  formattedString += days ? `${days}D` : ''
  formattedString += 'T'
  formattedString += hours ? `${hours}H` : ''
  formattedString += minutes ? `${minutes}M` : ''
  formattedString += seconds ? `${seconds}S` : ''

  return formattedString
}

function setAction (action){
  return action.toUpperCase();
}

export default function setAlarm(attributes = {}) {
  const {
    action,
    repeat,
    description,
    duration,
    attach,
    trigger,
    summary
  } = attributes

  let formattedString = 'BEGIN:VALARM\r\n'
  formattedString += `ACTION:${setAction(action)}\r\n`
  formattedString += repeat ? `REPEAT:${repeat}\r\n` : ''
  formattedString += description ? `DESCRIPTION:${description}\r\n` : ''
  formattedString += duration ? `DURATION:${setDuration(duration)}\r\n` : ''
  formattedString += attach ? `ATTACH;FMTTYPE=audio/basic:${attach}\r\n` : ''
  formattedString += trigger ? `TRIGGER;VALUE=DATE-TIME:${setDate(trigger)}\r\n` : ''
  formattedString += summary ? `SUMMARY:${summary}\r\n` : ''
  formattedString += 'END:VALARM\r\n'

  return formattedString
}

// Example:  A duration of 15 days, 5 hours, and 20 seconds would be:

// P15DT5H0M20S

// A duration of 7 weeks would be:

// P7W
<|endoftext|>


<commit_before>var bundles = require('../files/browserify_files');

module.exports = {
  task: function () {
    var cfg = {};
    for (var name in bundles) {
      var bundle = bundles[name];

      var options = {
        transform: [],

        // enables watchify when grunt is run with a watch task, e.g. `grunt dev`
        // must be evaluated lazily (using template var) to allow override by setConfig task.
        watch: '<%= env.browserify_watch %>',

        browserifyOptions: {
          debug: true
        },

        plugin: [
          ['browserify-resolutions', ['backbone', 'carto', 'cartodb.js', 'd3', 'jquery', 'jquery-ui', 'torque.js']]
        ]
      };

      if (bundle.options) {
        if (bundle.options.transform) {
          options.transform = options.transform.concat(bundle.options.transform);
        }
      }

      cfg[name] = {
        options: options,
        src: bundle.src,
        dest: bundle.dest || ('<%= assets_dir %>/javascripts/' + name + '.js')
      };
    }

    return cfg;
  }
};
<commit_msg>Use plugin per bundle<commit_after>var bundles = require('../files/browserify_files');

module.exports = {
  task: function () {
    var cfg = {};
    for (var name in bundles) {
      var bundle = bundles[name];

      var options = {
        transform: [],

        // enables watchify when grunt is run with a watch task, e.g. `grunt dev`
        // must be evaluated lazily (using template var) to allow override by setConfig task.
        watch: '<%= env.browserify_watch %>',

        browserifyOptions: {
          debug: true
        }
      };

      if (bundle.options) {
        if (bundle.options.transform) {
          options.transform = options.transform.concat(bundle.options.transform);
        }
        if (bundle.options.plugin) {
          options.plugin = bundle.options.plugin;
        }
      }

      cfg[name] = {
        options: options,
        src: bundle.src,
        dest: bundle.dest || ('<%= assets_dir %>/javascripts/' + name + '.js')
      };
    }

    return cfg;
  }
};
<|endoftext|>


<commit_before>const model = {
  filenameBase: 'timetable_notes_references',
  nonstandard: true,
  schema: [
    {
      name: 'note_id',
      type: 'varchar(255)',
      primary: true
    },
    {
      name: 'timetable_id',
      type: 'varchar(255)',
      index: true
    },
    {
      name: 'route_id',
      type: 'varchar(255)',
      index: true
    },
    {
      name: 'trip_id',
      type: 'varchar(255)',
      index: true
    },
    {
      name: 'stop_id',
      type: 'varchar(255)',
      index: true
    },
    {
      name: 'stop_sequence',
      type: 'integer',
      min: 0,
      index: true
    },
    {
      name: 'show_on_stoptime',
      type: 'integer',
      min: 0,
      max: 1
    }
  ]
};

export default model;
<commit_msg>Fix for timetable_notes_references schema<commit_after>const model = {
  filenameBase: 'timetable_notes_references',
  nonstandard: true,
  schema: [
    {
      name: 'note_id',
      type: 'varchar(255)'
    },
    {
      name: 'timetable_id',
      type: 'varchar(255)',
      index: true
    },
    {
      name: 'route_id',
      type: 'varchar(255)',
      index: true
    },
    {
      name: 'trip_id',
      type: 'varchar(255)',
      index: true
    },
    {
      name: 'stop_id',
      type: 'varchar(255)',
      index: true
    },
    {
      name: 'stop_sequence',
      type: 'integer',
      min: 0,
      index: true
    },
    {
      name: 'show_on_stoptime',
      type: 'integer',
      min: 0,
      max: 1
    }
  ]
};

export default model;
<|endoftext|>


<commit_before>var map = require('map-stream');
var rext = require('replace-ext');
var gutil = require('gulp-util');

const PLUGIN_NAME = 'gulp-twig';

module.exports = function (options) {
    'use strict';
    if (!options) {
        options = {};
    }

    function modifyContents(file, cb) {

        var data = file.data || options.data || {};

        if (file.isNull()) {
            return cb(null, file);
        }

        if (file.isStream()) {
            return cb(new gutil.PluginError(PLUGIN_NAME, "Streaming not supported!"));
        }

        data._file   = file;
        data._target = {
            path: rext(file.path, '.html'),
            relative: rext(file.relative, '.html')
        };

        var Twig = require('twig'),
            twig = Twig.twig,
            twigOpts = {
                path: file.path,
                async: false
            },
            template;

        if (options.debug !== undefined) {
            twigOpts.debug = options.debug;
        }
        if (options.trace !== undefined) {
            twigOpts.trace = options.trace;
        }
        if (options.base !== undefined) {
            twigOpts.base = options.base;
        }
        if (options.cache !== true) {
            Twig.cache(false);
        }

        if (options.functions) {
            options.functions.forEach(function (func) {
                Twig.extendFunction(func.name, func.func);
            });
        }

        if(options.extend) {
            Twig.extend(options.extend);
            delete options.extend;
        }

        template = twig(twigOpts);

        try {
            file.contents = new Buffer(template.render(data));
        }catch(e){
            if (options.errorLogToConsole) {
                gutil.log(PLUGIN_NAME + ' ' + e);
                return cb();
            }

            if (typeof options.onError === 'function') {
                options.onError(e);
                return cb();
            }
            return cb(new gutil.PluginError(PLUGIN_NAME, e));
        }

        file.path = rext(file.path, '.html');
        cb(null, file);
    }

    return map(modifyContents);
};
<commit_msg>Added support for filters.<commit_after>var map = require('map-stream');
var rext = require('replace-ext');
var gutil = require('gulp-util');

const PLUGIN_NAME = 'gulp-twig';

module.exports = function (options) {
    'use strict';
    if (!options) {
        options = {};
    }

    function modifyContents(file, cb) {

        var data = file.data || options.data || {};

        if (file.isNull()) {
            return cb(null, file);
        }

        if (file.isStream()) {
            return cb(new gutil.PluginError(PLUGIN_NAME, "Streaming not supported!"));
        }

        data._file   = file;
        data._target = {
            path: rext(file.path, '.html'),
            relative: rext(file.relative, '.html')
        };

        var Twig = require('twig'),
            twig = Twig.twig,
            twigOpts = {
                path: file.path,
                async: false
            },
            template;

        if (options.debug !== undefined) {
            twigOpts.debug = options.debug;
        }
        if (options.trace !== undefined) {
            twigOpts.trace = options.trace;
        }
        if (options.base !== undefined) {
            twigOpts.base = options.base;
        }
        if (options.cache !== true) {
            Twig.cache(false);
        }

        if (options.functions) {
            options.functions.forEach(function (func) {
                Twig.extendFunction(func.name, func.func);
            });
        }

        if (options.filters) {
            options.filters.forEach(function (filter) {
                Twig.extendFilter(filter.name, filter.func);
            });
        }

        if(options.extend) {
            Twig.extend(options.extend);
            delete options.extend;
        }

        template = twig(twigOpts);

        try {
            file.contents = new Buffer(template.render(data));
        }catch(e){
            if (options.errorLogToConsole) {
                gutil.log(PLUGIN_NAME + ' ' + e);
                return cb();
            }

            if (typeof options.onError === 'function') {
                options.onError(e);
                return cb();
            }
            return cb(new gutil.PluginError(PLUGIN_NAME, e));
        }

        file.path = rext(file.path, '.html');
        cb(null, file);
    }

    return map(modifyContents);
};
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import ThreadStackGraph from './ThreadStackGraph';
import { selectorsForThread, getSelectedThreadIndex } from '../selectors/';
import { getSampleIndexClosestToTime, getStackAsFuncArray } from '../profile-data';
import * as actions from '../actions';

class ProfileThreadHeaderBar extends Component {

  constructor(props) {
    super(props);
    this._onLabelMouseDown = this._onLabelMouseDown.bind(this);
    this._onGraphClick = this._onGraphClick.bind(this);
  }

  _onLabelMouseDown(e) {
    const { changeSelectedThread, threadIndex } = this.props;
    changeSelectedThread(threadIndex);

    // Don't allow clicks on the threads list to steal focus from the tree view.
    e.preventDefault();
  }

  _onGraphClick(time) {
    const { thread, threadIndex, funcStackInfo, changeSelectedThread, changeSelectedFuncStack } = this.props;
    const sampleIndex = getSampleIndexClosestToTime(thread.samples, time);
    const newSelectedStack = thread.samples.stack[sampleIndex];
    const newSelectedFuncStack = newSelectedStack === null ? -1 : funcStackInfo.stackIndexToFuncStackIndex[newSelectedStack];
    changeSelectedThread(threadIndex);
    changeSelectedFuncStack(threadIndex,
      getStackAsFuncArray(newSelectedFuncStack, funcStackInfo.funcStackTable));
  }

  render() {
    const { thread, interval, rangeStart, rangeEnd, funcStackInfo, selectedFuncStack, isSelected, style } = this.props;
    const title = thread.processType ? `${thread.name} [${thread.processType}]` : thread.name;
    return (

{title}

        <ThreadStackGraph interval={interval}
                   thread={thread}
                   className='threadStackGraph'
                   rangeStart={rangeStart}
                   rangeEnd={rangeEnd}
                   funcStackInfo={funcStackInfo}
                   selectedFuncStack={selectedFuncStack}
                   onClick={this._onGraphClick}/>

    );
  }

}

ProfileThreadHeaderBar.propTypes = {
  threadIndex: PropTypes.number.isRequired,
  thread: PropTypes.object.isRequired,
  funcStackInfo: PropTypes.object.isRequired,
  changeSelectedThread: PropTypes.func.isRequired,
  changeSelectedFuncStack: PropTypes.func.isRequired,
  interval: PropTypes.number.isRequired,
  rangeStart: PropTypes.number.isRequired,
  rangeEnd: PropTypes.number.isRequired,
  selectedFuncStack: PropTypes.number.isRequired,
  isSelected: PropTypes.bool.isRequired,
  style: PropTypes.object,
};

export default connect((state, props) => {
  const threadIndex = props.index;
  const selectors = selectorsForThread(threadIndex);
  const selectedThread = getSelectedThreadIndex(state);
  return {
    thread: selectors.getFilteredThread(state),
    funcStackInfo: selectors.getFuncStackInfo(state),
    selectedFuncStack: threadIndex === selectedThread ? selectors.getSelectedFuncStack(state) : -1,
    isSelected: threadIndex === selectedThread,
    threadIndex,
  };
}, actions)(ProfileThreadHeaderBar);
<commit_msg>Fix indentation.<commit_after>import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import ThreadStackGraph from './ThreadStackGraph';
import { selectorsForThread, getSelectedThreadIndex } from '../selectors/';
import { getSampleIndexClosestToTime, getStackAsFuncArray } from '../profile-data';
import * as actions from '../actions';

class ProfileThreadHeaderBar extends Component {

  constructor(props) {
    super(props);
    this._onLabelMouseDown = this._onLabelMouseDown.bind(this);
    this._onGraphClick = this._onGraphClick.bind(this);
  }

  _onLabelMouseDown(e) {
    const { changeSelectedThread, threadIndex } = this.props;
    changeSelectedThread(threadIndex);

    // Don't allow clicks on the threads list to steal focus from the tree view.
    e.preventDefault();
  }

  _onGraphClick(time) {
    const { thread, threadIndex, funcStackInfo, changeSelectedThread, changeSelectedFuncStack } = this.props;
    const sampleIndex = getSampleIndexClosestToTime(thread.samples, time);
    const newSelectedStack = thread.samples.stack[sampleIndex];
    const newSelectedFuncStack = newSelectedStack === null ? -1 : funcStackInfo.stackIndexToFuncStackIndex[newSelectedStack];
    changeSelectedThread(threadIndex);
    changeSelectedFuncStack(threadIndex,
      getStackAsFuncArray(newSelectedFuncStack, funcStackInfo.funcStackTable));
  }

  render() {
    const { thread, interval, rangeStart, rangeEnd, funcStackInfo, selectedFuncStack, isSelected, style } = this.props;
    const title = thread.processType ? `${thread.name} [${thread.processType}]` : thread.name;
    return (

{title}

        <ThreadStackGraph interval={interval}
                          thread={thread}
                          className='threadStackGraph'
                          rangeStart={rangeStart}
                          rangeEnd={rangeEnd}
                          funcStackInfo={funcStackInfo}
                          selectedFuncStack={selectedFuncStack}
                          onClick={this._onGraphClick}/>

    );
  }

}

ProfileThreadHeaderBar.propTypes = {
  threadIndex: PropTypes.number.isRequired,
  thread: PropTypes.object.isRequired,
  funcStackInfo: PropTypes.object.isRequired,
  changeSelectedThread: PropTypes.func.isRequired,
  changeSelectedFuncStack: PropTypes.func.isRequired,
  interval: PropTypes.number.isRequired,
  rangeStart: PropTypes.number.isRequired,
  rangeEnd: PropTypes.number.isRequired,
  selectedFuncStack: PropTypes.number.isRequired,
  isSelected: PropTypes.bool.isRequired,
  style: PropTypes.object,
};

export default connect((state, props) => {
  const threadIndex = props.index;
  const selectors = selectorsForThread(threadIndex);
  const selectedThread = getSelectedThreadIndex(state);
  return {
    thread: selectors.getFilteredThread(state),
    funcStackInfo: selectors.getFuncStackInfo(state),
    selectedFuncStack: threadIndex === selectedThread ? selectors.getSelectedFuncStack(state) : -1,
    isSelected: threadIndex === selectedThread,
    threadIndex,
  };
}, actions)(ProfileThreadHeaderBar);
<|endoftext|>


<commit_before>/*jshint node: true, -W106 */
'use strict';

/*
* Name : page.js
* Module : Page
* Location : /lib/businessTier/page
*
* History :
*
* Version   Date         Programmer         Description
* =========================================================
* 0.0.1     2015-05-19   Matteo Furlan    Initial code
* =========================================================
*/

var PageModel=require('../../dataTier/page/pageModel.js');
//var BarChart=require('../graph/barChart.js');
var LineChart=require('../graph/lineChart.js');
var MapChart=require('../graph/mapChart.js');
//var Table=require('../graph/table.js');

function Page(params,networkHandler,norris){
	if(params===undefined || networkHandler===undefined || norris===undefined ||
		norris._app===undefined || norris._io===undefined ||
		norris._networkHandler===undefined || norris._pageListSocket===undefined ||
		norris._pageList===undefined){
		console.log('Error: 421');
		return;
	}

	var pageM = new PageModel(params);
	if(pageM._ID === undefined) {
		console.log('Error: 421');
		return;
	}

	this._page = pageM;
	this._networkHandler = networkHandler;
	this._norris = norris;
	this._pageNamespace = '/' + params.ID;
	this._pageSocket = this._networkHandler.createSocket(this._pageNamespace);
	this._pageSocket.attachObject(this,'configPage');
	this._graphs = [];

	//add to routing
	this._networkHandler.addPageToRouting(this._pageNamespace);
}

/*Page.prototype.createBarChart = function(params) {
	var graph = new BarChart(params);
	if(graph._ID === undefined) {
		return null;
	}
	this._graphs.push(graph);
	this._page.addGraph(graph._dataGraph);
	return graph;
};
*/
Page.prototype.createLineChart = function(params) {
	/*OLD
	var graph = new LineChart(params);
	if(graph._ID === undefined) {
		return null;
	}
	this._graphs.push(graph);
	this._page.addGraph(graph._dataGraph);
	return graph;*/

	if(params.ID === undefined) {
		return null;
	}
	var graphSocket=this._networkHandler.createSocket(this._pageNamespace+'/'+params.ID);
	var graph = new LineChart(params, this, graphSocket);
	graphSocket.attachObject(graph, 'configGraph');

	this._graphs.push(graph);
	this._page.addGraph(graph._dataLineChart);
	var graphProp=graph.getProperties();

	var data={
		ID: this._page.getProperties().ID,
		graph: {
			ID: graphProp.ID,
			title: graphProp.title,
			type: 'LineChart',
			socketURL: this._networkHandler._routes._baseURL + '/' + this._pageNamespace + '/' + graphProp.ID
		}
	};
	this._pageSocket.sendMessage('insertGraph', data);

	this._networkHandler.addGraphToRouting(this._pageNamespace+'/'+params.ID);
	return graph;

};

Page.prototype.createLineChart = function(params) {
	if(params === undefined || params.ID === undefined) {
		return null;
	}

	for (var key in this._graphs) {
		if(this._graphs[key]._dataLineChart._ID===params.ID){
			return null;
		}
	}
	var graphSocket=this._networkHandler.createSocket(this._pageNamespace+'/'+params.ID);
	var graph = new LineChart(params, this, graphSocket);
	if(graph._dataLineChart === undefined) {
		return null;
	}
	graphSocket.attachObject(graph, 'configGraph');

	this._graphs.push(graph);
	this._page.addGraph(graph._dataLineChart);
	var graphProp=graph.getProperties();

	var data={
		ID: this._page.getProperties().ID,
		graph: {
			ID: graphProp.ID,
			title: graphProp.title,
			type: 'LineChart',
			socketURL: this._networkHandler._routes._baseURL + '/' + this._pageNamespace + '/' + graphProp.ID
		}
	};
	this._pageSocket.sendMessage('insertGraph', data);

	this._networkHandler.addGraphToRouting(this._pageNamespace+'/'+params.ID);
	return graph;
};

Page.prototype.createMapChart = function(params) {
	if(params === undefined || params.ID === undefined) {
		return null;
	}

	for (var key in this._graphs) {
		if(this._graphs[key]._dataMapChart._ID===params.ID){
			return null;
		}
	}
	var graphSocket=this._networkHandler.createSocket(this._pageNamespace+'/'+params.ID);
	var graph = new MapChart(params, this, graphSocket);
	if(graph._dataMapChart === undefined) {
		return null;
	}
	graphSocket.attachObject(graph, 'configGraph');

	this._graphs.push(graph);
	this._page.addGraph(graph._dataMapChart);
	var graphProp=graph.getProperties();

	var data={
		ID: this._page.getProperties().ID,
		graph: {
			ID: graphProp.ID,
			title: graphProp.title,
			type: 'MapChart',
			socketURL: this._networkHandler._routes._baseURL + '/' + this._pageNamespace + '/' + graphProp.ID
		}
	};
	this._pageSocket.sendMessage('insertGraph', data);

	this._networkHandler.addGraphToRouting(this._pageNamespace+'/'+params.ID);
	return graph;
};

/*Page.prototype.createTable = function(params) {
	var graph = new Table(params);
	if(graph._ID === undefined) {
		return null;
	}
	this._graphs.push(graph);
	this._page.addGraph(graph._dataGraph);
	return graph;
};*/

Page.prototype.updateProperties = function(params) {

	if(params!==undefined && params!==null && typeof params==='object') {

		//call the updateProperties method in the Data Tier
		this._page.updateProperties(params);

		//notify the page sockets
		this._pageSocket.sendMessage('updatePageProp', params);

		//notify norris about the page update
		this._norris.pageChanged({eventType: 'updatePage', params: params});
	}
};

Page.prototype.getConfigJSON = function() {
	var ret = {
		properties: this._page.getProperties(),
		data: []
	};
	var PData = this._page.getData();
	for(var i=0; i < PData.length; i++) {
		ret.data.push({ID: PData[i].properties.ID, title: PData[i].properties.title, socketURL: this._networkHandler._routes._baseURL + this._pageNamespace});
	}
	return ret;
};

Page.prototype.graphChanged = function(params) {
	if(params!==undefined && params.eventType!==undefined && params.params!== undefined &&
		typeof params.eventType === 'string' && params.eventType !== '' && typeof params.params === 'object') {
		//notify the page sockets
		this._pageSocket.sendMessage(params.eventType, params.params);
	}

	//notify norris about the graph update
	this._norris.pageChanged(params);
};

module.exports = Page;<commit_msg>fix page<commit_after>/*jshint node: true, -W106 */
'use strict';

/*
* Name : page.js
* Module : Page
* Location : /lib/businessTier/page
*
* History :
*
* Version   Date         Programmer         Description
* =========================================================
* 0.0.1     2015-05-19   Matteo Furlan    Initial code
* =========================================================
*/

var PageModel=require('../../dataTier/page/pageModel.js');
//var BarChart=require('../graph/barChart.js');
var LineChart=require('../graph/lineChart.js');
var MapChart=require('../graph/mapChart.js');
//var Table=require('../graph/table.js');

function Page(params,networkHandler,norris){
	if(params===undefined || networkHandler===undefined || norris===undefined ||
		norris._app===undefined || norris._io===undefined ||
		norris._networkHandler===undefined || norris._pageListSocket===undefined ||
		norris._pageList===undefined){
		console.log('Error: 421');
		return;
	}

	var pageM = new PageModel(params);
	if(pageM._ID === undefined) {
		console.log('Error: 421');
		return;
	}

	this._page = pageM;
	this._networkHandler = networkHandler;
	this._norris = norris;
	this._pageNamespace = '/' + params.ID;
	this._pageSocket = this._networkHandler.createSocket(this._pageNamespace);
	this._pageSocket.attachObject(this,'configPage');
	this._graphs = [];

	//add to routing
	this._networkHandler.addPageToRouting(this._pageNamespace);
}

/*Page.prototype.createBarChart = function(params) {
	var graph = new BarChart(params);
	if(graph._ID === undefined) {
		return null;
	}
	this._graphs.push(graph);
	this._page.addGraph(graph._dataGraph);
	return graph;
};
*/
Page.prototype.createLineChart = function(params) {
	/*OLD
	var graph = new LineChart(params);
	if(graph._ID === undefined) {
		return null;
	}
	this._graphs.push(graph);
	this._page.addGraph(graph._dataGraph);
	return graph;*/

	if(params.ID === undefined) {
		return null;
	}
	var graphSocket=this._networkHandler.createSocket(this._pageNamespace+'/'+params.ID);
	var graph = new LineChart(params, this, graphSocket);
	graphSocket.attachObject(graph, 'configGraph');

	this._graphs.push(graph);
	this._page.addGraph(graph._dataLineChart);
	var graphProp=graph.getProperties();

	var data={
		ID: this._page.getProperties().ID,
		graph: {
			ID: graphProp.ID,
			title: graphProp.title,
			type: 'LineChart',
			socketURL: this._networkHandler._routes._baseURL + '/' + this._pageNamespace + '/' + graphProp.ID
		}
	};
	this._pageSocket.sendMessage('insertGraph', data);

	this._networkHandler.addGraphToRouting(this._pageNamespace+'/'+params.ID);
	return graph;

};

Page.prototype.createLineChart = function(params) {
	if(params === undefined || params.ID === undefined) {
		return null;
	}

	for (var key in this._graphs) {
		if(this._graphs[key].getProperties().ID===params.ID){
			return null;
		}
	}
	var graphSocket=this._networkHandler.createSocket(this._pageNamespace+'/'+params.ID);
	var graph = new LineChart(params, this, graphSocket);
	if(graph._dataLineChart === undefined) {
		return null;
	}
	graphSocket.attachObject(graph, 'configGraph');

	this._graphs.push(graph);
	this._page.addGraph(graph._dataLineChart);
	var graphProp=graph.getProperties();

	var data={
		ID: this._page.getProperties().ID,
		graph: {
			ID: graphProp.ID,
			title: graphProp.title,
			type: 'LineChart',
			socketURL: this._networkHandler._routes._baseURL + '/' + this._pageNamespace + '/' + graphProp.ID
		}
	};
	this._pageSocket.sendMessage('insertGraph', data);

	this._networkHandler.addGraphToRouting(this._pageNamespace+'/'+params.ID);
	return graph;
};

Page.prototype.createMapChart = function(params) {
	if(params === undefined || params.ID === undefined) {
		return null;
	}

	for (var key in this._graphs) {
		if(this._graphs[key].getProperties().ID===params.ID){
			return null;
		}
	}
	var graphSocket=this._networkHandler.createSocket(this._pageNamespace+'/'+params.ID);
	var graph = new MapChart(params, this, graphSocket);
	if(graph._dataMapChart === undefined) {
		return null;
	}
	graphSocket.attachObject(graph, 'configGraph');

	this._graphs.push(graph);
	this._page.addGraph(graph._dataMapChart);
	var graphProp=graph.getProperties();

	var data={
		ID: this._page.getProperties().ID,
		graph: {
			ID: graphProp.ID,
			title: graphProp.title,
			type: 'MapChart',
			socketURL: this._networkHandler._routes._baseURL + '/' + this._pageNamespace + '/' + graphProp.ID
		}
	};
	this._pageSocket.sendMessage('insertGraph', data);

	this._networkHandler.addGraphToRouting(this._pageNamespace+'/'+params.ID);
	return graph;
};

/*Page.prototype.createTable = function(params) {
	var graph = new Table(params);
	if(graph._ID === undefined) {
		return null;
	}
	this._graphs.push(graph);
	this._page.addGraph(graph._dataGraph);
	return graph;
};*/

Page.prototype.updateProperties = function(params) {

	if(params!==undefined && params!==null && typeof params==='object') {

		//call the updateProperties method in the Data Tier
		this._page.updateProperties(params);

		//notify the page sockets
		this._pageSocket.sendMessage('updatePageProp', params);

		//notify norris about the page update
		this._norris.pageChanged({eventType: 'updatePage', params: params});
	}
};

Page.prototype.getConfigJSON = function() {
	var ret = {
		properties: this._page.getProperties(),
		data: []
	};
	var PData = this._page.getData();
	for(var i=0; i < PData.length; i++) {
		ret.data.push({
			ID: PData[i].properties.ID,
			title: PData[i].properties.title,
			socketURL: this._networkHandler._routes._baseURL + this._pageNamespace
		});
	}
	return ret;
};

Page.prototype.graphChanged = function(params) {
	if(params!==undefined && params.eventType!==undefined && params.params!== undefined &&
		typeof params.eventType === 'string' && params.eventType !== '' && typeof params.params === 'object') {
		//notify the page sockets
		this._pageSocket.sendMessage(params.eventType, params.params);
	}

	//notify norris about the graph update
	this._norris.pageChanged(params);
};

module.exports = Page;<|endoftext|>


<commit_before>'use strict';
var chai = require('chai');
chai.Assertion.includeStack = true;
require('chai').should();
var expect = require('chai').expect;
var nodePath = require('path');
var fs = require('fs');

var StringBuilder = require('raptor-strings/StringBuilder');

function testRender(path, data, done, options) {
    var inputPath = nodePath.join(__dirname, path);
    var expectedPath = nodePath.join(__dirname, path + '.expected.html');
    var actualPath = nodePath.join(__dirname, path + '.actual.html');
    options = options || {};
    var compiledPath = nodePath.join(__dirname, path + '.actual.js');

    // var compiler = require('../compiler').createCompiler(inputPath);
    // var src = fs.readFileSync(inputPath, {encoding: 'utf8'});

    // var compiledSrc = compiler.compile(src);
    // fs.writeFileSync(compiledPath, compiledSrc, {encoding: 'utf8'});

    // console.log('\nCompiled (' + inputPath + '):\n---------\n' + compiledSrc);

    var marko = require('../');

    require('../compiler').defaultOptions.checkUpToDate = false;

    var AsyncWriter = marko.AsyncWriter;
    var out = options.out || new AsyncWriter(new StringBuilder());

    marko.render(inputPath, data, out)
        .on('finish', function() {
            var output = out.getOutput();

            fs.writeFileSync(actualPath, output, {encoding: 'utf8'});

            var expected;
            try {
                expected = options.expected || fs.readFileSync(expectedPath, {encoding: 'utf8'});
            }
            catch(e) {
                expected = 'TBD';
                fs.writeFileSync(expectedPath, expected, {encoding: 'utf8'});
            }

            if (output !== expected) {
                throw new Error('Unexpected output for "' + inputPath + '":\nEXPECTED (' + expectedPath + '):\n---------\n' + expected +
                    '\n---------\nACTUAL (' + actualPath + '):\n---------\n' + output + '\n---------');
            }

            done();
        })
        .on('error', done)
        .end();

}

describe('marko/marko' , function() {

    beforeEach(function(done) {
        // for (var k in require.cache) {
        //     if (require.cache.hasOwnProperty(k)) {
        //         delete require.cache[k];
        //     }
        // }

        // require('raptor-logging').configureLoggers({
        //     'marko': 'INFO'
        // });

        done();
    });

    it('should render a simple template', function(done) {
        testRender('test-project/simple.marko', {}, done);
    });

    it('should render a simple template with expressions', function(done) {
        testRender('test-project/hello-dynamic.marko', {name: 'John'}, done);
    });

    it('should render a template with a custom tag', function(done) {
        testRender('test-project/custom-tag.marko', {}, done);
    });

    it("should allow for text replacement", function(done) {
        testRender("test-project/html-templates/text-replacement.marko", {
            zero: 0,
            person: {
                name: "John",
                address: {
                    city: "San Jose",
                    state: "CA",
                    line1: "2065 E. Hamilton Ave.",
                    zip: "95125"
                }
            }
        }, done);
    });

    it("should render simple template with logic", function(done) {
        testRender("test-project/html-templates/simple.marko", {
            message: "Hello World!",
            rootClass: "title",
            colors: ["red", "green", "blue"]
        }, done);
    });

    it("should allow for simple template handlers", function(done) {
        testRender("test-project/html-templates/simple-handlers.marko", {dynamic: "universe"}, done);
    });

    it("should allow for template handlers with nested body content", function(done) {
        testRender("test-project/html-templates/nested-handlers.marko", {showConditionalTab: false}, done);
    });

    it("should allow entity expressions", function(done) {
        testRender("test-project/html-templates/entities.marko", {}, done);
    });

    it("should allow escaped expressions", function(done) {
        testRender("test-project/html-templates/escaped.marko", {}, done);
    });

    it("should allow complex expressions", function(done) {
        testRender("test-project/html-templates/expressions.marko", {}, done);
    });

    it("should allow whitespace to be removed", function(done) {
        testRender("test-project/html-templates/whitespace.marko", {}, done);
    });

    it("should handle whitespace when using expressions", function(done) {
        testRender("test-project/html-templates/whitespace2.marko", {}, done);
    });

    it("should handle whitespace when using expressions", function(done) {
        testRender("test-project/html-templates/whitespace2.marko", {}, done);
    });

    it("should normalize whitespace", function(done) {
        testRender("test-project/html-templates/whitespace3.marko", {}, done);
    });

    it("should handle whitespace correctly for mixed text and element children", function(done) {
        testRender("test-project/html-templates/whitespace-inline-elements.marko", {}, done);
    });

    it("should allow HTML output that is not well-formed XML", function(done) {
        testRender("test-project/html-templates/html.marko", {}, done);
    });

    it("should allow for looping", function(done) {
        testRender("test-project/html-templates/looping.marko", {}, done);
    });

    it.only("should allow for looping (native for-loop)", function(done) {
        testRender("test-project/html-templates/looping-native-for-loop.marko", {}, done);
    });

    it("should allow for looping over properties", function(done) {
        testRender("test-project/html-templates/looping-props.marko", {}, done);
    });

    it("should allow for looping over ranges", function(done) {
        testRender("test-project/html-templates/looping-range.marko", {}, done);
    });

    it("should allow for dynamic attributes", function(done) {
        testRender("test-project/html-templates/attrs.marko", {"myAttrs": {style: "background-color: #FF0000; <test>", "class": "my-div"}}, done);
    });

    it("should allow for <def> functions", function(done) {
        testRender("test-project/html-templates/def.marko", {}, done);
    });

    it("should allow for <with> functions", function(done) {
        testRender("test-project/html-templates/with.marko", {}, done);
    });

    it("should allow for scriptlets", function(done) {
        testRender("test-project/html-templates/scriptlet.marko", {}, done);
    });

    it("should allow for includes", function(done) {
        testRender("test-project/html-templates/include.marko", {}, done);
    });

    it("should allow for <invoke function... />", function(done) {
        testRender("test-project/html-templates/invoke.marko", {}, done);
    });

    it("should allow for require", function(done) {
        testRender("test-project/html-templates/require.marko", {}, done);
    });

    // it("should handle errors correctly", function(done) {

    //     var tryTemplate = function(path, callback) {
    //         try
    //         {
    //             compileAndRender(path, {}, null, true /* invalid */);
    //             callback("", []);
    //         }
    //         catch(e) {

    //             if (!e.errors) {
    //                 logger.error('Error message for template at path "' + path + '": ' + e, e);
    //             }
    //             else {
    //                 console.log('Error message for template at path "' + path + '": ' + e)
    //             }
    //             callback(e.toString(), e.errors);
    //         }
    //     };

    //     tryTemplate("test-project/html-templates/errors.marko", function(message, errors) {
    //         var len = errors ? errors.length : -1;
    //         expect(len).toEqual(25);

    //     });

    // });

    it("should allow static file includes", function(done) {
        testRender("test-project/html-templates/include-resource-static.marko", {}, done);
    });

    it("should allow HTML pages with inline script", function(done) {
        testRender("test-project/html-templates/inline-script.marko", {name: "World"}, done);
    });

    it("should allow CDATA inside templates", function(done) {
        testRender("test-project/html-templates/cdata.marko", {name: "World"}, done);
    });

    // it("should allow type conversion", function(done) {
    //     var TypeConverter = require('raptor/templating/compiler/TypeConverter');
    //     expect(TypeConverter.convert('${entity:special}', "string", true).toString()).toEqual('"&special;"');
    // });

    it("should allow for if...else", function(done) {
        testRender("test-project/html-templates/if-else.marko", {}, done);
    });

    it("should allow for expressions and variables inside JavaScript strings", function(done) {
        testRender("test-project/html-templates/string-expressions.marko", {name: "John", count: 10}, done);
    });

    it("should allow for simple conditionals", function(done) {
        testRender("test-project/html-templates/simple-conditionals.marko", {name: "John", count: 51}, done);
    });

    it("should allow for conditional attributes", function(done) {
        testRender("test-project/html-templates/conditional-attributes.marko", {}, done);
    });

    it("should allow for dynamic attributes to be passed to tag renderer using a custom property name", function(done) {
        testRender("test-project/html-templates/dynamic-attributes.marko", {}, done);
    });

    it("should allow for dynamic attributes to be passed to tag renderer", function(done) {
        testRender("test-project/html-templates/dynamic-attributes2.marko", {}, done);
    });

    it("should allow for dynamic attributes to be passed to tag renderer as part of input object", function(done) {
        testRender("test-project/html-templates/dynamic-attributes3.marko", {}, done);
    });

    it("should allow for nested attributes", function(done) {
        testRender("test-project/html-templates/nested-attrs.marko", {active: true}, done);
    });

    it("should allow for new variables to be created and assigned values", function(done) {
        testRender("test-project/html-templates/var.marko", {active: true}, done);
    });

    it("should handle XML escaping correctly", function(done) {
        testRender("test-project/html-templates/xml-escaping.marko", {name: "<Patrick>", welcome: 'Welcome'}, done);
    });

    it("should allow for a doctype tag and a doctype attribute", function(done) {
        testRender("test-project/html-templates/doctype.marko", {}, done);
    });

    it("should allow for using templates to render custom tags", function(done) {
        testRender("test-project/html-templates/template-as-tag.marko", {title: "My Page Title"}, done);
    });

    it("should allow for caching HTML fragments", function(done) {
        testRender("test-project/html-templates/caching.marko", {}, done);
    });

    it("should escape XML in text node when enabled", function(done) {
        testRender("test-project/html-templates/escape-xml-enabled.marko", {}, done);
    });

    it("should not escape XML in text node when disabled", function(done) {
        testRender("test-project/html-templates/escape-xml-disabled.marko", {}, done);
    });

    it("should allow for attributes with default values", function(done) {
        testRender("test-project/html-templates/default-attributes.marko", {}, done);
    });

    it("should allow for input expressions to be provided to tag handler nodes", function(done) {
        testRender("test-project/html-templates/tag-input-expressions.marko", {name: "Frank", adult: true}, done);
    });

    it("should allow for using layouts", function(done) {
        testRender("test-project/html-templates/layout-use.marko", {}, done);
    });

    it("should work with custom iteration", function(done) {
        testRender("test-project/html-templates/looping-iterator.marko", {
            reverseIterator: function(arrayList, callback){
                var statusVar = {first: 0, last: arrayList.length-1};
                for(var i=arrayList.length-1; i>=0; i--){
                    statusVar.index = i;
                    callback(arrayList[i], statusVar);
                }
            }
        }, done);
    });

    it("should support scanning a directory for tags", function(done) {
        testRender("test-project/html-templates/scanned-tags.marko", {}, done);
    });

    it("should support scanning a directory for tags", function(done) {
        testRender("test-project/html-templates/template-tag-dynamic-attributes.marko", {}, done);
    });

    it("should not escape HTML characters inside script tags", function(done) {
        testRender("test-project/html-templates/script-tag-entities.marko", {
            name: '


<commit_before>//   (c) 2004-2006 by MulchProductions, www.mulchprod.de
//   (c) 2007-2014 by Kajona, www.kajona.de
//       Published under the GNU LGPL v2.1, see /system/licence_lgpl.txt
//       $Id$

if (typeof KAJONA == "undefined") {
	var KAJONA = {
		util: {},
		portal: {
			lang: {}
		},
		admin: {
			lang: {}
		}
	};
}

/*
 * -------------------------------------------------------------------------
 * Global functions
 * -------------------------------------------------------------------------
 */

/*
 * -------------------------------------------------------------------------
 * Portaleditor-specific functions
 * -------------------------------------------------------------------------
 */

KAJONA.admin.portaleditor = {
	objPlaceholderWithElements: {},

    initPortaleditor : function() {
        CKEDITOR_BASEPATH = KAJONA_WEBPATH+"/core/module_system/admin/scripts/ckeditor/";

        KAJONA.admin.loader.loadFile([
            "/core/module_system/admin/scripts/ckeditor/ckeditor.js"
        ], function() {
            //span and other tags are officially not support, nevertheless working...
            CKEDITOR.dtd.$editable.span = 1;
            CKEDITOR.dtd.$editable.a = 1;
            CKEDITOR.dtd.$editable.label = 1;
            CKEDITOR.dtd.$editable.td = 1;
            CKEDITOR.disableAutoInline = true;
            KAJONA.admin.portaleditor.RTE.init();
        });

        // init drag&drop of page elements
        KAJONA.admin.portaleditor.dragndrop.init();
    },

	switchEnabled: function (bitStatus) {
	    var strStatus = bitStatus == true ? 'true' : 'false';
		var url = window.location.href;
		var anchorPos = url.indexOf('#');
		if (anchorPos != -1) {
	    	url = url.substring(0, anchorPos);
		}

	    url = url.replace('&pe=false', '');
	    url = url.replace('&pe=true', '');
	    url = url.replace('?pe=false', '');
	    url = url.replace('?pe=true', '');

	    if(url.indexOf('?') == -1) {
	        window.location.replace(url+'?pe='+strStatus);
	    } else {
	        window.location.replace(url+'&pe='+strStatus);
	    }
	},

	openDialog: function (strUrl) {
		peDialog.setContentIFrame(strUrl);
		peDialog.init();
	},

	closeDialog: function (bitSkipConfirmation) {
        if(!bitSkipConfirmation)
	        var bitClose = confirm(KAJONA.admin.lang["pe_dialog_close_warning"]);
	    if(bitClose || bitSkipConfirmation) {
	    	peDialog.hide();
	    	//reset iframe
	    	peDialog.setContentRaw("");
	    }
	},

	addNewElements: function (strPlaceholder, strPlaceholderName, arrElements) {
		this.objPlaceholderWithElements[strPlaceholder] = {
			placeholderName: strPlaceholderName,
			elements: arrElements
		};
	},

    changeElementData : function(strDataPlaceholder, strDataSystemid, objElementData) {

        console.log("updating container "+strDataSystemid+" at placeholder "+strDataPlaceholder);
        var $objContent = jQuery.parseHTML(objElementData);

        //see if the element is already present, then flip the contents
        if($("div.peElementWrapper[data-systemid='"+strDataSystemid+"']").length) {
            $("div.peElementWrapper[data-systemid='"+strDataSystemid+"']").html($($objContent).closest("div.peElementWrapper[data-systemid="+strDataSystemid+"]").html());
        }
        else {
            //add it as the last element to the placeholder itself
            strDataPlaceholder = strDataPlaceholder.replace(/\|/g, '\\|');
            $("#menuContainer_"+strDataPlaceholder).before($($objContent).closest("div.peElementWrapper[data-systemid="+strDataSystemid+"]"));
        }

    },

    deleteElementData : function(strSystemid) {
        $("div.peElementWrapper[data-systemid='"+strSystemid+"']").remove();
        //and delete the element on the backend
        var data = {
            systemid: strSystemid
        };
        $.post(KAJONA_WEBPATH + '/xml.php?admin=1&module=pages_content&action=deleteElementFinalXML', data, function () {
        }).fail(function() {
                location.reload();
        });
    }
};

KAJONA.admin.portaleditor.RTE = {};
KAJONA.admin.portaleditor.RTE.config = {};
KAJONA.admin.portaleditor.RTE.modifiedFields = {};

KAJONA.admin.portaleditor.RTE.savePage = function () {

    //console. group('savePage');
    $.each(KAJONA.admin.portaleditor.RTE.modifiedFields, function (key, value) {
        var keySplitted = key.split('#');

        var data = {
            systemid: keySplitted[0],
            property: keySplitted[1],
            value: value
        };

        $.post(KAJONA_WEBPATH + '/xml.php?admin=1&module=pages_content&action=updateObjectProperty', data, function () {
            //console. warn('server response');
            //console. log(this.responseText);
        });
    });
    //console. groupEnd('savePage');

    KAJONA.admin.portaleditor.RTE.modifiedFields = {};
};

/**
 * To init the portaleditor, use a syntax like
 *
 * systemid#property#mode
 *
 * whereas systemid is the id of the target record, property the property of the target-object to update.
 * The mode controls the different editor-modes:
 *
 * wysiwyg: full CKEditor
 * plain: limited CKEditor, no linebreaks and only undo/redo buttons
 * textarea: limited CKEditor, linebreaks are allowed, undo/redo buttons
 */
KAJONA.admin.portaleditor.RTE.init = function () {

    $('*[data-kajona-editable]').each(function () {

        var editable = $(this);
        var keySplitted = editable.attr('data-kajona-editable').split('#');

        var strMode = keySplitted[2] ? keySplitted[2] : 'wysiwyg';

        var ckeditorConfig = KAJONA.admin.portaleditor.RTE.config;
        ckeditorConfig.customConfig = 'config_kajona_standard.js';
        ckeditorConfig.toolbar = strMode == 'wysiwyg' ? 'pe_full' : 'pe_lite';
        ckeditorConfig.forcePasteAsPlainText = true;
        ckeditorConfig.kajona_strMode = strMode;
        ckeditorConfig.title = false;
        ckeditorConfig.on = {
            blur: function( event ) {
                var data = event.editor.getData();
                var attr = $(event.editor.element).attr('data-kajona-editable');

                //validate, if injected
s have to be removed. its then up to the
                //portal element to decide if \n should be nl2br()ed.
                if(event.editor.config.kajona_strMode == 'textarea') {
                    data = data.replace("
", "");
                }

                KAJONA.admin.portaleditor.RTE.modifiedFields[attr] = data;

                // save field on blur
                KAJONA.admin.portaleditor.RTE.savePage();
            },
            key: function( event ) {
                //prevent enter in plaintext
                if (event.data.keyCode == 13 && event.editor.config.kajona_strMode == 'plain') {
                    event.cancel();
                }
            }
        };

        //disable drag n drop
        editable.bind('drop drag', function () {
            return false;
        });

        editable.attr("contenteditable", "true");
        CKEDITOR.inline(editable.get(0), ckeditorConfig);
    });

    // warn user if there are unsaved changes when leaving the page
    $(window).on('beforeunload', function () {
        // check if there are unsaved changes
        var unsavedChanges = false;
        $.each(KAJONA.admin.portaleditor.RTE.modifiedFields, function() {
            unsavedChanges = true;
            return false;
        });

        if (unsavedChanges) {
            return KAJONA.admin.lang.pe_rte_unsavedChanges;
        }
    });
};

/**
 * Initialise the drag & drop logic to move page elements
 */
KAJONA.admin.portaleditor.dragndrop = {};
KAJONA.admin.portaleditor.dragndrop.init = function () {

    // checks if the page element is allowed in the given placeholder or not
    var isElementAllowedInPlaceholder = function (ui, $placeholderWrapper) {
        var elementName = ui.item.data('element');
        var placeholder = $placeholderWrapper.data('placeholder');

        //if either the source or target element is from the master-page, only placeholders on the master-page are allowes
        if(placeholder.substring(0, "master".length) == "master" && ui.item.parent('.pePlaceholderWrapper').data('placeholder').substring(0, "master".length) != "master")
            return false;

        var allowedElements = placeholder.split('_')[1].split('|');
        return allowedElements.indexOf(elementName) !== -1;
    };

    // checks if the page element is allowed in the given placeholder or not
    var saveElementPosition = function (systemId, newPos) {
        $.post(KAJONA_WEBPATH + '/xml.php?admin=1&module=system&action=setAbsolutePosition', {
            systemid: systemId,
            listPos: newPos + 1
        });
    };

    var oldPos;
    var suspendStop = false;

    $('.pePlaceholderWrapper').sortable({
        items: 'div.peElementWrapper',
        handle: '.moveHandle',
        connectWith: '.pePlaceholderWrapper',
        cursor: 'move',
        forcePlaceholderSize: true,
        placeholder: 'peElementMovePlaceholder',
        start: function(event, ui) {
            oldPos = ui.item.parent().children('div.peElementWrapper').index(ui.item);
        },
        activate: function(event, ui) {
            var $placeholderWrapper = $(this);
            if (isElementAllowedInPlaceholder(ui, $placeholderWrapper)) {
                $placeholderWrapper.addClass('pePlaceholderWrapperDropTarget');
            }
        },
        over: function(event, ui) {
            var $placeholderWrapper = $(this);

            // hide placeholder if element is not allowed
            if (isElementAllowedInPlaceholder(ui, $placeholderWrapper)) {
                $(ui.placeholder).show();
            } else {
                $(ui.placeholder).hide();
            }
        },
        receive: function(event, ui) {
            var $placeholderWrapper = $(this);
            var $oldPlaceholderWrapper = ui.sender;

            if (isElementAllowedInPlaceholder(ui, $placeholderWrapper)) {
                var newPlaceholder = $placeholderWrapper.data('placeholder');
                var systemId = ui.item.data('systemid');
                var newPos = ui.item.parent().children('div.peElementWrapper').index(ui.item);

                suspendStop = true;
                $.post(KAJONA_WEBPATH + '/xml.php?admin=1&module=pages_content&action=moveElement', {
                    systemid: systemId,
                    placeholder: newPlaceholder
                }, function () {
                    saveElementPosition(systemId, newPos);
                    suspendStop = false;
                });
            } else {
                $oldPlaceholderWrapper.sortable("cancel");
            }
        },
        stop: function(event, ui) {
            if (!suspendStop) { // to prevent double requests
                var newPos = ui.item.parent().children('div.peElementWrapper').index(ui.item);

                if (oldPos !== newPos) {
                    var systemId = ui.item.data('systemid');
                    saveElementPosition(systemId, newPos);
                }
            }

            oldPos = null;
        },
        deactivate: function(event, ui) {
            var $placeholderWrapper = $(this);
            $placeholderWrapper.removeClass('pePlaceholderWrapperDropTarget');
        },
        delay: KAJONA.util.isTouchDevice() ? 2000 : 0
    });
};

/**
 * Folderview functions
 */
KAJONA.admin.folderview = {
    /**
     * holds a reference to the ModalDialog
     */
    dialog: undefined,

    /**
     * holds CKEditors CKEditorFuncNum parameter to read it again in KAJONA.admin.folderview.fillFormFields()
     * so we don't have to pass through the param with all requests
     */
    selectCallbackCKEditorFuncNum: 0,

    /**
     * To be called when the user selects an page/folder/file out of a folderview dialog/popup
     * Detects if the folderview is embedded in a dialog or popup to find the right context
     *
     * @param {Array} arrTargetsValues
     * @param {function} objCallback
     */
    selectCallback: function (arrTargetsValues, objCallback) {
        if (window.opener) {
            window.opener.KAJONA.admin.folderview.fillFormFields(arrTargetsValues);
        } else if (parent) {
            parent.KAJONA.admin.folderview.fillFormFields(arrTargetsValues);
        }

        if ($.isFunction(objCallback)) {
            objCallback();
        }

        this.close();

    },

    /**
     * fills the form fields with the selected values
     */
    fillFormFields: function (arrTargetsValues) {
        for (var i in arrTargetsValues) {
            if (arrTargetsValues[i][0] == "ckeditor") {
                CKEDITOR.tools.callFunction(this.selectCallbackCKEditorFuncNum, arrTargetsValues[i][1]);
            } else {
                var formField = $("#"+arrTargetsValues[i][0]).get(0);

                if (formField != null) {
                    formField.value = arrTargetsValues[i][1];

                    //fire the onchange event on the form field
                    if (document.createEvent) { //Firefox
                        var evt = document.createEvent("Events");
                        evt.initEvent('change', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
                        formField.dispatchEvent(evt);
                    } else if (document.createEventObject) { //IE
                        var evt = document.createEventObject();
                        formField.fireEvent('onchange', evt);
                    }

                }
            }
        }
    },

    /**
     * fills the form fields with the selected values
     */
    close: function () {
        if (window.opener) {
            window.close();
        } else if (parent) {
            var context = parent.KAJONA.admin.folderview;
            context.dialog.hide();
            context.dialog.setContentRaw("");
        }
    }
};

/**
 * Loader for dynamically loading additional js and css files after the onDOMReady event
 *
 */
KAJONA.admin.loader = new KAJONA.util.Loader();

KAJONA.admin.tooltip = {
    initTooltip : function() {
        KAJONA.admin.loader.loadFile(['/core/module_system/admin/scripts/qtip2/jquery.qtip.min.js', '/core/module_system/admin/scripts/qtip2/jquery.qtip.min.css'], function() {

            $('*[rel=tooltip]').qtip({
                position: {
                    viewport: $(window)
                },
                style: {
                    classes: 'qtip-youtube qtip-shadow'
                }
            });
        });
    },

    addTooltip : function(objElement, strText) {
        KAJONA.admin.loader.loadFile(['/core/module_system/admin/scripts/qtip2/jquery.qtip.min.js', '/core/module_system/admin/scripts/qtip2/jquery.qtip.min.css'], function() {

            if(strText) {
                $(objElement).qtip({
                    position: {
                        viewport: $(window)
                    },
                    style: {
                        classes: 'qtip-youtube qtip-shadow'
                    },
                    content : {
                        text: strText
                    }
                });
            }
            else {
                $(objElement).qtip({
                    position: {
                        viewport: $(window)
                    },
                    style: {
                        classes: 'qtip-youtube qtip-shadow'
                    }
                });
            }
        });
    }

};

KAJONA.admin.tooltip.initTooltip();<commit_msg>NEW: module_pages | portaleditor -> removed a debugging output [ticket #930]<commit_after>//   (c) 2004-2006 by MulchProductions, www.mulchprod.de
//   (c) 2007-2014 by Kajona, www.kajona.de
//       Published under the GNU LGPL v2.1, see /system/licence_lgpl.txt
//       $Id$

if (typeof KAJONA == "undefined") {
	var KAJONA = {
		util: {},
		portal: {
			lang: {}
		},
		admin: {
			lang: {}
		}
	};
}

/*
 * -------------------------------------------------------------------------
 * Global functions
 * -------------------------------------------------------------------------
 */

/*
 * -------------------------------------------------------------------------
 * Portaleditor-specific functions
 * -------------------------------------------------------------------------
 */

KAJONA.admin.portaleditor = {
	objPlaceholderWithElements: {},

    initPortaleditor : function() {
        CKEDITOR_BASEPATH = KAJONA_WEBPATH+"/core/module_system/admin/scripts/ckeditor/";

        KAJONA.admin.loader.loadFile([
            "/core/module_system/admin/scripts/ckeditor/ckeditor.js"
        ], function() {
            //span and other tags are officially not support, nevertheless working...
            CKEDITOR.dtd.$editable.span = 1;
            CKEDITOR.dtd.$editable.a = 1;
            CKEDITOR.dtd.$editable.label = 1;
            CKEDITOR.dtd.$editable.td = 1;
            CKEDITOR.disableAutoInline = true;
            KAJONA.admin.portaleditor.RTE.init();
        });

        // init drag&drop of page elements
        KAJONA.admin.portaleditor.dragndrop.init();
    },

	switchEnabled: function (bitStatus) {
	    var strStatus = bitStatus == true ? 'true' : 'false';
		var url = window.location.href;
		var anchorPos = url.indexOf('#');
		if (anchorPos != -1) {
	    	url = url.substring(0, anchorPos);
		}

	    url = url.replace('&pe=false', '');
	    url = url.replace('&pe=true', '');
	    url = url.replace('?pe=false', '');
	    url = url.replace('?pe=true', '');

	    if(url.indexOf('?') == -1) {
	        window.location.replace(url+'?pe='+strStatus);
	    } else {
	        window.location.replace(url+'&pe='+strStatus);
	    }
	},

	openDialog: function (strUrl) {
		peDialog.setContentIFrame(strUrl);
		peDialog.init();
	},

	closeDialog: function (bitSkipConfirmation) {
        if(!bitSkipConfirmation)
	        var bitClose = confirm(KAJONA.admin.lang["pe_dialog_close_warning"]);
	    if(bitClose || bitSkipConfirmation) {
	    	peDialog.hide();
	    	//reset iframe
	    	peDialog.setContentRaw("");
	    }
	},

	addNewElements: function (strPlaceholder, strPlaceholderName, arrElements) {
		this.objPlaceholderWithElements[strPlaceholder] = {
			placeholderName: strPlaceholderName,
			elements: arrElements
		};
	},

    changeElementData : function(strDataPlaceholder, strDataSystemid, objElementData) {

        var $objContent = jQuery.parseHTML(objElementData);

        //see if the element is already present, then flip the contents
        if($("div.peElementWrapper[data-systemid='"+strDataSystemid+"']").length) {
            $("div.peElementWrapper[data-systemid='"+strDataSystemid+"']").html($($objContent).closest("div.peElementWrapper[data-systemid="+strDataSystemid+"]").html());
        }
        else {
            //add it as the last element to the placeholder itself
            strDataPlaceholder = strDataPlaceholder.replace(/\|/g, '\\|');
            $("#menuContainer_"+strDataPlaceholder).before($($objContent).closest("div.peElementWrapper[data-systemid="+strDataSystemid+"]"));
        }

    },

    deleteElementData : function(strSystemid) {
        $("div.peElementWrapper[data-systemid='"+strSystemid+"']").remove();
        //and delete the element on the backend
        var data = {
            systemid: strSystemid
        };
        $.post(KAJONA_WEBPATH + '/xml.php?admin=1&module=pages_content&action=deleteElementFinalXML', data, function () {
        }).fail(function() {
                location.reload();
        });
    }
};

KAJONA.admin.portaleditor.RTE = {};
KAJONA.admin.portaleditor.RTE.config = {};
KAJONA.admin.portaleditor.RTE.modifiedFields = {};

KAJONA.admin.portaleditor.RTE.savePage = function () {

    //console. group('savePage');
    $.each(KAJONA.admin.portaleditor.RTE.modifiedFields, function (key, value) {
        var keySplitted = key.split('#');

        var data = {
            systemid: keySplitted[0],
            property: keySplitted[1],
            value: value
        };

        $.post(KAJONA_WEBPATH + '/xml.php?admin=1&module=pages_content&action=updateObjectProperty', data, function () {
            //console. warn('server response');
            //console. log(this.responseText);
        });
    });
    //console. groupEnd('savePage');

    KAJONA.admin.portaleditor.RTE.modifiedFields = {};
};

/**
 * To init the portaleditor, use a syntax like
 *
 * systemid#property#mode
 *
 * whereas systemid is the id of the target record, property the property of the target-object to update.
 * The mode controls the different editor-modes:
 *
 * wysiwyg: full CKEditor
 * plain: limited CKEditor, no linebreaks and only undo/redo buttons
 * textarea: limited CKEditor, linebreaks are allowed, undo/redo buttons
 */
KAJONA.admin.portaleditor.RTE.init = function () {

    $('*[data-kajona-editable]').each(function () {

        var editable = $(this);
        var keySplitted = editable.attr('data-kajona-editable').split('#');

        var strMode = keySplitted[2] ? keySplitted[2] : 'wysiwyg';

        var ckeditorConfig = KAJONA.admin.portaleditor.RTE.config;
        ckeditorConfig.customConfig = 'config_kajona_standard.js';
        ckeditorConfig.toolbar = strMode == 'wysiwyg' ? 'pe_full' : 'pe_lite';
        ckeditorConfig.forcePasteAsPlainText = true;
        ckeditorConfig.kajona_strMode = strMode;
        ckeditorConfig.title = false;
        ckeditorConfig.on = {
            blur: function( event ) {
                var data = event.editor.getData();
                var attr = $(event.editor.element).attr('data-kajona-editable');

                //validate, if injected
s have to be removed. its then up to the
                //portal element to decide if \n should be nl2br()ed.
                if(event.editor.config.kajona_strMode == 'textarea') {
                    data = data.replace("
", "");
                }

                KAJONA.admin.portaleditor.RTE.modifiedFields[attr] = data;

                // save field on blur
                KAJONA.admin.portaleditor.RTE.savePage();
            },
            key: function( event ) {
                //prevent enter in plaintext
                if (event.data.keyCode == 13 && event.editor.config.kajona_strMode == 'plain') {
                    event.cancel();
                }
            }
        };

        //disable drag n drop
        editable.bind('drop drag', function () {
            return false;
        });

        editable.attr("contenteditable", "true");
        CKEDITOR.inline(editable.get(0), ckeditorConfig);
    });

    // warn user if there are unsaved changes when leaving the page
    $(window).on('beforeunload', function () {
        // check if there are unsaved changes
        var unsavedChanges = false;
        $.each(KAJONA.admin.portaleditor.RTE.modifiedFields, function() {
            unsavedChanges = true;
            return false;
        });

        if (unsavedChanges) {
            return KAJONA.admin.lang.pe_rte_unsavedChanges;
        }
    });
};

/**
 * Initialise the drag & drop logic to move page elements
 */
KAJONA.admin.portaleditor.dragndrop = {};
KAJONA.admin.portaleditor.dragndrop.init = function () {

    // checks if the page element is allowed in the given placeholder or not
    var isElementAllowedInPlaceholder = function (ui, $placeholderWrapper) {
        var elementName = ui.item.data('element');
        var placeholder = $placeholderWrapper.data('placeholder');

        //if either the source or target element is from the master-page, only placeholders on the master-page are allowes
        if(placeholder.substring(0, "master".length) == "master" && ui.item.parent('.pePlaceholderWrapper').data('placeholder').substring(0, "master".length) != "master")
            return false;

        var allowedElements = placeholder.split('_')[1].split('|');
        return allowedElements.indexOf(elementName) !== -1;
    };

    // checks if the page element is allowed in the given placeholder or not
    var saveElementPosition = function (systemId, newPos) {
        $.post(KAJONA_WEBPATH + '/xml.php?admin=1&module=system&action=setAbsolutePosition', {
            systemid: systemId,
            listPos: newPos + 1
        });
    };

    var oldPos;
    var suspendStop = false;

    $('.pePlaceholderWrapper').sortable({
        items: 'div.peElementWrapper',
        handle: '.moveHandle',
        connectWith: '.pePlaceholderWrapper',
        cursor: 'move',
        forcePlaceholderSize: true,
        placeholder: 'peElementMovePlaceholder',
        start: function(event, ui) {
            oldPos = ui.item.parent().children('div.peElementWrapper').index(ui.item);
        },
        activate: function(event, ui) {
            var $placeholderWrapper = $(this);
            if (isElementAllowedInPlaceholder(ui, $placeholderWrapper)) {
                $placeholderWrapper.addClass('pePlaceholderWrapperDropTarget');
            }
        },
        over: function(event, ui) {
            var $placeholderWrapper = $(this);

            // hide placeholder if element is not allowed
            if (isElementAllowedInPlaceholder(ui, $placeholderWrapper)) {
                $(ui.placeholder).show();
            } else {
                $(ui.placeholder).hide();
            }
        },
        receive: function(event, ui) {
            var $placeholderWrapper = $(this);
            var $oldPlaceholderWrapper = ui.sender;

            if (isElementAllowedInPlaceholder(ui, $placeholderWrapper)) {
                var newPlaceholder = $placeholderWrapper.data('placeholder');
                var systemId = ui.item.data('systemid');
                var newPos = ui.item.parent().children('div.peElementWrapper').index(ui.item);

                suspendStop = true;
                $.post(KAJONA_WEBPATH + '/xml.php?admin=1&module=pages_content&action=moveElement', {
                    systemid: systemId,
                    placeholder: newPlaceholder
                }, function () {
                    saveElementPosition(systemId, newPos);
                    suspendStop = false;
                });
            } else {
                $oldPlaceholderWrapper.sortable("cancel");
            }
        },
        stop: function(event, ui) {
            if (!suspendStop) { // to prevent double requests
                var newPos = ui.item.parent().children('div.peElementWrapper').index(ui.item);

                if (oldPos !== newPos) {
                    var systemId = ui.item.data('systemid');
                    saveElementPosition(systemId, newPos);
                }
            }

            oldPos = null;
        },
        deactivate: function(event, ui) {
            var $placeholderWrapper = $(this);
            $placeholderWrapper.removeClass('pePlaceholderWrapperDropTarget');
        },
        delay: KAJONA.util.isTouchDevice() ? 2000 : 0
    });
};

/**
 * Folderview functions
 */
KAJONA.admin.folderview = {
    /**
     * holds a reference to the ModalDialog
     */
    dialog: undefined,

    /**
     * holds CKEditors CKEditorFuncNum parameter to read it again in KAJONA.admin.folderview.fillFormFields()
     * so we don't have to pass through the param with all requests
     */
    selectCallbackCKEditorFuncNum: 0,

    /**
     * To be called when the user selects an page/folder/file out of a folderview dialog/popup
     * Detects if the folderview is embedded in a dialog or popup to find the right context
     *
     * @param {Array} arrTargetsValues
     * @param {function} objCallback
     */
    selectCallback: function (arrTargetsValues, objCallback) {
        if (window.opener) {
            window.opener.KAJONA.admin.folderview.fillFormFields(arrTargetsValues);
        } else if (parent) {
            parent.KAJONA.admin.folderview.fillFormFields(arrTargetsValues);
        }

        if ($.isFunction(objCallback)) {
            objCallback();
        }

        this.close();

    },

    /**
     * fills the form fields with the selected values
     */
    fillFormFields: function (arrTargetsValues) {
        for (var i in arrTargetsValues) {
            if (arrTargetsValues[i][0] == "ckeditor") {
                CKEDITOR.tools.callFunction(this.selectCallbackCKEditorFuncNum, arrTargetsValues[i][1]);
            } else {
                var formField = $("#"+arrTargetsValues[i][0]).get(0);

                if (formField != null) {
                    formField.value = arrTargetsValues[i][1];

                    //fire the onchange event on the form field
                    if (document.createEvent) { //Firefox
                        var evt = document.createEvent("Events");
                        evt.initEvent('change', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
                        formField.dispatchEvent(evt);
                    } else if (document.createEventObject) { //IE
                        var evt = document.createEventObject();
                        formField.fireEvent('onchange', evt);
                    }

                }
            }
        }
    },

    /**
     * fills the form fields with the selected values
     */
    close: function () {
        if (window.opener) {
            window.close();
        } else if (parent) {
            var context = parent.KAJONA.admin.folderview;
            context.dialog.hide();
            context.dialog.setContentRaw("");
        }
    }
};

/**
 * Loader for dynamically loading additional js and css files after the onDOMReady event
 *
 */
KAJONA.admin.loader = new KAJONA.util.Loader();

KAJONA.admin.tooltip = {
    initTooltip : function() {
        KAJONA.admin.loader.loadFile(['/core/module_system/admin/scripts/qtip2/jquery.qtip.min.js', '/core/module_system/admin/scripts/qtip2/jquery.qtip.min.css'], function() {

            $('*[rel=tooltip]').qtip({
                position: {
                    viewport: $(window)
                },
                style: {
                    classes: 'qtip-youtube qtip-shadow'
                }
            });
        });
    },

    addTooltip : function(objElement, strText) {
        KAJONA.admin.loader.loadFile(['/core/module_system/admin/scripts/qtip2/jquery.qtip.min.js', '/core/module_system/admin/scripts/qtip2/jquery.qtip.min.css'], function() {

            if(strText) {
                $(objElement).qtip({
                    position: {
                        viewport: $(window)
                    },
                    style: {
                        classes: 'qtip-youtube qtip-shadow'
                    },
                    content : {
                        text: strText
                    }
                });
            }
            else {
                $(objElement).qtip({
                    position: {
                        viewport: $(window)
                    },
                    style: {
                        classes: 'qtip-youtube qtip-shadow'
                    }
                });
            }
        });
    }

};

KAJONA.admin.tooltip.initTooltip();<|endoftext|>