<commit_before>/*
 * Copyright 2014-2016 Mendix Technology bv
 */
require([
    "dojo/_base/declare", "mxui/widget/_WidgetBase", "dijit/_TemplatedMixin",
    "mxui/dom", "dojo/dom-class", "dojo/dom-style", "dojo/dom-construct"
], function(declare, _WidgetBase, _TemplatedMixin, dom, domClass, domStyle, domConstruct) {

    "use strict";

    return declare("CameraWidgetForPhoneGap.widget.CameraWidgetForPhoneGap", [ _WidgetBase ], {

        buttonClass: "wx-mxwx-button-extra",
        buttonText: "activate camera",
        imageContainerClass: "wx-mxwx-imagecontainer-extra",
        imageWidth: 150,
        imageHeight: 150,
        imageLocation: "right",
        targetWidth: 150,
        targetHeight: 150,
        autoSaveEnabled: false,
        onchangemf: "",
        onSaveNanoflow: "",
        pictureSource: "camera",

        _contextObj: null,
        _imageUrl: null,
        _previewNode: null,

        postCreate: function() {
            domClass.add(this.domNode, "wx-CameraWidgetForPhoneGap");

            var elements = [ this._setupPreview(), this._setupButton() ];
            if (/below|right/.test(this.imageLocation)) {
                elements.reverse();
            }

            var alignment = "horizontal";
            if (/above|below/.test(this.imageLocation)) {
                alignment = "vertical";
            }

            elements.forEach(function(el) {
                domClass.add(el, "wx-CameraWidgetForPhoneGap-" + alignment);
                this.domNode.appendChild(el);
            }, this);

            this.listen("commit", this._sendFile);
        },

        update: function(obj, callback) {
            if (obj) {
                this._contextObj = obj;
                this._loadData();
                this._resetSubscriptions();
                this._setPicture("");
            }

            if (callback) callback();
        },

        _setupButton: function() {
            var button = dom.create("button", {
                "type": "button",
                "class": "btn btn-primary wx-CameraWidgetForPhoneGap-button " + this.buttonClass
            }, this.buttonText);

            this.connect(button, "click", "_getPicture");
            return button;
        },

        _setupPreview: function() {
            this._previewNode = dom.create("div", {
                "class": "wx-CameraWidgetForPhoneGap-preview " + this.imageContainerClass
            });
            return this._previewNode;
        },

        _loadData: function() {
            if (this._contextObj) {
                if (!this._contextObj.inheritsFrom("System.FileDocument")) {
                    var span = dom.create("span", {
                            "class": "alert-danger"
                        },
                        "Entity '" + this._contextObj.getEntity() + "' does not inherit from 'System.FileDocument'");
                    domConstruct.empty(this.domNode);
                    this.domNode.appendChild(span);
                }
            }

        },

        _setPicture: function(url) {
            this._imageUrl = url;
            this._setThumbnail(url);
        },

        _setThumbnail: function(url) {
            var urlDisplay = url ? "" : "none",
                width = this.imageWidth || 100,
                height = this.imageHeight || 100,
                background = url ? "url(" + url + ")" : "none";

            domStyle.set(this._previewNode, {
                "background-image": background,
                "display": urlDisplay,
                "width": width + "px",
                "height": height + "px"
            });
        },

        _getPicture: function() {
            var self = this;

            if (!navigator.camera) {
                window.mx.ui.error("Unable to detect camera.");
                return;
            }

            var sourceType = (this.pictureSource == "camera") ?
                    Camera.PictureSourceType.CAMERA : Camera.PictureSourceType.PHOTOLIBRARY;
            var params = {
                quality: 100,
                destinationType: Camera.DestinationType.FILE_URL,
                correctOrientation: true,
                sourceType: sourceType
            };
            if (this.targetWidth !== 0) params.targetWidth = this.targetWidth;
            if (this.targetHeight !== 0) params.targetHeight = this.targetHeight;
            // TODO: get rid of temp image files
            navigator.camera.getPicture(success, error, params);

            function success(url) {
                if (self.autoSaveEnabled) {
                    self._autoSave(url);
                } else {
                    self._setPicture(url);
                }
            }

            function error(e) {
                window.mx.ui.error("Retrieving image from camera failed with error code " + e.message || e.code || "");
            }
        },

        _sendFile: function(callback) {
            var self = this;

            if (!this._imageUrl) {
                if (callback) callback();
                return;
            }

            var filename = /[^\/]*$/.exec(this._imageUrl)[0];
            var guid = this._contextObj.getGuid();
            if (window.mx.data.saveDocument && window.mx.data.saveDocument.length === 6) {
                window.resolveLocalFileSystemURL(this._imageUrl, function(fileEntry) {
                    fileEntry.file(function(blob) {
                        var fileReader = new FileReader();
                        fileReader.onload = function(e) {
                            window.mx.data.saveDocument(guid, filename, {}, new Blob([ e.target.result ]), success, error);
                        };

                        fileReader.onerror = function(e) {
                            error(e.target.error);
                        };

                        fileReader.readAsArrayBuffer(blob);
                    }, error);
                }, error);
            } else {
                // For Mendix versions < 6.4
                var options = new FileUploadOptions();
                options.fileKey = "mxdocument";
                options.fileName = filename;
                options.mimeType = "image/jpeg";
                options.useBrowserHttp = true;

                var url = mx.appUrl +
                    "file?guid=" + this._contextObj.getGuid() +
                    "&csrfToken=" + mx.session.getConfig("csrftoken");

                var ft = new FileTransfer();
                ft.upload(this._imageUrl, url, refreshObject, error, options);
            }

            function refreshObject() {
                window.mx.data.get({
                    guid: guid,
                    noCache: true,
                    callback: success,
                    error: error
                });
            }

            function success() {
                self._setPicture("");
                self._executeAction();
                if (callback) callback();
            }

            function error(e) {
                logger.error("Uploading image failed with error code ", e);
                window.mx.ui.error("Uploading image failed with error " + e.message || e.code || "");
            }
        },

        _autoSave: function(url) {
            this._imageUrl = url;
            if (this._contextObj){
                 window.mx.data.commit({
                     mxobj: this._contextObj,
                     callback: function(){
                        this._sendFile();
                     }
                }, this);
            }
        },

        _resetSubscriptions: function() {
            this.unsubscribeAll();

            if (this._contextObj) {
                this.subscribe({
                    guid: this._contextObj.getGuid(),
                    callback: function(guid) {
                        window.mx.data.get({
                            guid: guid,
                            callback: function(obj) {
                                this._contextObj = obj;
                                this._loadData();
                            }
                        }, this);
                    }
                });
            }
        },

        _executeAction: function() {
            if (this.onchangemf && this._contextObj) {
                var microflow = this.onchangemf;
                window.mx.ui.action(microflow, {
                    context: this.mxcontext,
                    origin: this.mxform,
                    error: function(error) {
                        mx.ui.error("An error occurred while executing on save microflow " + microflow + " : " + error.message);
                    }
                });
            }

            if (this.onSaveNanoflow && this.mxcontext) {
                window.mx.data.callNanoflow({
                    nanoflow: this.onSaveNanoflow,
                    origin: this.mxform,
                    context: this.mxcontext,
                    error: function (error) {
                        mx.ui.error("An error occurred while executing the on click nanoflow: " + error.message);
                    }
                });
            }
        },
    });
});
<commit_msg>Fix nanoflow<commit_after>/*
 * Copyright 2014-2016 Mendix Technology bv
 */
require([
    "dojo/_base/declare", "mxui/widget/_WidgetBase", "dijit/_TemplatedMixin",
    "mxui/dom", "dojo/dom-class", "dojo/dom-style", "dojo/dom-construct"
], function(declare, _WidgetBase, _TemplatedMixin, dom, domClass, domStyle, domConstruct) {

    "use strict";

    return declare("CameraWidgetForPhoneGap.widget.CameraWidgetForPhoneGap", [ _WidgetBase ], {

        buttonClass: "wx-mxwx-button-extra",
        buttonText: "activate camera",
        imageContainerClass: "wx-mxwx-imagecontainer-extra",
        imageWidth: 150,
        imageHeight: 150,
        imageLocation: "right",
        targetWidth: 150,
        targetHeight: 150,
        autoSaveEnabled: false,
        onchangemf: "",
        onSaveNanoflow: "",
        pictureSource: "camera",

        _contextObj: null,
        _imageUrl: null,
        _previewNode: null,

        postCreate: function() {
            domClass.add(this.domNode, "wx-CameraWidgetForPhoneGap");

            var elements = [ this._setupPreview(), this._setupButton() ];
            if (/below|right/.test(this.imageLocation)) {
                elements.reverse();
            }

            var alignment = "horizontal";
            if (/above|below/.test(this.imageLocation)) {
                alignment = "vertical";
            }

            elements.forEach(function(el) {
                domClass.add(el, "wx-CameraWidgetForPhoneGap-" + alignment);
                this.domNode.appendChild(el);
            }, this);

            this.listen("commit", this._sendFile);
        },

        update: function(obj, callback) {
            if (obj) {
                this._contextObj = obj;
                this._loadData();
                this._resetSubscriptions();
                this._setPicture("");
            }

            if (callback) callback();
        },

        _setupButton: function() {
            var button = dom.create("button", {
                "type": "button",
                "class": "btn btn-primary wx-CameraWidgetForPhoneGap-button " + this.buttonClass
            }, this.buttonText);

            this.connect(button, "click", "_getPicture");
            return button;
        },

        _setupPreview: function() {
            this._previewNode = dom.create("div", {
                "class": "wx-CameraWidgetForPhoneGap-preview " + this.imageContainerClass
            });
            return this._previewNode;
        },

        _loadData: function() {
            if (this._contextObj) {
                if (!this._contextObj.inheritsFrom("System.FileDocument")) {
                    var span = dom.create("span", {
                            "class": "alert-danger"
                        },
                        "Entity '" + this._contextObj.getEntity() + "' does not inherit from 'System.FileDocument'");
                    domConstruct.empty(this.domNode);
                    this.domNode.appendChild(span);
                }
            }

        },

        _setPicture: function(url) {
            this._imageUrl = url;
            this._setThumbnail(url);
        },

        _setThumbnail: function(url) {
            var urlDisplay = url ? "" : "none",
                width = this.imageWidth || 100,
                height = this.imageHeight || 100,
                background = url ? "url(" + url + ")" : "none";

            domStyle.set(this._previewNode, {
                "background-image": background,
                "display": urlDisplay,
                "width": width + "px",
                "height": height + "px"
            });
        },

        _getPicture: function() {
            var self = this;

            if (!navigator.camera) {
                window.mx.ui.error("Unable to detect camera.");
                return;
            }

            var sourceType = (this.pictureSource == "camera") ?
                    Camera.PictureSourceType.CAMERA : Camera.PictureSourceType.PHOTOLIBRARY;
            var params = {
                quality: 100,
                destinationType: Camera.DestinationType.FILE_URL,
                correctOrientation: true,
                sourceType: sourceType
            };
            if (this.targetWidth !== 0) params.targetWidth = this.targetWidth;
            if (this.targetHeight !== 0) params.targetHeight = this.targetHeight;
            // TODO: get rid of temp image files
            navigator.camera.getPicture(success, error, params);

            function success(url) {
                if (self.autoSaveEnabled) {
                    self._autoSave(url);
                } else {
                    self._setPicture(url);
                }
            }

            function error(e) {
                window.mx.ui.error("Retrieving image from camera failed with error code " + e.message || e.code || "");
            }
        },

        _sendFile: function(callback) {
            var self = this;

            if (!this._imageUrl) {
                if (callback) callback();
                return;
            }

            var filename = /[^\/]*$/.exec(this._imageUrl)[0];
            var guid = this._contextObj.getGuid();
            if (window.mx.data.saveDocument && window.mx.data.saveDocument.length === 6) {
                window.resolveLocalFileSystemURL(this._imageUrl, function(fileEntry) {
                    fileEntry.file(function(blob) {
                        var fileReader = new FileReader();
                        fileReader.onload = function(e) {
                            window.mx.data.saveDocument(guid, filename, {}, new Blob([ e.target.result ]), success, error);
                        };

                        fileReader.onerror = function(e) {
                            error(e.target.error);
                        };

                        fileReader.readAsArrayBuffer(blob);
                    }, error);
                }, error);
            } else {
                // For Mendix versions < 6.4
                var options = new FileUploadOptions();
                options.fileKey = "mxdocument";
                options.fileName = filename;
                options.mimeType = "image/jpeg";
                options.useBrowserHttp = true;

                var url = mx.appUrl +
                    "file?guid=" + this._contextObj.getGuid() +
                    "&csrfToken=" + mx.session.getConfig("csrftoken");

                var ft = new FileTransfer();
                ft.upload(this._imageUrl, url, refreshObject, error, options);
            }

            function refreshObject() {
                window.mx.data.get({
                    guid: guid,
                    noCache: true,
                    callback: success,
                    error: error
                });
            }

            function success() {
                self._setPicture("");
                self._executeAction();
                if (callback) callback();
            }

            function error(e) {
                logger.error("Uploading image failed with error code ", e);
                window.mx.ui.error("Uploading image failed with error " + e.message || e.code || "");
            }
        },

        _autoSave: function(url) {
            this._imageUrl = url;
            if (this._contextObj){
                 window.mx.data.commit({
                     mxobj: this._contextObj,
                     callback: function(){
                        this._sendFile();
                     }
                }, this);
            }
        },

        _resetSubscriptions: function() {
            this.unsubscribeAll();

            if (this._contextObj) {
                this.subscribe({
                    guid: this._contextObj.getGuid(),
                    callback: function(guid) {
                        window.mx.data.get({
                            guid: guid,
                            callback: function(obj) {
                                this._contextObj = obj;
                                this._loadData();
                            }
                        }, this);
                    }
                });
            }
        },

        _executeAction: function() {
            if (this.onchangemf && this._contextObj) {
                var microflow = this.onchangemf;
                window.mx.ui.action(microflow, {
                    context: this.mxcontext,
                    origin: this.mxform,
                    error: function(error) {
                        mx.ui.error("An error occurred while executing on save microflow " + microflow + " : " + error.message);
                    }
                });
            }

            if (this.onSaveNanoflow.nanoflow && this.mxcontext) {
                window.mx.data.callNanoflow({
                    nanoflow: this.onSaveNanoflow,
                    origin: this.mxform,
                    context: this.mxcontext,
                    error: function (error) {
                        mx.ui.error("An error occurred while executing the on click nanoflow: " + error.message);
                    }
                });
            }
        },
    });
});
<|endoftext|>


<commit_before>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

WebInspector.TimelineJSProfileProcessor = { };

/**
 * @param {!ProfilerAgent.CPUProfile} jsProfile
 * @param {!WebInspector.TracingModel.Thread} thread
 * @return {!Array.<!WebInspector.TracingModel.Event>}
 */
WebInspector.TimelineJSProfileProcessor.generateTracingEventsFromCpuProfile = function(jsProfile, thread)
{
    if (!jsProfile.samples)
        return [];
    var jsProfileModel = new WebInspector.CPUProfileDataModel(jsProfile);
    var idleNode = jsProfileModel.idleNode;
    var programNode = jsProfileModel.programNode;
    var gcNode = jsProfileModel.gcNode;
    var samples = jsProfileModel.samples;
    var timestamps = jsProfileModel.timestamps;
    var jsEvents = [];
    for (var i = 0; i < samples.length; ++i) {
        var node = jsProfileModel.nodeByIndex(i);
        if (node === programNode || node === gcNode || node === idleNode)
            continue;
        var stackTrace = node._stackTraceArray;
        if (!stackTrace) {
            stackTrace = /** @type {!ConsoleAgent.StackTrace} */ (new Array(node.depth + 1));
            node._stackTraceArray = stackTrace;
            for (var j = 0; node.parent; node = node.parent)
                stackTrace[j++] = /** @type {!ConsoleAgent.CallFrame} */ (node);
        }
        var jsEvent = new WebInspector.TracingModel.Event(WebInspector.TracingModel.DevToolsMetadataEventCategory, WebInspector.TimelineModel.RecordType.JSSample,
            WebInspector.TracingModel.Phase.Instant, timestamps[i], thread);
        jsEvent.args["data"] = { stackTrace: stackTrace };
        jsEvents.push(jsEvent);
    }
    return jsEvents;
}

/**
 * @param {!Array.<!WebInspector.TracingModel.Event>} events
 * @return {!Array.<!WebInspector.TracingModel.Event>}
 */
WebInspector.TimelineJSProfileProcessor.generateJSFrameEvents = function(events)
{
    function equalFrames(frame1, frame2)
    {
        return frame1.scriptId === frame2.scriptId && frame1.functionName === frame2.functionName;
    }

    function eventEndTime(e)
    {
        return e.endTime || e.startTime;
    }

    function isJSInvocationEvent(e)
    {
        switch (e.name) {
        case WebInspector.TimelineModel.RecordType.FunctionCall:
        case WebInspector.TimelineModel.RecordType.EvaluateScript:
            return true;
        }
        return false;
    }

    var jsFrameEvents = [];
    var jsFramesStack = [];
    var coalesceThresholdMs = WebInspector.TimelineFlameChartDataProvider.JSFrameCoalesceThresholdMs;

    function onStartEvent(e)
    {
        extractStackTrace(e);
    }

    function onInstantEvent(e, top)
    {
        if (e.name === WebInspector.TimelineModel.RecordType.JSSample && top && !isJSInvocationEvent(top))
            return;
        extractStackTrace(e);
    }

    function onEndEvent(e)
    {
        if (isJSInvocationEvent(e))
            jsFramesStack.length = 0;
    }

    function extractStackTrace(e)
    {
        var eventData = e.args["data"] || e.args["beginData"];
        var stackTrace = eventData && eventData["stackTrace"];
        if (!stackTrace)
            return;
        while (jsFramesStack.length && eventEndTime(jsFramesStack.peekLast()) + coalesceThresholdMs <= e.startTime)
            jsFramesStack.pop();
        var endTime = eventEndTime(e);
        var numFrames = stackTrace.length;
        var minFrames = Math.min(numFrames, jsFramesStack.length);
        var j;
        for (j = 0; j < minFrames; ++j) {
            var newFrame = stackTrace[numFrames - 1 - j];
            var oldFrame = jsFramesStack[j].args["data"];
            if (!equalFrames(newFrame, oldFrame))
                break;
            jsFramesStack[j].setEndTime(Math.max(jsFramesStack[j].endTime, endTime));
        }
        jsFramesStack.length = j;
        for (; j < numFrames; ++j) {
            var frame = stackTrace[numFrames - 1 - j];
            var jsFrameEvent = new WebInspector.TracingModel.Event(WebInspector.TracingModel.DevToolsMetadataEventCategory, WebInspector.TimelineModel.RecordType.JSFrame,
                WebInspector.TracingModel.Phase.Complete, e.startTime, e.thread);
            jsFrameEvent.addArgs({ data: frame });
            jsFrameEvent.setEndTime(endTime);
            jsFramesStack.push(jsFrameEvent);
            jsFrameEvents.push(jsFrameEvent);
        }
    }

    var stack = [];
    for (var i = 0; i < events.length; ++i) {
        var e = events[i];
        var top = stack.peekLast();
        if (top && top.endTime <= e.startTime)
            onEndEvent(stack.pop());
        if (e.duration) {
            onStartEvent(e);
            stack.push(e);
        } else {
            onInstantEvent(e, stack.peekLast());
        }
    }
    while (stack.length)
        onEndEvent(stack.pop());

    return jsFrameEvents;
}
<commit_msg>DevTools: put GC events on top of the current call stack in timeline.<commit_after>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

WebInspector.TimelineJSProfileProcessor = { };

/**
 * @param {!ProfilerAgent.CPUProfile} jsProfile
 * @param {!WebInspector.TracingModel.Thread} thread
 * @return {!Array.<!WebInspector.TracingModel.Event>}
 */
WebInspector.TimelineJSProfileProcessor.generateTracingEventsFromCpuProfile = function(jsProfile, thread)
{
    if (!jsProfile.samples)
        return [];
    var jsProfileModel = new WebInspector.CPUProfileDataModel(jsProfile);
    var idleNode = jsProfileModel.idleNode;
    var programNode = jsProfileModel.programNode;
    var gcNode = jsProfileModel.gcNode;
    var samples = jsProfileModel.samples;
    var timestamps = jsProfileModel.timestamps;
    var jsEvents = [];
    for (var i = 0; i < samples.length; ++i) {
        var node = jsProfileModel.nodeByIndex(i);
        if (node === programNode || node === gcNode || node === idleNode)
            continue;
        var stackTrace = node._stackTraceArray;
        if (!stackTrace) {
            stackTrace = /** @type {!ConsoleAgent.StackTrace} */ (new Array(node.depth + 1));
            node._stackTraceArray = stackTrace;
            for (var j = 0; node.parent; node = node.parent)
                stackTrace[j++] = /** @type {!ConsoleAgent.CallFrame} */ (node);
        }
        var jsEvent = new WebInspector.TracingModel.Event(WebInspector.TracingModel.DevToolsMetadataEventCategory, WebInspector.TimelineModel.RecordType.JSSample,
            WebInspector.TracingModel.Phase.Instant, timestamps[i], thread);
        jsEvent.args["data"] = { stackTrace: stackTrace };
        jsEvents.push(jsEvent);
    }
    return jsEvents;
}

/**
 * @param {!Array.<!WebInspector.TracingModel.Event>} events
 * @return {!Array.<!WebInspector.TracingModel.Event>}
 */
WebInspector.TimelineJSProfileProcessor.generateJSFrameEvents = function(events)
{
    function equalFrames(frame1, frame2)
    {
        return frame1.scriptId === frame2.scriptId && frame1.functionName === frame2.functionName;
    }

    function eventEndTime(e)
    {
        return e.endTime || e.startTime;
    }

    function isJSInvocationEvent(e)
    {
        switch (e.name) {
        case WebInspector.TimelineModel.RecordType.FunctionCall:
        case WebInspector.TimelineModel.RecordType.EvaluateScript:
            return true;
        }
        return false;
    }

    var jsFrameEvents = [];
    var jsFramesStack = [];
    var coalesceThresholdMs = WebInspector.TimelineFlameChartDataProvider.JSFrameCoalesceThresholdMs;

    function onStartEvent(e)
    {
        extractStackTrace(e);
    }

    function onInstantEvent(e, top)
    {
        if (e.name === WebInspector.TimelineModel.RecordType.JSSample && top && !isJSInvocationEvent(top))
            return;
        extractStackTrace(e);
    }

    function onEndEvent(e)
    {
        if (isJSInvocationEvent(e))
            jsFramesStack.length = 0;
    }

    function extractStackTrace(e)
    {
        while (jsFramesStack.length && eventEndTime(jsFramesStack.peekLast()) + coalesceThresholdMs <= e.startTime)
            jsFramesStack.pop();
        var eventData = e.args["data"] || e.args["beginData"];
        var stackTrace = eventData && eventData["stackTrace"];
        // GC events do not hold call stack, so make a copy of the current stack.
        if (e.name === WebInspector.TimelineModel.RecordType.GCEvent)
            stackTrace = jsFramesStack.map(function(frameEvent) { return frameEvent.args["data"]; }).reverse();
        if (!stackTrace)
            return;
        var endTime = eventEndTime(e);
        var numFrames = stackTrace.length;
        var minFrames = Math.min(numFrames, jsFramesStack.length);
        var j;
        for (j = 0; j < minFrames; ++j) {
            var newFrame = stackTrace[numFrames - 1 - j];
            var oldFrame = jsFramesStack[j].args["data"];
            if (!equalFrames(newFrame, oldFrame))
                break;
            jsFramesStack[j].setEndTime(Math.max(jsFramesStack[j].endTime, endTime));
        }
        jsFramesStack.length = j;
        for (; j < numFrames; ++j) {
            var frame = stackTrace[numFrames - 1 - j];
            var jsFrameEvent = new WebInspector.TracingModel.Event(WebInspector.TracingModel.DevToolsMetadataEventCategory, WebInspector.TimelineModel.RecordType.JSFrame,
                WebInspector.TracingModel.Phase.Complete, e.startTime, e.thread);
            jsFrameEvent.addArgs({ data: frame });
            jsFrameEvent.setEndTime(endTime);
            jsFramesStack.push(jsFrameEvent);
            jsFrameEvents.push(jsFrameEvent);
        }
    }

    var stack = [];
    for (var i = 0; i < events.length; ++i) {
        var e = events[i];
        var top = stack.peekLast();
        if (top && top.endTime <= e.startTime)
            onEndEvent(stack.pop());
        if (e.duration) {
            onStartEvent(e);
            stack.push(e);
        } else {
            onInstantEvent(e, stack.peekLast());
        }
    }
    while (stack.length)
        onEndEvent(stack.pop());

    return jsFrameEvents;
}
<|endoftext|>


<commit_before>import PropTypes from 'prop-types'
import React from 'react'
import Spinner from 'part:@sanity/components/loading/spinner'
import styles from './styles/DocumentsPane.css'
import {StateLink, IntentLink, withRouterHOC} from 'part:@sanity/base/router'
import SortIcon from 'part:@sanity/base/sort-icon'
import Ink from 'react-ink'

import ListView from './ListView'
import {partition, uniqBy, get} from 'lodash'
import VisibilityOffIcon from 'part:@sanity/base/visibility-off-icon'
import EditIcon from 'part:@sanity/base/edit-icon'
import QueryContainer from 'part:@sanity/base/query-container'
import {DRAFTS_FOLDER, getPublishedId, isDraftId, getDraftId} from '../utils/draftUtils'
import {isPublishedId} from '../utils/draftUtils'
import schema from 'part:@sanity/base/schema'
import Preview from 'part:@sanity/base/preview'
import Pane from 'part:@sanity/components/panes/default'
import DocumentsPaneMenu from './DocumentsPaneMenu'
import Button from 'part:@sanity/components/buttons/default'
import PlusIcon from 'part:@sanity/base/plus-icon'
import Snackbar from 'part:@sanity/components/snackbar/default'
import {Tooltip} from '@sanity/react-tippy'
const NOOP = () => {} // eslint-disable-line

const LOCALSTORAGE_KEY = 'desk-tool.documents-pane-settings'

function readSettings() {
  return JSON.parse(window.localStorage.getItem(LOCALSTORAGE_KEY) || '{}')
}

function writeSettings(settings) {
  window.localStorage.setItem(LOCALSTORAGE_KEY, JSON.stringify(settings))
}

function getDocumentKey(document) {
  return getPublishedId(document._id)
}

function toGradientOrderClause(orderBy) {
  return orderBy
    .map(ordering => [ordering.field, ordering.direction].filter(Boolean).join(' '))
    .join(', ')
}

const ORDER_BY_UPDATED_AT = {
  title: 'Last edited',
  name: 'updatedAt',
  by: [{field: '_updatedAt', direction: 'desc'}]
}

const ORDER_BY_CREATED_AT = {
  title: 'Created',
  name: 'createdAt',
  by: [{field: '_createdAt', direction: 'desc'}]
}

const DEFAULT_SELECTED_ORDERING_OPTION = ORDER_BY_UPDATED_AT
const DEFAULT_ORDERING_OPTIONS = [ORDER_BY_UPDATED_AT, ORDER_BY_CREATED_AT]

function removePublishedWithDrafts(documents) {
  const [draftIds, publishedIds] = partition(documents.map(doc => doc._id), isDraftId)

  return documents
    .map(doc => {
      const publishedId = getPublishedId(doc._id)
      const draftId = getDraftId(doc._id)
      return {
        ...doc,
        hasPublished: publishedIds.includes(publishedId),
        hasDraft: draftIds.includes(draftId)
      }
    })
    .filter(doc => !(isPublishedId(doc._id) && doc.hasDraft))
}

function writeSettingsForType(type, settings) {
  writeSettings(
    Object.assign(readSettings(), {
      [type]: settings
    })
  )
}

export default withRouterHOC(
  class DocumentsPane extends React.PureComponent {
    static propTypes = {
      selectedType: PropTypes.string,
      selectedDocumentId: PropTypes.string,
      schemaType: PropTypes.object,
      isCollapsed: PropTypes.bool,
      router: PropTypes.object
    }

    static defaultProps = {
      loading: false,
      isCollapsed: false,
      published: [],
      drafts: [],
      onSetListLayout: NOOP
    }

    handleSetListLayout = listLayout => {
      this.setState(
        prevState => ({
          settings: {
            ...prevState.settings,
            listLayout: listLayout.key
          }
        }),
        this.writeSettings
      )
    }

    constructor(props) {
      super()
      const settings = readSettings()
      this.state = {
        settings: (settings && settings[props.selectedType]) || {
          listLayout: 'default',
          ordering: DEFAULT_SELECTED_ORDERING_OPTION
        },
        menuIsOpen: false
      }
    }

    handleSetOrdering = ordering => {
      this.setState(
        prevState => ({
          settings: {
            ...prevState.settings,
            ordering: ordering.name
          }
        }),
        this.writeSettings
      )
    }

    writeSettings() {
      writeSettingsForType(this.props.selectedType, this.state.settings)
    }

    handleToggleMenu = evt => {
      evt.stopPropagation()
      this.setState(prevState => ({menuIsOpen: !prevState.menuIsOpen}))
    }

    handleCloseMenu = evt => {
      evt.stopPropagation()
      this.setState(prevState => ({menuIsOpen: !prevState.menuIsOpen}))
    }

    getOrderingOptions(selectedType) {
      const type = schema.get(selectedType)

      const optionsWithDefaults = type.orderings
        ? type.orderings.concat(DEFAULT_ORDERING_OPTIONS)
        : DEFAULT_ORDERING_OPTIONS

      return uniqBy(optionsWithDefaults, 'name').map(option => {
        return {
          ...option,
          icon: option.icon || SortIcon,
          title: (

              Sort by {option.title}

          )
        }
      })
    }

    handleGoToCreateNew = () => {
      const {selectedType, router} = this.props
      router.navigateIntent('create', {type: selectedType})
    }

    renderDocumentsPaneMenu = () => {
      const {selectedType} = this.props
      const type = schema.get(selectedType)
      return (
        <DocumentsPaneMenu
          onSetListLayout={this.handleSetListLayout}
          onSetOrdering={this.handleSetOrdering}
          onGoToCreateNew={this.handleGoToCreateNew}
          onMenuClose={this.handleCloseMenu}
          onClickOutside={this.handleCloseMenu}
          isOpen={this.state.menuIsOpen}
          orderingOptions={this.getOrderingOptions(selectedType)}
          type={type}
        />
      )
    }

    renderStatus = item => {
      return (

          {!item.hasPublished && (
            <Tooltip title="Not published" arrow theme="light" distance="2" sticky size="small">

                <VisibilityOffIcon />

            </Tooltip>
          )}
          {item.hasDraft &&
            item.hasPublished && (
              <Tooltip
                title="Has changes not yet published"
                arrow
                theme="light"
                distance="2"
                sticky
                size="small"
              >

                  <EditIcon />

              </Tooltip>
            )}

      )
    }

    renderDocumentPaneItem = (item, index, options = {}) => {
      const {selectedType, selectedDocumentId} = this.props
      const {settings} = this.state

      const ordering = this.getOrderingOptions(selectedType).find(
        option => option.name === settings.ordering
      )

      const type = schema.get(selectedType)
      const linkState = {
        selectedDocumentId: getPublishedId(item._id),
        selectedType: type.name,
        action: 'edit'
      }

      const isSelected =
        selectedDocumentId && getPublishedId(item._id) === getPublishedId(selectedDocumentId)

      return (
        <StateLink state={linkState} className={styles.link} tabIndex={0}>

            <Preview
              value={item}
              ordering={ordering}
              layout={settings.listLayout}
              type={type}
              status={() => this.renderStatus(item)}
            />

          <Ink duration={1000} opacity={0.1} radius={200} />
        </StateLink>
      )
    }

    renderFunctions = isCollapsed => {
      const {selectedType} = this.props
      const type = schema.get(selectedType)
      return (
        <Button
          title={`Create new ${type.name}`}
          icon={PlusIcon}
          color="primary"
          kind="simple"
          onClick={this.handleGoToCreateNew}
        />
      )
    }

    handleScroll = scrollTop => {
      this.setState({scrollTop})
    }

    render() {
      const {selectedDocumentId, schemaType, isCollapsed, router} = this.props

      const {settings} = this.state
      const currentOrderingOption =
        this.getOrderingOptions(schemaType.name).find(
          option => option.name === settings.ordering
        ) || DEFAULT_SELECTED_ORDERING_OPTION
      const params = {type: schemaType.name, draftsPath: `${DRAFTS_FOLDER}.**`}
      const query = `*[_type == $type] | order(${toGradientOrderClause(
        currentOrderingOption.by
      )}) [0...10000] {_id, _type}`
      const {selectedType, action} = router.state
      const isSelected = selectedType && !action && !selectedDocumentId
      return (
        <Pane
          {...this.props}
          renderMenu={this.renderDocumentsPaneMenu}
          renderFunctions={this.renderFunctions}
          defaultWidth={200}
          isCollapsed={isCollapsed}
          onMenuToggle={this.handleToggleMenu}
          scrollTop={this.state.scrollTop}
          isSelected={isSelected}
        >
          <QueryContainer
            query={query}
            params={params}
            type={schemaType}
            selectedId={selectedDocumentId}
            settings={settings}
          >
            {({result, loading, error, onRetry, type}) => {
              if (error) {
                return (
                  <Snackbar kind="danger" action={{title: 'Retry'}} onAction={onRetry}>

An error occurred while loading items:

{error.message}

                  </Snackbar>
                )
              }

              const items = removePublishedWithDrafts(result ? result.documents : [])

              if (!loading && (!items || items.length === 0)) {
                return (

                        There are no documents of type {type.title} yet.

                      {get(this.props, 'router.state.action') !== 'edit' && (
                        <Button color="primary" icon={PlusIcon} onClick={this.handleGoToCreateNew}>
                          New {type.title}
                        </Button>
                      )}

                )
              }

              return (
                <div className={styles[`layout__${settings.listLayout}`]}>
                  {loading && <Spinner center message="Loading items…" />}
                  {items && (
                    <ListView
                      onScroll={this.handleScroll}
                      items={items}
                      getItemKey={getDocumentKey}
                      renderItem={this.renderDocumentPaneItem}
                      listLayout={settings.listLayout}
                    />
                  )}

              )
            }}
          </QueryContainer>
        </Pane>
      )
    }
  }
)
<commit_msg>[desk-tool] Check event existence before attempting to stop propagation<commit_after>import PropTypes from 'prop-types'
import React from 'react'
import Spinner from 'part:@sanity/components/loading/spinner'
import styles from './styles/DocumentsPane.css'
import {StateLink, IntentLink, withRouterHOC} from 'part:@sanity/base/router'
import SortIcon from 'part:@sanity/base/sort-icon'
import Ink from 'react-ink'

import ListView from './ListView'
import {partition, uniqBy, get} from 'lodash'
import VisibilityOffIcon from 'part:@sanity/base/visibility-off-icon'
import EditIcon from 'part:@sanity/base/edit-icon'
import QueryContainer from 'part:@sanity/base/query-container'
import {DRAFTS_FOLDER, getPublishedId, isDraftId, getDraftId} from '../utils/draftUtils'
import {isPublishedId} from '../utils/draftUtils'
import schema from 'part:@sanity/base/schema'
import Preview from 'part:@sanity/base/preview'
import Pane from 'part:@sanity/components/panes/default'
import DocumentsPaneMenu from './DocumentsPaneMenu'
import Button from 'part:@sanity/components/buttons/default'
import PlusIcon from 'part:@sanity/base/plus-icon'
import Snackbar from 'part:@sanity/components/snackbar/default'
import {Tooltip} from '@sanity/react-tippy'
const NOOP = () => {} // eslint-disable-line

const LOCALSTORAGE_KEY = 'desk-tool.documents-pane-settings'

function readSettings() {
  return JSON.parse(window.localStorage.getItem(LOCALSTORAGE_KEY) || '{}')
}

function writeSettings(settings) {
  window.localStorage.setItem(LOCALSTORAGE_KEY, JSON.stringify(settings))
}

function getDocumentKey(document) {
  return getPublishedId(document._id)
}

function toGradientOrderClause(orderBy) {
  return orderBy
    .map(ordering => [ordering.field, ordering.direction].filter(Boolean).join(' '))
    .join(', ')
}

const ORDER_BY_UPDATED_AT = {
  title: 'Last edited',
  name: 'updatedAt',
  by: [{field: '_updatedAt', direction: 'desc'}]
}

const ORDER_BY_CREATED_AT = {
  title: 'Created',
  name: 'createdAt',
  by: [{field: '_createdAt', direction: 'desc'}]
}

const DEFAULT_SELECTED_ORDERING_OPTION = ORDER_BY_UPDATED_AT
const DEFAULT_ORDERING_OPTIONS = [ORDER_BY_UPDATED_AT, ORDER_BY_CREATED_AT]

function removePublishedWithDrafts(documents) {
  const [draftIds, publishedIds] = partition(documents.map(doc => doc._id), isDraftId)

  return documents
    .map(doc => {
      const publishedId = getPublishedId(doc._id)
      const draftId = getDraftId(doc._id)
      return {
        ...doc,
        hasPublished: publishedIds.includes(publishedId),
        hasDraft: draftIds.includes(draftId)
      }
    })
    .filter(doc => !(isPublishedId(doc._id) && doc.hasDraft))
}

function writeSettingsForType(type, settings) {
  writeSettings(
    Object.assign(readSettings(), {
      [type]: settings
    })
  )
}

export default withRouterHOC(
  class DocumentsPane extends React.PureComponent {
    static propTypes = {
      selectedType: PropTypes.string,
      selectedDocumentId: PropTypes.string,
      schemaType: PropTypes.object,
      isCollapsed: PropTypes.bool,
      router: PropTypes.object
    }

    static defaultProps = {
      loading: false,
      isCollapsed: false,
      published: [],
      drafts: [],
      onSetListLayout: NOOP
    }

    handleSetListLayout = listLayout => {
      this.setState(
        prevState => ({
          settings: {
            ...prevState.settings,
            listLayout: listLayout.key
          }
        }),
        this.writeSettings
      )
    }

    constructor(props) {
      super()
      const settings = readSettings()
      this.state = {
        settings: (settings && settings[props.selectedType]) || {
          listLayout: 'default',
          ordering: DEFAULT_SELECTED_ORDERING_OPTION
        },
        menuIsOpen: false
      }
    }

    handleSetOrdering = ordering => {
      this.setState(
        prevState => ({
          settings: {
            ...prevState.settings,
            ordering: ordering.name
          }
        }),
        this.writeSettings
      )
    }

    writeSettings() {
      writeSettingsForType(this.props.selectedType, this.state.settings)
    }

    handleToggleMenu = evt => {
      if (evt) {
        evt.stopPropagation()
      }

      this.setState(prevState => ({menuIsOpen: !prevState.menuIsOpen}))
    }

    handleCloseMenu = evt => {
      if (evt) {
        evt.stopPropagation()
      }

      this.setState(prevState => ({menuIsOpen: !prevState.menuIsOpen}))
    }

    getOrderingOptions(selectedType) {
      const type = schema.get(selectedType)

      const optionsWithDefaults = type.orderings
        ? type.orderings.concat(DEFAULT_ORDERING_OPTIONS)
        : DEFAULT_ORDERING_OPTIONS

      return uniqBy(optionsWithDefaults, 'name').map(option => {
        return {
          ...option,
          icon: option.icon || SortIcon,
          title: (

              Sort by {option.title}

          )
        }
      })
    }

    handleGoToCreateNew = () => {
      const {selectedType, router} = this.props
      router.navigateIntent('create', {type: selectedType})
    }

    renderDocumentsPaneMenu = () => {
      const {selectedType} = this.props
      const type = schema.get(selectedType)
      return (
        <DocumentsPaneMenu
          onSetListLayout={this.handleSetListLayout}
          onSetOrdering={this.handleSetOrdering}
          onGoToCreateNew={this.handleGoToCreateNew}
          onMenuClose={this.handleCloseMenu}
          onClickOutside={this.handleCloseMenu}
          isOpen={this.state.menuIsOpen}
          orderingOptions={this.getOrderingOptions(selectedType)}
          type={type}
        />
      )
    }

    renderStatus = item => {
      return (

          {!item.hasPublished && (
            <Tooltip title="Not published" arrow theme="light" distance="2" sticky size="small">

                <VisibilityOffIcon />

            </Tooltip>
          )}
          {item.hasDraft &&
            item.hasPublished && (
              <Tooltip
                title="Has changes not yet published"
                arrow
                theme="light"
                distance="2"
                sticky
                size="small"
              >

                  <EditIcon />

              </Tooltip>
            )}

      )
    }

    renderDocumentPaneItem = (item, index, options = {}) => {
      const {selectedType, selectedDocumentId} = this.props
      const {settings} = this.state

      const ordering = this.getOrderingOptions(selectedType).find(
        option => option.name === settings.ordering
      )

      const type = schema.get(selectedType)
      const linkState = {
        selectedDocumentId: getPublishedId(item._id),
        selectedType: type.name,
        action: 'edit'
      }

      const isSelected =
        selectedDocumentId && getPublishedId(item._id) === getPublishedId(selectedDocumentId)

      return (
        <StateLink state={linkState} className={styles.link} tabIndex={0}>

            <Preview
              value={item}
              ordering={ordering}
              layout={settings.listLayout}
              type={type}
              status={() => this.renderStatus(item)}
            />

          <Ink duration={1000} opacity={0.1} radius={200} />
        </StateLink>
      )
    }

    renderFunctions = isCollapsed => {
      const {selectedType} = this.props
      const type = schema.get(selectedType)
      return (
        <Button
          title={`Create new ${type.name}`}
          icon={PlusIcon}
          color="primary"
          kind="simple"
          onClick={this.handleGoToCreateNew}
        />
      )
    }

    handleScroll = scrollTop => {
      this.setState({scrollTop})
    }

    render() {
      const {selectedDocumentId, schemaType, isCollapsed, router} = this.props

      const {settings} = this.state
      const currentOrderingOption =
        this.getOrderingOptions(schemaType.name).find(
          option => option.name === settings.ordering
        ) || DEFAULT_SELECTED_ORDERING_OPTION
      const params = {type: schemaType.name, draftsPath: `${DRAFTS_FOLDER}.**`}
      const query = `*[_type == $type] | order(${toGradientOrderClause(
        currentOrderingOption.by
      )}) [0...10000] {_id, _type}`
      const {selectedType, action} = router.state
      const isSelected = selectedType && !action && !selectedDocumentId
      return (
        <Pane
          {...this.props}
          renderMenu={this.renderDocumentsPaneMenu}
          renderFunctions={this.renderFunctions}
          defaultWidth={200}
          isCollapsed={isCollapsed}
          onMenuToggle={this.handleToggleMenu}
          scrollTop={this.state.scrollTop}
          isSelected={isSelected}
        >
          <QueryContainer
            query={query}
            params={params}
            type={schemaType}
            selectedId={selectedDocumentId}
            settings={settings}
          >
            {({result, loading, error, onRetry, type}) => {
              if (error) {
                return (
                  <Snackbar kind="danger" action={{title: 'Retry'}} onAction={onRetry}>

An error occurred while loading items:

{error.message}

                  </Snackbar>
                )
              }

              const items = removePublishedWithDrafts(result ? result.documents : [])

              if (!loading && (!items || items.length === 0)) {
                return (

                        There are no documents of type {type.title} yet.

                      {get(this.props, 'router.state.action') !== 'edit' && (
                        <Button color="primary" icon={PlusIcon} onClick={this.handleGoToCreateNew}>
                          New {type.title}
                        </Button>
                      )}

                )
              }

              return (
                <div className={styles[`layout__${settings.listLayout}`]}>
                  {loading && <Spinner center message="Loading items…" />}
                  {items && (
                    <ListView
                      onScroll={this.handleScroll}
                      items={items}
                      getItemKey={getDocumentKey}
                      renderItem={this.renderDocumentPaneItem}
                      listLayout={settings.listLayout}
                    />
                  )}

              )
            }}
          </QueryContainer>
        </Pane>
      )
    }
  }
)
<|endoftext|>


<commit_before>'use strict';

var http = require('http');
var spawn = require('child_process').spawn;

http.createServer(function(req, res) {
  var json = '';

  if (req.method !== 'POST') {
    return;
  }
  if (req.headers['x-github-event'] !== 'push') {
    return;
  }

  req.on('data', function(chunk) {
    json += chunk;
  });
  req.on('end', function() {
    var data = JSON.parse(json);

    if (data.ref === 'refs/heads/master') {
      // The spawned process invokes Grunt, which will fail if run in a "detached"
      // state *without* I/O redirection.
      spawn('./deploy.sh', [], {
        detached: true,
        stdio: 'ignore'
      });
    }

    res.end();
  });
  req.on('error', function() {
    res.end();
  });
}).listen(1337, '0.0.0.0');

console.log('Server running at http://0.0.0.0:1337/');
<commit_msg>Fix bug in webhook server<commit_after>'use strict';

var http = require('http');
var spawn = require('child_process').spawn;

http.createServer(function(req, res) {
  var json = '';

  if (req.method !== 'POST') {
    return;
  }
  if (req.headers['x-github-event'] !== 'push') {
    return;
  }

  req.on('data', function(chunk) {
    json += chunk;
  });
  req.on('end', function() {
    var data = JSON.parse(json);

    if (data.ref === 'refs/heads/master') {
      // The spawned process invokes Grunt, which will fail if run in a "detached"
      // state *without* I/O redirection.
      spawn(__dirname + '/deploy.sh', [], {
        detached: true,
        stdio: 'ignore'
      });
    }

    res.end();
  });
  req.on('error', function() {
    res.end();
  });
}).listen(1337, '0.0.0.0');

console.log('Server running at http://0.0.0.0:1337/');
<|endoftext|>


<commit_before>/**
 * Developer: Stepan Burguchev
 * Date: 11/26/2014
 * Copyright: 2009-2014 Comindware®
 *       All Rights Reserved
 *
 * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF Comindware
 *       The copyright notice above does not evidence any
 *       actual or intended publication of such source code.
 */

/* global define, require, Handlebars, Backbone, Marionette, $, _ */

define(['text!../templates/popout.html', 'module/lib', 'core/utils/utilsApi', 'core/services/WindowService'],
    function (template, lib, utils, WindowService) {
        'use strict';

        var slice = Array.prototype.slice;

        var classes = {
            OPEN: 'open',
            DIRECTION_UP: 'popout__up',
            DIRECTION_DOWN: 'popout__down',
            FLOW_LEFT: 'dev-popout-flow-left',
            FLOW_RIGHT: 'dev-popout-flow-right',
            CUSTOM_ANCHOR: 'popout__action-btn',
            DEFAULT_ANCHOR: 'popout__action'
        };

        var config = {
            BOTTOM_HEIGHT_OFFSET: 20,
            TRIANGLE_WIDTH: 16,
            PANEL_OFFSET: 8
        };

        var popoutFlow = {
            LEFT: 'left',
            RIGHT: 'right'
        };

        var popoutDirection = {
            UP: 'up',
            DOWN: 'down'
        };

        var height = {
            AUTO: 'auto',
            BOTTOM: 'bottom'
        };

        var defaultOptions = {
            popoutFlow: popoutFlow.LEFT,
            customAnchor: false,
            fade: false,
            height: 'auto',
            autoOpen: true,
            direction: popoutDirection.DOWN
        };

        return Marionette.LayoutView.extend({
            initialize: function (options) {
                _.extend(this.options, _.clone(defaultOptions), options || {});
                utils.helpers.ensureOption(options, 'buttonView');
                utils.helpers.ensureOption(options, 'panelView');
                _.bindAll(this, 'open', 'close', '__handleBlur', '__handleWindowResize');
            },

            template: Handlebars.compile(template),

            className: 'popout',

            regions: {
                buttonRegion: '.js-button-region',
                panelRegion: '.js-panel-region'
            },

            ui: {
                button: '.js-button-region',
                panel: '.js-panel-region'
            },

            events: {
                'click @ui.button': '__handleClick',
                'blur @ui.panel': '__handleBlur'
            },

            onRender: function () {
                //noinspection JSValidateTypes
                this.isOpen = false;
                if (this.button) {
                    this.stopListening(this.button);
                }
                this.button = new this.options.buttonView(_.result(this.options, 'buttonViewOptions'));
                this.listenTo(this.button, 'all', function () {
                    var args = slice.call(arguments);
                    args[0] = 'button:' + args[0];
                    this.triggerMethod.apply(this, args);
                });
                this.buttonRegion.show(this.button);

                if (this.options.popoutFlow === popoutFlow.LEFT) {
                    this.ui.panel.addClass(classes.FLOW_LEFT);
                    this.ui.panel.removeClass(classes.FLOW_RIGHT);
                } else {
                    this.ui.panel.addClass(classes.FLOW_RIGHT);
                    this.ui.panel.removeClass(classes.FLOW_LEFT);
                }
                if (this.options.customAnchor) {
                    this.ui.button.addClass(classes.CUSTOM_ANCHOR);
                } else {
                    this.ui.button.addClass(classes.DEFAULT_ANCHOR);
                }

                this.currentDirection = this.options.direction;
                this.updateDirectionClasses();
            },

            updatePanelFlow: function () {
                var rect = {},
                    leftPos = 0,
                    rightPos = 0,
                    triangleWidth = config.TRIANGLE_WIDTH,
                    panelOffset = config.PANEL_OFFSET,
                    isFlowRight = this.options.popoutFlow === popoutFlow.RIGHT;

                if (this.options.customAnchor) {
                    rect = this.button.$el.find('.js-anchor')[0].getBoundingClientRect();
                    if (isFlowRight) {
                        leftPos = rect.width / 2 - triangleWidth / 2 - panelOffset;
                    } else {
                        rightPos = this.button.$el.width() - rect.width + rect.width / 2 - triangleWidth / 2 - panelOffset;
                    }
                } else {
                    rect = this.ui.button[0].getBoundingClientRect();
                    if (isFlowRight) {
                        leftPos = rect.width - triangleWidth - panelOffset;
                    } else {
                        rightPos = -panelOffset;
                    }
                }

                if (isFlowRight) {
                    this.panelRegion.$el.css({
                        left: leftPos
                    });
                } else {
                    this.panelRegion.$el.css({
                        right: rightPos
                    });
                }
            },

            updateDirectionClasses: function () {
                if (this.currentDirection === popoutDirection.UP) {
                    this.ui.button.addClass(classes.DIRECTION_UP);
                    this.ui.button.removeClass(classes.DIRECTION_DOWN);

                    if (this.panelRegion.$el) {
                        this.panelRegion.$el.removeClass(classes.DIRECTION_DOWN);
                        this.panelRegion.$el.addClass(classes.DIRECTION_UP);
                    }
                } else {
                    this.ui.button.addClass(classes.DIRECTION_DOWN);
                    this.ui.button.removeClass(classes.DIRECTION_UP);

                    if (this.panelRegion.$el) {
                        this.panelRegion.$el.removeClass(classes.DIRECTION_UP);
                        this.panelRegion.$el.addClass(classes.DIRECTION_DOWN);
                    }
                }
            },

            __handleClick: function () {
                if (this.options.autoOpen) {
                    this.open();
                }
            },

            open: function () {
                if (this.isOpen) {
                    return;
                }
                this.trigger('before:open', this);

                var panelViewOptions = _.extend(_.result(this.options, 'panelViewOptions') || {}, {
                    parent: this
                });
                if (this.panelView) {
                    this.stopListening(this.panelView);
                }
                this.panelView = new this.options.panelView(panelViewOptions);
                this.listenTo(this.panelView, 'all', function () {
                    var args = slice.call(arguments);
                    args[0] = 'panel:' + args[0];
                    this.triggerMethod.apply(this, args);
                });
                this.$el.addClass(classes.OPEN);
                if (this.options.fade) {
                    WindowService.fadeIn();
                }
                this.ui.panel.css('display', 'block');
                this.ui.panel.show({
                    duration: 0,
                    complete: function () {
                        this.panelRegion.show(this.panelView);
                        if (this.options.height === height.BOTTOM) {
                            $(window).on('resize', this.__handleWindowResize);
                            this.__handleWindowResize();
                        }
                        this.correctDirection();
                        this.updatePanelFlow();
                        this.focus();
                        //noinspection JSValidateTypes
                        this.isOpen = true;
                        this.trigger('open', this);
                    }.bind(this)
                });
            },

            correctDirection: function () {
                var panelHeight = this.panelRegion.$el.height(),
                    viewportHeight = window.innerHeight,
                    panelTopOffset = $(this.panelRegion.$el)[0].getBoundingClientRect().top;

                if (this.currentDirection === popoutDirection.UP && panelTopOffset < panelHeight) {
                    this.currentDirection = popoutDirection.DOWN;
                    this.updateDirectionClasses();
                } else if (this.currentDirection === popoutDirection.DOWN && viewportHeight - panelTopOffset < panelHeight) {
                    this.currentDirection = popoutDirection.UP;
                    this.panelRegion.$el.css({
                        top: -(panelHeight + config.BOTTOM_HEIGHT_OFFSET)
                    });
                    this.updateDirectionClasses();
                }
            },

            close: function () {
                if (!this.isOpen || !$.contains(document.documentElement, this.el)) {
                    return;
                }
                this.trigger('before:close', this);
                if (this.options.fade) {
                    WindowService.fadeOut();
                }
                if (this.options.height === height.BOTTOM) {
                    $(window).off('resize', this.__handleWindowResize);
                }
                this.ui.panel.hide({
                    duration: 0,
                    complete: function () {
                        this.$el.removeClass(classes.OPEN);
                        this.panelRegion.reset();
                        //noinspection JSValidateTypes
                        this.isOpen = false;
                        this.ui.panel.blur();
                        this.render();
                        this.trigger('close', this);
                    }.bind(this)
                });
            },

            focus: function () {
                this.ui.panel.focus();
            },

            __handleBlur: function () {
                setTimeout(function () {
                    if (this.$el.find(document.activeElement).length > 0) {
                        $(document.activeElement).one('blur', this.__handleBlur);
                    } else {
                        this.close();
                    }
                }.bind(this), 15);
            },

            __handleWindowResize: function () {
                var outlineDiff = (this.panelView.$el.outerHeight() - this.panelView.$el.height());
                var panelHeight = $(window).height() - this.panelView.$el.offset().top - outlineDiff - config.BOTTOM_HEIGHT_OFFSET;
                this.panelView.$el.height(panelHeight);
            }
        });
    });
<commit_msg>Fix dropdown position<commit_after>/**
 * Developer: Stepan Burguchev
 * Date: 11/26/2014
 * Copyright: 2009-2014 Comindware®
 *       All Rights Reserved
 *
 * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF Comindware
 *       The copyright notice above does not evidence any
 *       actual or intended publication of such source code.
 */

/* global define, require, Handlebars, Backbone, Marionette, $, _ */

define(['text!../templates/popout.html', 'module/lib', 'core/utils/utilsApi', 'core/services/WindowService'],
    function (template, lib, utils, WindowService) {
        'use strict';

        var slice = Array.prototype.slice;

        var classes = {
            OPEN: 'open',
            DIRECTION_UP: 'popout__up',
            DIRECTION_DOWN: 'popout__down',
            FLOW_LEFT: 'dev-popout-flow-left',
            FLOW_RIGHT: 'dev-popout-flow-right',
            CUSTOM_ANCHOR: 'popout__action-btn',
            DEFAULT_ANCHOR: 'popout__action'
        };

        var config = {
            BOTTOM_HEIGHT_OFFSET: 20,
            TRIANGLE_WIDTH: 16,
            PANEL_OFFSET: 8
        };

        var popoutFlow = {
            LEFT: 'left',
            RIGHT: 'right'
        };

        var popoutDirection = {
            UP: 'up',
            DOWN: 'down'
        };

        var height = {
            AUTO: 'auto',
            BOTTOM: 'bottom'
        };

        var defaultOptions = {
            popoutFlow: popoutFlow.LEFT,
            customAnchor: false,
            fade: false,
            height: 'auto',
            autoOpen: true,
            direction: popoutDirection.DOWN
        };

        return Marionette.LayoutView.extend({
            initialize: function (options) {
                _.defaults(this.options, defaultOptions);
                utils.helpers.ensureOption(options, 'buttonView');
                utils.helpers.ensureOption(options, 'panelView');
                _.bindAll(this, 'open', 'close', '__handleBlur', '__handleWindowResize');
            },

            template: Handlebars.compile(template),

            className: 'popout',

            regions: {
                buttonRegion: '.js-button-region',
                panelRegion: '.js-panel-region'
            },

            ui: {
                button: '.js-button-region',
                panel: '.js-panel-region'
            },

            events: {
                'click @ui.button': '__handleClick',
                'blur @ui.panel': '__handleBlur'
            },

            onRender: function () {
                //noinspection JSValidateTypes
                this.isOpen = false;
                if (this.button) {
                    this.stopListening(this.button);
                }
                this.button = new this.options.buttonView(_.result(this.options, 'buttonViewOptions'));
                this.listenTo(this.button, 'all', function () {
                    var args = slice.call(arguments);
                    args[0] = 'button:' + args[0];
                    this.triggerMethod.apply(this, args);
                });
                this.buttonRegion.show(this.button);

                if (this.options.popoutFlow === popoutFlow.LEFT) {
                    this.ui.panel.addClass(classes.FLOW_LEFT);
                    this.ui.panel.removeClass(classes.FLOW_RIGHT);
                } else {
                    this.ui.panel.addClass(classes.FLOW_RIGHT);
                    this.ui.panel.removeClass(classes.FLOW_LEFT);
                }
                if (this.options.customAnchor) {
                    this.ui.button.addClass(classes.CUSTOM_ANCHOR);
                } else {
                    this.ui.button.addClass(classes.DEFAULT_ANCHOR);
                }

                this.currentDirection = this.options.direction;
                this.updateDirectionClasses();
            },

            updatePanelFlow: function () {
                var rect = {},
                    leftPos = 0,
                    rightPos = 0,
                    triangleWidth = config.TRIANGLE_WIDTH,
                    panelOffset = config.PANEL_OFFSET,
                    isFlowRight = this.options.popoutFlow === popoutFlow.RIGHT;

                if (this.options.customAnchor) {
                    rect = this.button.$el.find('.js-anchor')[0].getBoundingClientRect();
                    if (isFlowRight) {
                        rightPos = this.button.$el.width() - rect.width + rect.width / 2 - triangleWidth / 2 - panelOffset;
                    } else {
                        leftPos = rect.width / 2 - triangleWidth / 2 - panelOffset;
                    }
                } else {
                    rect = this.ui.button[0].getBoundingClientRect();
                    if (isFlowRight) {
                        leftPos = rect.width - triangleWidth - panelOffset;
                    } else {
                        rightPos = -panelOffset;
                    }
                }

                if (isFlowRight) {
                    this.panelRegion.$el.css({
                        left: leftPos
                    });
                } else {
                    this.panelRegion.$el.css({
                        right: rightPos
                    });
                }
            },

            updateDirectionClasses: function () {
                if (this.currentDirection === popoutDirection.UP) {
                    this.ui.button.addClass(classes.DIRECTION_UP);
                    this.ui.button.removeClass(classes.DIRECTION_DOWN);

                    if (this.panelRegion.$el) {
                        this.panelRegion.$el.removeClass(classes.DIRECTION_DOWN);
                        this.panelRegion.$el.addClass(classes.DIRECTION_UP);
                    }
                } else {
                    this.ui.button.addClass(classes.DIRECTION_DOWN);
                    this.ui.button.removeClass(classes.DIRECTION_UP);

                    if (this.panelRegion.$el) {
                        this.panelRegion.$el.removeClass(classes.DIRECTION_UP);
                        this.panelRegion.$el.addClass(classes.DIRECTION_DOWN);
                    }
                }
            },

            __handleClick: function () {
                if (this.options.autoOpen) {
                    this.open();
                }
            },

            open: function () {
                if (this.isOpen) {
                    return;
                }
                this.trigger('before:open', this);

                var panelViewOptions = _.extend(_.result(this.options, 'panelViewOptions') || {}, {
                    parent: this
                });
                if (this.panelView) {
                    this.stopListening(this.panelView);
                }
                this.panelView = new this.options.panelView(panelViewOptions);
                this.listenTo(this.panelView, 'all', function () {
                    var args = slice.call(arguments);
                    args[0] = 'panel:' + args[0];
                    this.triggerMethod.apply(this, args);
                });
                this.$el.addClass(classes.OPEN);
                if (this.options.fade) {
                    WindowService.fadeIn();
                }
                this.ui.panel.css('display', 'block');
                this.ui.panel.show({
                    duration: 0,
                    complete: function () {
                        this.panelRegion.show(this.panelView);
                        if (this.options.height === height.BOTTOM) {
                            $(window).on('resize', this.__handleWindowResize);
                            this.__handleWindowResize();
                        }
                        this.correctDirection();
                        this.updatePanelFlow();
                        this.focus();
                        //noinspection JSValidateTypes
                        this.isOpen = true;
                        this.trigger('open', this);
                    }.bind(this)
                });
            },

            correctDirection: function () {
                var panelHeight = this.panelRegion.$el.height(),
                    viewportHeight = window.innerHeight,
                    panelTopOffset = $(this.panelRegion.$el)[0].getBoundingClientRect().top;

                if (this.currentDirection === popoutDirection.UP && panelTopOffset < panelHeight) {
                    this.currentDirection = popoutDirection.DOWN;
                    this.updateDirectionClasses();
                } else if (this.currentDirection === popoutDirection.DOWN && viewportHeight - panelTopOffset < panelHeight) {
                    this.currentDirection = popoutDirection.UP;
                    this.panelRegion.$el.css({
                        top: -(panelHeight + config.BOTTOM_HEIGHT_OFFSET)
                    });
                    this.updateDirectionClasses();
                }
            },

            close: function () {
                if (!this.isOpen || !$.contains(document.documentElement, this.el)) {
                    return;
                }
                this.trigger('before:close', this);
                if (this.options.fade) {
                    WindowService.fadeOut();
                }
                if (this.options.height === height.BOTTOM) {
                    $(window).off('resize', this.__handleWindowResize);
                }
                this.ui.panel.hide({
                    duration: 0,
                    complete: function () {
                        this.$el.removeClass(classes.OPEN);
                        this.panelRegion.reset();
                        //noinspection JSValidateTypes
                        this.isOpen = false;
                        this.ui.panel.blur();
                        this.render();
                        this.trigger('close', this);
                    }.bind(this)
                });
            },

            focus: function () {
                this.ui.panel.focus();
            },

            __handleBlur: function () {
                setTimeout(function () {
                    if (this.$el.find(document.activeElement).length > 0) {
                        $(document.activeElement).one('blur', this.__handleBlur);
                    } else {
                        this.close();
                    }
                }.bind(this), 15);
            },

            __handleWindowResize: function () {
                var outlineDiff = (this.panelView.$el.outerHeight() - this.panelView.$el.height());
                var panelHeight = $(window).height() - this.panelView.$el.offset().top - outlineDiff - config.BOTTOM_HEIGHT_OFFSET;
                this.panelView.$el.height(panelHeight);
            }
        });
    });
<|endoftext|>


<commit_before>/**
 * Copyright 2014 Flipkart Internet Pvt. Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
function BarTile() {
  this.newDiv = "";
  this.object = "";
}

function getBarChartFormValues() {
  var period = $(".bar-time-unit").val();
  var timeframe = $(".bar-timeframe").val();
  var eventField = $(".bar-event-field").val();
  var uniqueKey = $(".bar-uniquekey").val();
  if (eventField == "none") {
    return [[], false];
  }
  var groupingString = currentFieldList[parseInt(eventField)].field;
  var status = true;
  if (!$("#bar-time-unit").valid() || !$("#bar-timeframe").valid()) {
    status = false;
  }
  return [{
    "period": period
    , "timeframe": timeframe
    , "nesting": [groupingString]
    , "uniqueKey": uniqueKey
  }, status]
}

function setBarChartFormValues(object) {
  console.log(object)
  $(".bar-time-unit").val(object.tileContext.period);
  $(".bar-time-unit").selectpicker('refresh');
  $(".bar-timeframe").val(object.tileContext.timeframe);
  $(".bar-event-field").val(currentFieldList.findIndex(x => x.field == object.tileContext.nesting[0]));
  $(".bar-event-field").selectpicker('refresh');
  $(".bar-uniquekey").val(currentFieldList.findIndex(x => x.field == object.tileContext.uniqueKey));
  $(".bar-uniquekey").selectpicker('refresh');
}

function clearBarChartForm() {
  var parentElement = $("#" + currentChartType + "-chart-data");
  var timeUnitEl = parentElement.find(".bar-time-unit");
  timeUnitEl.find('option:eq(0)').prop('selected', true);
  $(timeUnitEl).selectpicker('refresh');
  var timeframe = parentElement.find(".bar-timeframe");
  timeframe.val('');
  var groupingKey = parentElement.find(".bar-event-field");
  groupingKey.find('option:eq(0)').prop('selected', true);
  $(groupingKey).selectpicker('refresh');
  var stackingBarUniqueKey = parentElement.find(".bar-uniquekey");
  stackingBarUniqueKey.find('option:eq(0)').prop('selected', true);
  $(stackingBarUniqueKey).selectpicker('refresh');
}
BarTile.prototype.getQuery = function (newDiv, object) {
  this.newDiv = newDiv;
  this.object = object;
  this.object.tileContext.filters.pop();
  object.tileContext.filters.push(timeValue(object.tileContext.period, object.tileContext.timeframe, getPeriodSelect(object.id)))
  var data = {
    "opcode": "group"
    , "table": object.tileContext.table
    , "filters": object.tileContext.filters
    , "uniqueCountOn": object.tileContext.uniqueCountOn && object.tileContext.uniqueCountOn != "none" ? object.tileContext.uniqueCountOn : null
    , "nesting": object.tileContext.nesting
  }
  $.ajax({
    method: "post"
    , dataType: 'json'
    , accepts: {
      json: 'application/json'
    }
    , url: apiUrl + "/v1/analytics"
    , contentType: "application/json"
    , data: JSON.stringify(data)
    , success: $.proxy(this.getData, this)
  });
}
BarTile.prototype.getData = function (data) {
  this.object.tileContext.filters.pop();
  if (data.result == undefined || data.result.length == 0) return;
  var colors = new Colors(Object.keys(data.result).length);
  var columns = [];
  var ticks = [];
  var i = 0;
  this.uniqueValues = [];
  var flatData = [];
  for (property in data.result) {
    var value = data.result[property] / Math.pow(10, 2);
    var dataElement = {
      label: property
      , data: [[i, value]]
      , color: colors.nextColor()
    };
    columns.push(dataElement);
    ticks.push([i, property]);
    flatData.push({
      label: property
      , data: value
      , color: dataElement.color
    });
    this.object.tileContext.uiFiltersList = [];
    this.object.tileContext.uiFiltersList.push(property);
    i++;
  }
  var xAxisOptions = {
    tickLength: 0
    , labelWidth: 0
  };
  var tmpLabel = "";
  for (var i = 0; i < ticks.length; i++) {
    tmpLabel += (ticks[i][1] + " ");
  }
  /*if (tmpLabel.visualLength() <= parentWidth) {
    xAxisOptions['ticks'] = ticks;
    xAxisOptions['tickFormatter'] = null;
  }
  else {
    xAxisOptions['ticks'] = null;
    xAxisOptions['tickFormatter'] = function () {
      return "";
    }
  }*/
  xAxisOptions['ticks'] = null;
  xAxisOptions['tickFormatter'] = function () {
    return "";
  }
  this.render(xAxisOptions, columns);
  console.log(xAxisOptions);
}
BarTile.prototype.render = function (xAxisOptions, columns) {
  console.log(columns);
  var newDiv = this.newDiv;
  var object = this.object;
  var chartDiv = newDiv.find(".chart-item");
  console.log(object.id);
  var ctx = chartDiv.find("#" + object.id);
  ctx.width(ctx.width);
  ctx.height(230);
  var chartOptions = {
    series: {
      bars: {
        show: true
        , label: {
          show: true
        }
        , barWidth: 0.5
        , align: "center"
        , lineWidth: 1.0
        , fill: true
        , fillColor: {
          colors: [{
            opacity: 0.3
          }, {
            opacity: 0.7
          }]
        }
      }
      , valueLabels: {
        show: true
      }
    }
    , legend: {
      show: false
    }
    , yaxis: {
      tickLength: 0,
      tickFormatter: function(val, axis) {
        return numDifferentiation(val);
      },
    }
    , xaxis: xAxisOptions,
    grid: {
      hoverable: true
      , color: "#B2B2B2"
      , show: true
      , borderWidth: {
        top: 0
        , right: 0
        , bottom: 1
        , left: 1
      }
      , borderColor: "#EEEEEE"
    }
    , tooltip: true
    , tooltipOpts: {
      content: function (label, x, y) {
        return label + ": " + y;
      }
    }
    ,legend: {
      show: true
      , noColumns: getLegendColumn(object.tileContext.widgetType)
      , labelFormatter: function (label, series) {
        return '  ' + label + '  ';
      }
      , container: $(chartDiv.find(".legend"))
    }
  };
  $.plot(ctx, columns, chartOptions);
}
<commit_msg>bar tile filter fix<commit_after>/**
 * Copyright 2014 Flipkart Internet Pvt. Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
function BarTile() {
  this.newDiv = "";
  this.object = "";
}

function getBarChartFormValues() {
  var period = $(".bar-time-unit").val();
  var timeframe = $(".bar-timeframe").val();
  var eventField = $(".bar-event-field").val();
  var uniqueKey = $(".bar-uniquekey").val();
  if (eventField == "none") {
    return [[], false];
  }
  var groupingString = currentFieldList[parseInt(eventField)].field;
  var status = true;
  if (!$("#bar-time-unit").valid() || !$("#bar-timeframe").valid()) {
    status = false;
  }
  return [{
    "period": period
    , "timeframe": timeframe
    , "nesting": [groupingString]
    , "uniqueKey": uniqueKey
  }, status]
}

function setBarChartFormValues(object) {
  console.log(object)
  $(".bar-time-unit").val(object.tileContext.period);
  $(".bar-time-unit").selectpicker('refresh');
  $(".bar-timeframe").val(object.tileContext.timeframe);
  $(".bar-event-field").val(currentFieldList.findIndex(x => x.field == object.tileContext.nesting[0]));
  $(".bar-event-field").selectpicker('refresh');
  $(".bar-uniquekey").val(currentFieldList.findIndex(x => x.field == object.tileContext.uniqueKey));
  $(".bar-uniquekey").selectpicker('refresh');
}

function clearBarChartForm() {
  var parentElement = $("#" + currentChartType + "-chart-data");
  var timeUnitEl = parentElement.find(".bar-time-unit");
  timeUnitEl.find('option:eq(0)').prop('selected', true);
  $(timeUnitEl).selectpicker('refresh');
  var timeframe = parentElement.find(".bar-timeframe");
  timeframe.val('');
  var groupingKey = parentElement.find(".bar-event-field");
  groupingKey.find('option:eq(0)').prop('selected', true);
  $(groupingKey).selectpicker('refresh');
  var stackingBarUniqueKey = parentElement.find(".bar-uniquekey");
  stackingBarUniqueKey.find('option:eq(0)').prop('selected', true);
  $(stackingBarUniqueKey).selectpicker('refresh');
}
BarTile.prototype.getQuery = function (newDiv, object) {
  this.newDiv = newDiv;
  this.object = object;
  this.object.tileContext.filters.pop();
  object.tileContext.filters.push(timeValue(object.tileContext.period, object.tileContext.timeframe, getPeriodSelect(object.id)))
  var data = {
    "opcode": "group"
    , "table": object.tileContext.table
    , "filters": object.tileContext.filters
    , "uniqueCountOn": object.tileContext.uniqueCountOn && object.tileContext.uniqueCountOn != "none" ? object.tileContext.uniqueCountOn : null
    , "nesting": object.tileContext.nesting
  }
  $.ajax({
    method: "post"
    , dataType: 'json'
    , accepts: {
      json: 'application/json'
    }
    , url: apiUrl + "/v1/analytics"
    , contentType: "application/json"
    , data: JSON.stringify(data)
    , success: $.proxy(this.getData, this)
  });
}
BarTile.prototype.getData = function (data) {
  this.object.tileContext.filters.pop();
  if(this.object.tileContext.uiFiltersList == undefined) {
    this.object.tileContext.uiFiltersList = [];
    this.object.tileContext.uiFiltersSelectedList = [];
  }

  if (data.result == undefined || data.result.length == 0) return;
  var colors = new Colors(Object.keys(data.result).length);
  var columns = [];
  var ticks = [];
  var i = 0;
  this.uniqueValues = [];
  var flatData = [];
  this.object.tileContext.uiFiltersList = [];
  for (property in data.result) {
    var value = data.result[property] / Math.pow(10, 2);
    var visible = $.inArray( property, this.object.tileContext.uiFiltersSelectedList);
    if((visible == -1 ? true : false)) {
      var dataElement = {
        label: property
        , data: [[i, value]]
        , color: colors.nextColor()
      };
      columns.push(dataElement);
      ticks.push([i, property]);
      flatData.push({
        label: property
        , data: value
        , color: dataElement.color
      });
    }
    this.object.tileContext.uiFiltersList.push(property);
    i++;
  }
  var xAxisOptions = {
    tickLength: 0
    , labelWidth: 0
  };
  var tmpLabel = "";
  for (var i = 0; i < ticks.length; i++) {
    tmpLabel += (ticks[i][1] + " ");
  }
  /*if (tmpLabel.visualLength() <= parentWidth) {
    xAxisOptions['ticks'] = ticks;
    xAxisOptions['tickFormatter'] = null;
  }
  else {
    xAxisOptions['ticks'] = null;
    xAxisOptions['tickFormatter'] = function () {
      return "";
    }
  }*/
  xAxisOptions['ticks'] = null;
  xAxisOptions['tickFormatter'] = function () {
    return "";
  }
  this.render(xAxisOptions, columns);
  console.log(xAxisOptions);
}
BarTile.prototype.render = function (xAxisOptions, columns) {
  console.log(columns);
  var newDiv = this.newDiv;
  var object = this.object;
  var chartDiv = newDiv.find(".chart-item");
  console.log(object.id);
  var ctx = chartDiv.find("#" + object.id);
  ctx.width(ctx.width);
  ctx.height(230);
  var chartOptions = {
    series: {
      bars: {
        show: true
        , label: {
          show: true
        }
        , barWidth: 0.5
        , align: "center"
        , lineWidth: 1.0
        , fill: true
        , fillColor: {
          colors: [{
            opacity: 0.3
          }, {
            opacity: 0.7
          }]
        }
      }
      , valueLabels: {
        show: true
      }
    }
    , legend: {
      show: false
    }
    , yaxis: {
      tickLength: 0,
      tickFormatter: function(val, axis) {
        return numDifferentiation(val);
      },
    }
    , xaxis: xAxisOptions,
    grid: {
      hoverable: true
      , color: "#B2B2B2"
      , show: true
      , borderWidth: {
        top: 0
        , right: 0
        , bottom: 1
        , left: 1
      }
      , borderColor: "#EEEEEE"
    }
    , tooltip: true
    , tooltipOpts: {
      content: function (label, x, y) {
        return label + ": " + y;
      }
    }
    ,legend: {
      show: true
      , noColumns: getLegendColumn(object.tileContext.widgetType)
      , labelFormatter: function (label, series) {
        return '  ' + label + '  ';
      }
      , container: $(chartDiv.find(".legend"))
    }
  };
  $.plot(ctx, columns, chartOptions);
}
<|endoftext|>


<commit_before>#!/usr/bin/env node

var routes = require('./lib/routes.js');
var videos = require('./lib/videos.js');
var async = require('async');

var sourceIndividual;
var seenIndividuals = [];
var seenTracks = [];
var seenArtists = [];

var error = function (err) {
	if (err) {
		console.log('Error: ', err.message);
		process.exit(1);
	}
};

var random = function (array) {
	return array[Math.floor(Math.random()*array.length)];
};

var valuesNotIn = function (values, notIn) {
	// returns values from values that are not in notIn
	return values.filter( function (value) {
		return notIn.indexOf( value ) === -1;
	});
};

var generatePlaylist = function (individual, done) {
	var callback = 	function (err, tracks) {
		error(err);
		var track;

		var notSeenTracks = valuesNotIn(tracks, seenTracks);
		if (notSeenTracks.length > 0) {
			track = random(notSeenTracks);
			seenTracks.push(track);
		} else {
			track = random(tracks);
		}
		if (! track) {
			nextIndex = nextIndex +1;
			next[nextIndex]();
			return;
		}
		routes.getTrackDetails(track, function (err, details) {
			error(err);

			if (!details) {
				error(new Error('No details for ' + track));
			}

			var theseArtistMids = details.artists.map(function (value) { return value.mid; });
			seenArtists = seenArtists.concat(valuesNotIn(theseArtistMids, seenArtists));
			var name = details.name || 'WHOOPS, FREEBASE DOES NOT APPEAR TO HAVE AN ENGLISH NAME FOR THIS TRACK';
			var artist = details.artists.map(function (value) {
				return value.name || 'WHOOPS, FREEBASE DOES NOT APPEAR TO HAVE AN ENGLISH NAME FOR THIS ARTIST';
			}).join(' & ');
			var release = random(details.releases).name || 'WHOOPS, FREEBASE DOES NOT APPEAR TO HAVE AN ENGLISH NAME FOR THIS RELEASE';

			var output = '"' + name + '"';
			output += '\n' + artist;
			output += '\n_' + release + '_';

			var q = '"' + name + '" "' + artist + '" "' + release + '"';
			console.log(output);

			videos.search(q, function (err, data) {
				if (data && data.items && data.items[0] && data.items[0].url) {
					console.log(data.items[0].url);
				}

				routes.getArtistsAndContributorsFromTracks([track], function (err, contributors) {
					error(err);
					var contributor;
					var notSeen = valuesNotIn(contributors, seenIndividuals);
					if (notSeen.length > 0) {
						contributor = random(notSeen);
						seenIndividuals.push(contributor);
					} else {
						contributor = random(contributors);
					}
					routes.getArtistDetails(contributor, function (err, details) {
						var name = details.name || 'WHOOPS, FREEBASE DOES NOT HAVE AN ENGLISH NAME FOR THIS PERSON';
						console.log('\n ... with ' + name + ' ... \n');
						sourceIndividual = contributor;
						done();
					});
				});
			});
		});
	};

	var options = {subquery: {
		artist: [{
					'mid|=': seenArtists,
					optional: 'forbidden'
		}]
	}};

	// next[nextIndex] = what function to invoke if the current one doesn't find a track
	var nextIndex = 0;
	var next = [
		// Find a track by an artist we haven't seen yet.
		function () {
			if (seenArtists.length === 0) {
				// If this is the first track, get one by this artist if we can.
				routes.getTracksByArtists([individual], {}, callback);
			} else {
				// Otherwise, get one by an artist we haven't seen yet
				routes.getTracksWithContributors([individual], options, callback);
			}
		},
		routes.getTracksWithContributors.bind(undefined, [individual], options, callback),
		// Look for any track with this contributor credited as a contributor regardless if we've seen the artist already.
		routes.getTracksWithContributors.bind(undefined, [individual], {}, callback),
		// Look for any tracks actually credited to this contributor as the main artist. We are desperate!
		routes.getTracksByArtists.bind(undefined, [individual], {}, callback),
		// Give up
		error.bind(undefined, new Error('Could not find any tracks for contributor ' + individual))
	];

	// Kick it off
	next[nextIndex]();
};

var startingPoint = process.argv[2] || 'Todd Rundgren';
routes.getMids(startingPoint, '/music/artist', function (err, mids) {
	error(err);
	sourceIndividual = mids[0];
	if (! sourceIndividual) {
		console.log('Could not find an artist named ' + process.argv[2]);
		process.exit(0);
	}
	seenIndividuals.push(sourceIndividual);
	async.forever(
		function (next) {
			generatePlaylist(sourceIndividual, next);
		},
		error
	);
});<commit_msg>need to check for errors<commit_after>#!/usr/bin/env node

var routes = require('./lib/routes.js');
var videos = require('./lib/videos.js');
var async = require('async');

var sourceIndividual;
var seenIndividuals = [];
var seenTracks = [];
var seenArtists = [];

var error = function (err) {
	if (err) {
		console.log('Error: ', err.message);
		process.exit(1);
	}
};

var random = function (array) {
	return array[Math.floor(Math.random()*array.length)];
};

var valuesNotIn = function (values, notIn) {
	// returns values from values that are not in notIn
	return values.filter( function (value) {
		return notIn.indexOf( value ) === -1;
	});
};

var generatePlaylist = function (individual, done) {
	var callback = 	function (err, tracks) {
		error(err);
		var track;

		var notSeenTracks = valuesNotIn(tracks, seenTracks);
		if (notSeenTracks.length > 0) {
			track = random(notSeenTracks);
			seenTracks.push(track);
		} else {
			track = random(tracks);
		}
		if (! track) {
			nextIndex = nextIndex +1;
			next[nextIndex]();
			return;
		}
		routes.getTrackDetails(track, function (err, details) {
			error(err);

			if (!details) {
				error(new Error('No details for ' + track));
			}

			var theseArtistMids = details.artists.map(function (value) { return value.mid; });
			seenArtists = seenArtists.concat(valuesNotIn(theseArtistMids, seenArtists));
			var name = details.name || 'WHOOPS, FREEBASE DOES NOT APPEAR TO HAVE AN ENGLISH NAME FOR THIS TRACK';
			var artist = details.artists.map(function (value) {
				return value.name || 'WHOOPS, FREEBASE DOES NOT APPEAR TO HAVE AN ENGLISH NAME FOR THIS ARTIST';
			}).join(' & ');
			var release = random(details.releases).name || 'WHOOPS, FREEBASE DOES NOT APPEAR TO HAVE AN ENGLISH NAME FOR THIS RELEASE';

			var output = '"' + name + '"';
			output += '\n' + artist;
			output += '\n_' + release + '_';

			var q = '"' + name + '" "' + artist + '" "' + release + '"';
			console.log(output);

			videos.search(q, function (err, data) {
				if (data && data.items && data.items[0] && data.items[0].url) {
					console.log(data.items[0].url);
				}

				routes.getArtistsAndContributorsFromTracks([track], function (err, contributors) {
					error(err);
					var contributor;
					var notSeen = valuesNotIn(contributors, seenIndividuals);
					if (notSeen.length > 0) {
						contributor = random(notSeen);
						seenIndividuals.push(contributor);
					} else {
						contributor = random(contributors);
					}
					routes.getArtistDetails(contributor, function (err, details) {
						error(err);
						var name = details.name || 'WHOOPS, FREEBASE DOES NOT HAVE AN ENGLISH NAME FOR THIS PERSON';
						console.log('\n ... with ' + name + ' ... \n');
						sourceIndividual = contributor;
						done();
					});
				});
			});
		});
	};

	var options = {subquery: {
		artist: [{
					'mid|=': seenArtists,
					optional: 'forbidden'
		}]
	}};

	// next[nextIndex] = what function to invoke if the current one doesn't find a track
	var nextIndex = 0;
	var next = [
		// Find a track by an artist we haven't seen yet.
		function () {
			if (seenArtists.length === 0) {
				// If this is the first track, get one by this artist if we can.
				routes.getTracksByArtists([individual], {}, callback);
			} else {
				// Otherwise, get one by an artist we haven't seen yet
				routes.getTracksWithContributors([individual], options, callback);
			}
		},
		routes.getTracksWithContributors.bind(undefined, [individual], options, callback),
		// Look for any track with this contributor credited as a contributor regardless if we've seen the artist already.
		routes.getTracksWithContributors.bind(undefined, [individual], {}, callback),
		// Look for any tracks actually credited to this contributor as the main artist. We are desperate!
		routes.getTracksByArtists.bind(undefined, [individual], {}, callback),
		// Give up
		error.bind(undefined, new Error('Could not find any tracks for contributor ' + individual))
	];

	// Kick it off
	next[nextIndex]();
};

var startingPoint = process.argv[2] || 'Todd Rundgren';
routes.getMids(startingPoint, '/music/artist', function (err, mids) {
	error(err);
	sourceIndividual = mids[0];
	if (! sourceIndividual) {
		console.log('Could not find an artist named ' + process.argv[2]);
		process.exit(0);
	}
	seenIndividuals.push(sourceIndividual);
	async.forever(
		function (next) {
			generatePlaylist(sourceIndividual, next);
		},
		error
	);
});<|endoftext|>


<commit_before>var input = {
    "b": "two",
    "a": 1
}; //this is a json string used by matrix-org for test purposes

// obj.sort(function(a, b) {
//     return a.b.localeCompare(b.a);
// });
// //console.log(a.b.localeCompare(b.a));
function sortJSON() {
    JSON.stringify(input, Object.keys(input).sort());

} // has to be a function called sort SortJson

// function CanonicalJSON(input, err) {
//     for (var i = 0; i < input.length; i++) { // i guess i have to use slices innstes creating forloops
//         var sorted = sortJSON(input);

//         if (err != null) {
//             return null;
//         }
//     }
//     for (var j = 0; j < sorted.length; i++) {
//         //return compactJSON(sorted);
//     }
// }

//the basic idea is to reencode json and then arrange them into lexicographical order.
//gophers has a very copmplex way to do it,but JS is somewhat simple :)
// i guess there is nno need to use interfaces in js,as gophers use it to handle loosely handled or non-strictly typed json.<commit_msg>changes in json.js<commit_after>

//console.log(JSON.stringify(JSON.parse(input)));

// function sortFactory(prop) {
//    return function(a,b){ return a[prop].localeCompare(b[prop]); };
// }
// input.sort(function(a, b) {
//     return a.A.localeCompare(b.B);
// });

//console.log(obj);
// console.log(obj.sort(sortFactory('A'))); // sort by name property
// console.log(obj.sort(sortFactory('A'))); // sort by surname property
//this is a json string used by matrix-org for test purposes

// input.sort(function(a, b) {
//     return a.b.localeCompare(b.a);
// });

function sortJSON(input) {
    JSON.stringify(input, Object.keys(obj).sort());

} // has to be a function called sort SortJson

//console.log(JSON.stringify(input, Object.keys(obj).sort()));

function canonicalJSON(input, err) {
    for (var i = 0; i < input.length; i++) { // i guess i have to use slices innstes creating forloops
        var sorted = sortJSON(input);

        if (err != null) {
            return null;
        }
    }
    for (var j = 0; j < sorted.length; i++) {
        return compactJSON(sorted);
    }
}

function compactJSON(input, output) {
    var i;
    for (i = 0; i < input.length; i++) {
        var c = input[i];
        if (c <= ' ') {
            continue;
        }
        output.push(c);
        if (c == '""') {
            for (i = 0; i < input.length; i++) {
                c = input[i];
                if (c == "\\") {
                    var escape = input[i];
                    if (escape == "u") {
                        compactUnicodeEscape(input, output, i);
                    } else if (escape == "/") {
                        output.push(escape);
                    } else {
                        output.push("\\", escape);
                    }
                    if (c == '""') {
                        break;
                    }
                }
            }
        }
        return output;
    }
}

function compactUnicodeEscape(input, output, index) {
    const ESCAPES = "uuuuuuuubtnufruuuuuuuuuuuuuuuuuu";
    const HEX = "0123456789ABCDEF";
    var inputLength = input.length;
    if (inputLength - index < 4) {
        return output, inputLength;
    }
    c = readHexDigits(input[index]);
    index += 4;
    if (c < ' ') {
        escape = ESCAPES[c];
        output.push(output, '\\', escape);
    }
    if (escape == 'u') {
        output.push("0", "0", ('0' + (c >> 4)), HEX[c & 0xF]);
    } else if (c == '\\' || c == '"') {
        // Otherwise the character only needs escaping if it is a QUOTE '"' or BACKSLASH '\\'.
        output.push(output, '\\', c);
    } else if (c < 0xD800 || c >= 0xE000) {
        // If the character isn't a surrogate pair then encoded it directly as UTF-8.
        var buffer;
        //n := utf8.EncodeRune(buffer[:], rune(c))
        //output = append(output, buffer[:n]...)
    } else {

        if (inputLength - index < 6) {
            return output, inputLength;
        }
        // Decode the 4 hex digits from the '\uXXXX'.
        var surrogate = readHexDigits(input[index + 2]);
        index += 6;
        // Reconstruct the UCS4 codepoint from the surrogates.
        var codepoint = 0x10000 + (((c & 0x3FF) << 10) | (surrogate & 0x3FF));
        // Encode the charater as UTF-8.
        var buffer;
        //n := utf8.EncodeRune(buffer[:], rune(codepoint))
        //output = append(output, buffer[:n]...)
    }
    return output, index;
}
//the basic idea is to reencode json and then arrange them into lexicographical order.
//gophers has a very copmplex way to do it,but JS is somewhat simple :)
// i guess there is nno need to use interfaces in js,as gophers use it to handle loosely handled or non-strictly typed json.<|endoftext|>