<commit_before>define([
    'jquery',
    'gizmo/superdesk',
    'livedesk/views/provider-edit',
    'angular',
    'lib/livedesk/scripts/js/manage-feeds/manage-feeds',
    'lib/livedesk/scripts/js/manage-feeds/services/chained-blogs-data',
    'lib/livedesk/scripts/js/manage-feeds/services/add-provider',
    'lib/livedesk/scripts/js/manage-feeds/services/sms-data',
    'lib/livedesk/scripts/js/manage-feeds/directives/checkbox-custom',
    'lib/livedesk/scripts/js/manage-feeds/directives/sms-checkbox-custom',
    'tmpl!livedesk>layouts/livedesk',
    'tmpl!core>layouts/footer',
    'tmpl!core>layouts/footer-static',
    'tmpl!livedesk>manage-feeds',
    'tmpl!livedesk>manage-feeds-provider',
    'tmpl!livedesk>manage-feeds-external-blog',
], function ($, Gizmo, EditProviderView, ngular, feeds) {
    function getGizmoUrl(path) {
        var url = new Gizmo.Url(path);
        return url.get();
    }

    function getLastId(blogHref) {
        //small hack to get the blog id
        //@TODO get it in a smarter way
        var hackArray = blogHref.split('/');
        var blogId = hackArray[hackArray.length - 1];
        return blogId;
    }

    return function(blogHref) {
        var SMS_TYPE = 'smsblog';
        var PROVIDER_TYPE = 'blog provider';
        var blogId = getLastId(blogHref);

        var sourcesUrl = getGizmoUrl('LiveDesk/Blog/' + blogId + '/Source') + '?X-Filter=*';
        var smsUrl = getGizmoUrl('Data/SourceType/smsfeed/Source') + '?X-Filter=Name,Id';
        var smsSourcesUrl = getGizmoUrl('Data/SourceType/smsblog/Source?blogId=' + blogId + '&X-Filter=*') ;

        var providersUrl = getGizmoUrl('Data/SourceType/' + PROVIDER_TYPE + '/Source') + '?X-Filter=Name,Id,URI';
        var chainBlogUrl = getGizmoUrl('LiveDesk/Blog/' + blogId + '/Source');

        feeds.controller('chainedBlogs', function($scope, $http, chainedBlogsData, provider, smsData) {
            //initializing some vars
            $scope.chains = [];
            $scope.newTitle = '';
            $scope.newUrl = '';

            $scope.msg = {
                newTitleError: false,
                newUrlError: false,
                newInputError: false,
                noChains: true,
                noSmsFeeds: true
            };

            $scope.smss = [];
            $scope.handleChange = function(sms) {
                if ( sms.assigned ) {
                    assign(sms);
                } else {
                    unassign(sms);
                }
            };

            var checkChains = function() {
                $scope.msg.noChains = $scope.chains.length === 0;
            };

            var assign = function(sms) {
                var name = sms.Name;
                var newSource = {
                    Name: name,
                    Type: SMS_TYPE,
                    IsModifiable: 'True',
                    OriginURI: name,
                    URI: SMS_TYPE + '/' + name
                };
                var assignUrl = getGizmoUrl('LiveDesk/Blog/' + blogId + '/Source');
                $http.post(assignUrl, newSource);
            };

            var unassign = function(sms) {
                var unassignUrl = getGizmoUrl('LiveDesk/Blog/' + blogId + '/Source/' + sms.source);
                $http({method: 'DELETE', url: unassignUrl});
            };

            //get the sms feeds
            smsData.getData(smsUrl, smsSourcesUrl).then(function(data){
                $scope.smss = data;
                $scope.msg.noSmsFeeds = $scope.smss.length === 0;
            });

            //done here with sms starting with chained blogs

            chainedBlogsData.getData(providersUrl, sourcesUrl).then(function(chains){
                $scope.chains = chains;
                checkChains();
            });

            var isUrl = function(url) {
                return url && url.match(/^(https?:)?\/\//);
            };

            $scope.chainChange = function (blog, OriginUri, parentIndex, index) {
                if ( blog.chained ) {
                    //add source
                    var name = blog.Title;
                    var URI = blog.href;
                    var newChainedBlog = {
                        'IsModifiable': 'True',
                        'Name': name,
                        'OriginURI': OriginUri,
                        'Type': 'chained blog',
                        'URI': URI
                    }
                    $http.post(chainBlogUrl, newChainedBlog).
                    success(function(data, status, headers, config) {
                        var sourceId = getLastId(data.href);
                        $scope.chains[parentIndex].blogList[index].sourceId = sourceId;
                        $scope.chains[parentIndex].blogList[index].chained = true;
                    });
                } else {
                    var unchainUrl = getGizmoUrl('LiveDesk/Blog/' + blogId + '/Source/' + blog.sourceId);
                    $http({method: 'DELETE', url: unchainUrl});
                    $scope.chains[parentIndex].blogList[index].chained = false;

                }
            };

            $scope.removeProvider = function (chain) {
                var index = $scope.chains.indexOf( chain );
                if ( confirm(_("Removing provider will unchain its blogs.\nAre you sure to continue?")) ){
                    var removeSourceUrl = getGizmoUrl('Data/Source/' + chain.Id);
                    provider.unchainBlogs(getGizmoUrl('LiveDesk/Blog/' + blogId + '/Source/'), chain.blogList);
                    $http({method: 'DELETE', url: removeSourceUrl});
                    $scope.chains.splice(index, 1);
                    checkChains();
                }
            };

            $scope.preEditProvider = function(provider) {
                if ( typeof provider == "undefined" ) {
                    $scope.provider = -1;
                } else {
                    $scope.provider = provider;
                    $scope.newTitle = provider.Name;
                    $scope.newUrl = provider.URI.href;
                }
            };

            var cleanEditForm = function() {
                $scope.newTitle = '';
                $scope.newUrl = '';
                //$scope.provider = -1;
                jQuery('#AddProvider').modal('hide');
            };

            $scope.editProvider = function() {
                var valid = true;
                if ( $scope.newTitle.length < 1 ) {
                    $scope.msg.newTitleError = true;
                    valid = false;
                } else {
                    $scope.msg.newTitleError = false;
                }
                if ( !isUrl($scope.newUrl) ) {
                    $scope.msg.newUrlError = true;
                    valid = false;
                } else {
                    $scope.msg.newUrlError = false;
                }

                if ( valid ) {
                     var myData = {
                        'IsModifiable': "True",
                        'Name': $scope.newTitle,
                        'Type': PROVIDER_TYPE,
                        'URI': $scope.newUrl
                    };

                    if ( $scope.provider == -1 ) {
                        //new provider
                        provider.addData(getGizmoUrl('Data/Source'), myData).then(function(data){
                            provider.createProviderObject(data).then(function(data){
                                $scope.chains.push(data);
                                cleanEditForm();
                                checkChains();
                            }, function(data){
                                $scope.msg.newInputError = true;
                            })
                        }, function(data) {
                            $scope.msg.newInputError = true;
                        });
                    } else {

                        //editing existing provider
                        provider.getBlogs($scope.newUrl).then(function(newBlogsdata){
                            //we got the new blogs (can be empty)
                            var editData = {
                                Name: $scope.newTitle,
                                URI: $scope.newUrl
                            };
                            provider.editProvider(getGizmoUrl('Data/Source/' + $scope.provider.Id), editData ).then(function(data){
                                //was able to edit the provider
                                //unchain blogs
                                provider.unchainBlogs(getGizmoUrl('LiveDesk/Blog/' + blogId + '/Source/'), $scope.provider.blogList);
                                //update provider object
                                $scope.provider.blogList = newBlogsdata;
                                $scope.provider.URI.href = $scope.newUrl;
                                $scope.provider.Name = $scope.newTitle;
                                //close the form
                                cleanEditForm();
                            }, function(data) {
                                //was not able to edit the provider
                                $scope.msg.newInputError = true;
                            });
                        }, function() {
                            //error getting the new blogs
                            $scope.msg.newUrlError = true;
                        });

                    }
                }
            };
        });

        var myBlog = Gizmo.Auth(new Gizmo.Register.Blog(blogHref));
        myBlog.sync().done(function(data){
            var myData = {
                Title: data.Title,
                Id: data.Id,
                ui: {
                    content: 'is-content=1',
                    submenu: 'is-submenu',
                    submenuActive4: 'active'
                }
            }
            $('#area-main').tmpl( 'livedesk>manage-feeds', myData );
            $('#controller-heaven').attr('ng-controller', 'chainedBlogs');
            angular.bootstrap(document, ['manageFeeds']);
        });
    }
});
<commit_msg>LB-1342 After editing chaining provider name selected blog is reset<commit_after>define([
    'jquery',
    'gizmo/superdesk',
    'livedesk/views/provider-edit',
    'angular',
    'lib/livedesk/scripts/js/manage-feeds/manage-feeds',
    'lib/livedesk/scripts/js/manage-feeds/services/chained-blogs-data',
    'lib/livedesk/scripts/js/manage-feeds/services/add-provider',
    'lib/livedesk/scripts/js/manage-feeds/services/sms-data',
    'lib/livedesk/scripts/js/manage-feeds/directives/checkbox-custom',
    'lib/livedesk/scripts/js/manage-feeds/directives/sms-checkbox-custom',
    'tmpl!livedesk>layouts/livedesk',
    'tmpl!core>layouts/footer',
    'tmpl!core>layouts/footer-static',
    'tmpl!livedesk>manage-feeds',
    'tmpl!livedesk>manage-feeds-provider',
    'tmpl!livedesk>manage-feeds-external-blog',
], function ($, Gizmo, EditProviderView, ngular, feeds) {
    function getGizmoUrl(path) {
        var url = new Gizmo.Url(path);
        return url.get();
    }

    function getLastId(blogHref) {
        //small hack to get the blog id
        //@TODO get it in a smarter way
        var hackArray = blogHref.split('/');
        var blogId = hackArray[hackArray.length - 1];
        return blogId;
    }

    return function(blogHref) {
        var SMS_TYPE = 'smsblog';
        var PROVIDER_TYPE = 'blog provider';
        var blogId = getLastId(blogHref);

        var sourcesUrl = getGizmoUrl('LiveDesk/Blog/' + blogId + '/Source') + '?X-Filter=*';
        var smsUrl = getGizmoUrl('Data/SourceType/smsfeed/Source') + '?X-Filter=Name,Id';
        var smsSourcesUrl = getGizmoUrl('Data/SourceType/smsblog/Source?blogId=' + blogId + '&X-Filter=*') ;

        var providersUrl = getGizmoUrl('Data/SourceType/' + PROVIDER_TYPE + '/Source') + '?X-Filter=Name,Id,URI';
        var chainBlogUrl = getGizmoUrl('LiveDesk/Blog/' + blogId + '/Source');

        feeds.controller('chainedBlogs', function($scope, $http, chainedBlogsData, provider, smsData) {
            //initializing some vars
            $scope.chains = [];
            $scope.newTitle = '';
            $scope.newUrl = '';

            $scope.msg = {
                newTitleError: false,
                newUrlError: false,
                newInputError: false,
                noChains: true,
                noSmsFeeds: true
            };

            $scope.smss = [];
            $scope.handleChange = function(sms) {
                if ( sms.assigned ) {
                    assign(sms);
                } else {
                    unassign(sms);
                }
            };

            var checkChains = function() {
                $scope.msg.noChains = $scope.chains.length === 0;
            };

            var assign = function(sms) {
                var name = sms.Name;
                var newSource = {
                    Name: name,
                    Type: SMS_TYPE,
                    IsModifiable: 'True',
                    OriginURI: name,
                    URI: SMS_TYPE + '/' + name
                };
                var assignUrl = getGizmoUrl('LiveDesk/Blog/' + blogId + '/Source');
                $http.post(assignUrl, newSource);
            };

            var unassign = function(sms) {
                var unassignUrl = getGizmoUrl('LiveDesk/Blog/' + blogId + '/Source/' + sms.source);
                $http({method: 'DELETE', url: unassignUrl});
            };

            //get the sms feeds
            smsData.getData(smsUrl, smsSourcesUrl).then(function(data){
                $scope.smss = data;
                $scope.msg.noSmsFeeds = $scope.smss.length === 0;
            });

            //done here with sms starting with chained blogs

            chainedBlogsData.getData(providersUrl, sourcesUrl).then(function(chains){
                $scope.chains = chains;
                checkChains();
            });

            var isUrl = function(url) {
                return url && url.match(/^(https?:)?\/\//);
            };

            $scope.chainChange = function (blog, OriginUri, parentIndex, index) {
                if ( blog.chained ) {
                    //add source
                    var name = blog.Title;
                    var URI = blog.href;
                    var newChainedBlog = {
                        'IsModifiable': 'True',
                        'Name': name,
                        'OriginURI': OriginUri,
                        'Type': 'chained blog',
                        'URI': URI
                    }
                    $http.post(chainBlogUrl, newChainedBlog).
                    success(function(data, status, headers, config) {
                        var sourceId = getLastId(data.href);
                        $scope.chains[parentIndex].blogList[index].sourceId = sourceId;
                        $scope.chains[parentIndex].blogList[index].chained = true;
                    });
                } else {
                    var unchainUrl = getGizmoUrl('LiveDesk/Blog/' + blogId + '/Source/' + blog.sourceId);
                    $http({method: 'DELETE', url: unchainUrl});
                    $scope.chains[parentIndex].blogList[index].chained = false;

                }
            };

            $scope.removeProvider = function (chain) {
                var index = $scope.chains.indexOf( chain );
                if ( confirm(_("Removing provider will unchain its blogs.\nAre you sure to continue?")) ){
                    var removeSourceUrl = getGizmoUrl('Data/Source/' + chain.Id);
                    provider.unchainBlogs(getGizmoUrl('LiveDesk/Blog/' + blogId + '/Source/'), chain.blogList);
                    $http({method: 'DELETE', url: removeSourceUrl});
                    $scope.chains.splice(index, 1);
                    checkChains();
                }
            };

            $scope.preEditProvider = function(provider) {
                if ( typeof provider == "undefined" ) {
                    $scope.provider = -1;
                } else {
                    $scope.provider = provider;
                    $scope.newTitle = provider.Name;
                    $scope.newUrl = provider.URI.href;
                }
            };

            var cleanEditForm = function() {
                $scope.newTitle = '';
                $scope.newUrl = '';
                //$scope.provider = -1;
                jQuery('#AddProvider').modal('hide');
            };

            $scope.editProvider = function() {
                var valid = true;
                if ( $scope.newTitle.length < 1 ) {
                    $scope.msg.newTitleError = true;
                    valid = false;
                } else {
                    $scope.msg.newTitleError = false;
                }
                if ( !isUrl($scope.newUrl) ) {
                    $scope.msg.newUrlError = true;
                    valid = false;
                } else {
                    $scope.msg.newUrlError = false;
                }

                if ( valid ) {
                     var myData = {
                        'IsModifiable': "True",
                        'Name': $scope.newTitle,
                        'Type': PROVIDER_TYPE,
                        'URI': $scope.newUrl
                    };

                    if ( $scope.provider == -1 ) {
                        //new provider
                        provider.addData(getGizmoUrl('Data/Source'), myData).then(function(data){
                            provider.createProviderObject(data).then(function(data){
                                $scope.chains.push(data);
                                cleanEditForm();
                                checkChains();
                            }, function(data){
                                $scope.msg.newInputError = true;
                            })
                        }, function(data) {
                            $scope.msg.newInputError = true;
                        });
                    } else {

                        //editing existing provider
                        provider.getBlogs($scope.newUrl).then(function(newBlogsdata){
                            //we got the new blogs (can be empty)
                            var editData = {
                                Name: $scope.newTitle,
                                URI: $scope.newUrl
                            };
                            provider.editProvider(getGizmoUrl('Data/Source/' + $scope.provider.Id), editData ).then(function(data){
                                //was able to edit the provider
                                //update provider object
                                $scope.provider.Name = $scope.newTitle;
                                if ($scope.provider.URI.href != $scope.newUrl){
                                  //unchain blogs
                                  provider.unchainBlogs(getGizmoUrl('LiveDesk/Blog/' + blogId + '/Source/'), $scope.provider.blogList);
                                  $scope.provider.blogList = newBlogsdata;
                                  $scope.provider.URI.href = $scope.newUrl;
                                }
                                //close the form
                                cleanEditForm();
                            }, function(data) {
                                //was not able to edit the provider
                                $scope.msg.newInputError = true;
                            });
                        }, function() {
                            //error getting the new blogs
                            $scope.msg.newUrlError = true;
                        });

                    }
                }
            };
        });

        var myBlog = Gizmo.Auth(new Gizmo.Register.Blog(blogHref));
        myBlog.sync().done(function(data){
            var myData = {
                Title: data.Title,
                Id: data.Id,
                ui: {
                    content: 'is-content=1',
                    submenu: 'is-submenu',
                    submenuActive4: 'active'
                }
            }
            $('#area-main').tmpl( 'livedesk>manage-feeds', myData );
            $('#controller-heaven').attr('ng-controller', 'chainedBlogs');
            angular.bootstrap(document, ['manageFeeds']);
        });
    }
});
<|endoftext|>


<commit_before>/*jslint nomen: true, vars: true, white: true */
/*jshint scripturl: true */
/*global red,esprima,able,uid,console,window,jQuery,Raphael */

(function (red, $) {
	"use strict";
	var cjs = red.cjs,
		_ = red._;

	var display;
    var platform = window.navigator.platform;

	var to_func = function (value) {
		return function () { return value; };
	};

	if(platform === "iPhone" || platform === "iPod") {
		display = "phone";
	} else if(platform === "iPad") {
		display = "tablet";
	} else {
		display = "desktop";
	}

	$.widget("red.editor", {
		options: {
			debug_ready: false,
			full_window: true,
			server_window: window.opener,
			client_id: "",
			single_col_navigation: display === "phone" || display === "tablet",
			view_type: display,
			annotations: {}
		},

		_create: function () {
			this.$on_command = $.proxy(this.on_command, this);
			this.element.addClass(this.option("view_type"))
						.attr({
							id: "editor"
						});

			if(this.option("full_window")) {
				$("html").addClass("full_window_editor");
			}
			var communication_mechanism;
			if(this.option("server_window") === window) {
				communication_mechanism = new red.SameWindowCommWrapper(this.option("client_id"));
			} else {
				communication_mechanism = new red.InterWindowCommWrapper(this.option("server_window"), this.option("client_id"));
			}

			this.client_socket = new red.ProgramStateClient({
				ready_func: this.option("debug_ready"),
				comm_mechanism: communication_mechanism
			}).on("message", function (data) {
				if (data.type === "color") {
					var color = data.value;
				}
			}, this).on("loaded", function (root_client) {
				this.load_viewer(root_client);
			}, this);

			this.element.text("Loading...");
			$(window).on("beforeunload", _.bind(function () {
				this.on_unload();
			}, this));
		},

		get_client_socket: function() {
			return this.client_socket;
		},

		load_viewer: function (root_client) {
			this.element.html("");
			this.menu = $("<div />").menu({
										title: "menu",
										items: {
											"Undo": {
												on_select: _.bind(this.undo, this)
											},
											"Redo": {
												on_select: _.bind(this.redo, this)
											},
											"Export": {
												on_select: _.bind(this["export"], this)
											}
											/*
											"Upload to Gallery": {
												on_select: _.bind(this.upload, this),
												disabled: true
											},
											"Save": {
												on_select: _.bind(this.save, this),
												disabled: true
											},
											"Save As": {
												on_select: _.bind(this.save_as, this),
												disabled: true
											},
											"Open": {
												on_select: _.bind(this.open, this),
												disabled: true
											}*/
										}
									})
									.appendTo(this.element);
									/*
			this.reset_button = $("<a />")	.addClass("reset button")
											.text("Reset")
											.appendTo(this.menu)
											.attr("href", "javascript:void(0)")
											.on("click", $.proxy(this.reset, this));
											*/

			this.navigator = $("<div />")	.appendTo(this.element)
											.navigator({
												root_client: root_client,
												single_col: this.option("single_col_navigation")
											})
											.on("command", this.$on_command);

			$(window).on("keydown", _.bind(function (event) {
				if (event.keyCode === 90 && (event.metaKey || event.ctrlKey)) {
					if (event.shiftKey) { this.redo(); }
					else { this.undo(); }
					event.stopPropagation();
					event.preventDefault();
				}/* else if(event.keyCode === 82 && (event.metaKey || event.ctrlKey)) { // 'r': prevent refresh
					event.stopPropagation();
					event.preventDefault();
				}*/
			}, this));
		},

		"export": function() {
			this.client_socket.post_command("export");
		},

		upload: function() {
		},
		save: function() {
		},
		save_as: function() {
		},
		open: function() {
		},

		on_command: function(event) {
			var type = event.command_type;
			var client, name, value, command, state, transition, statechart_puppet_id, parent_puppet_id;

			if(type === "add_property") {
				client = event.client;
				var prop_type;
				if(client.type() === "dict") {
					prop_type = "stateful_obj";
				} else {
					prop_type = "stateful_prop";
				}

				if(prop_type === "stateful_obj") {
					value = red.create("stateful_obj", undefined, true);
					value.do_initialize({
						direct_protos: red.create("stateful_prop", { can_inherit: false, statechart_parent: value })
					});
				} else if(prop_type === "stateful_prop") {
					value = red.create('stateful_prop');
				}

				command = new red.SetPropCommand({
					parent: { id: to_func(client.obj_id) },
					value: value,
					index: 0
				});
				this.client_socket.post_command(command);
			} else if(type === "rename") {
				client = event.client;
				command = new red.RenamePropCommand({
					parent: { id: to_func(client.obj_id) },
					from: event.from_name,
					to: event.to_name
				});
				this.client_socket.post_command(command);
			} else if(type === "inherit") {
				client = event.client;
				value = event.value;
				var prop_name = event.name;

				command = new red.InheritPropCommand({
					parent: { id: to_func(client.obj_id) },
					name: prop_name,
					value: { id: to_func(value.obj_id) }
				});
				this.client_socket.post_command(command);
			} else if(type === "unset") {
				client = event.client;
				command = new red.UnsetPropCommand({
					parent: { id: to_func(client.obj_id) },
					name: event.name
				});
				this.client_socket.post_command(command);
			} else if(type === "set_stateful_prop_for_state") {
				client = event.prop;
				state = event.state;
				value = red.create('cell', {str: ''});

				command = new red.SetStatefulPropValueCommand({
					stateful_prop: { id: to_func(client.obj_id) },
					state: { id: to_func(state.cobj_id) },
					value: value
				});
				this.client_socket.post_command(command);
			} else if(type === "unset_stateful_prop_for_state") {
				client = event.prop;
				state = event.state;

				command = new red.UnsetStatefulPropValueCommand({
					stateful_prop: { id: to_func(client.obj_id) },
					state: { id: to_func(state.cobj_id) }
				});
				this.client_socket.post_command(command);
			} else if(type === "set_str") {
				client = event.client;
				value = event.str;

				command = new red.ChangeCellCommand({
					cell: { id: to_func(client.cobj_id || client.obj_id) },
					str: value
				});
				this.client_socket.post_command(command);
			} else if(type === "add_state") {
				state = event.state;
				statechart_puppet_id = state.puppet_master_id || state.id();
				var substates = state.get_substates();

				var substates_size = _.size(substates);
				var state_name, make_start;

				if(substates_size === 0) {
					state_name = "init";
					make_start = true;
				} else {
					var orig_state_name = "state_" + substates_size;
					state_name = orig_state_name;
					var i = 1;
					while(_.has(substates, state_name)) {
						state_name = orig_state_name + "_" + i;
					}
					make_start = false;
				}

				command = new red.AddStateCommand({
					statechart: { id: to_func(statechart_puppet_id) },
					name: state_name,
					make_start: make_start
				});

				this.client_socket.post_command(command);
			} else if(type === "remove_state") {
				state = event.state;
				name = state.get_name("parent");
				parent_puppet_id = state.parent().puppet_master_id || state.parent().id();
				command = new red.RemoveStateCommand({
					statechart: { id: to_func(parent_puppet_id) },
					name: name
				});
				this.client_socket.post_command(command);
			} else if(type === "remove_transition") {
				transition = event.transition;
				var statechart = transition.root();
				command = new red.RemoveTransitionCommand({
					transition: { id: to_func(transition.puppet_master_id || transition.id()) },
					statechart: { id: to_func(statechart.puppet_master_id || transition.id()) }
				});
				this.client_socket.post_command(command);
			} else if(type === "set_type") {
				var to_type = event.type_name;
				name = event.prop_name;
				client = event.client;
				if(to_type === "Object") {
					value = red.create("stateful_obj", undefined, true);
					value.do_initialize({
						direct_protos: red.create("stateful_prop", { can_inherit: false, statechart_parent: value })
					});
				} else if(to_type === "Property") {
					value = red.create('stateful_prop');
				}

				command = new red.SetPropCommand({
					parent: { id: to_func(client.obj_id) },
					value: value,
					name: name
				});
				this.client_socket.post_command(command);
			} else if(type === "add_transition") {
				var from_state = event.from;
				var to_state = event.to;
				state = from_state.root();
				statechart_puppet_id = state.puppet_master_id || state.id();
				var from_puppet_id = from_state.puppet_master_id || from_state.id(),
					to_puppet_id = to_state.puppet_master_id || to_state.id();
				event = red.create_event("parsed", {str: "(event)", inert: true});
				command = new red.AddTransitionCommand({
					from: { id: to_func(from_puppet_id) },
					to: { id: to_func(to_puppet_id) },
					event: event,
					statechart: { id: to_func(statechart_puppet_id) }
				});
				this.client_socket.post_command(command);
			} else if(type === "set_transition_to") {
				transition = event.transition;
				state = event.to;
				statechart_puppet_id = state.puppet_master_id || state.id();
				command = new red.SetTransitionToCommand({
					transition: { id: to_func(transition.puppet_master_id || transition.id()) },
					statechart: { id: to_func(statechart_puppet_id) }
				});
				this.client_socket.post_command(command);
			} else if(type === "set_transition_from") {
				transition = event.transition;
				state = event.from;
				statechart_puppet_id = state.puppet_master_id || state.id();
				command = new red.SetTransitionFromCommand({
					transition: { id: to_func(transition.puppet_master_id || transition.id()) },
					statechart: { id: to_func(statechart_puppet_id) }
				});
				this.client_socket.post_command(command);
			} else if(type === "rename_state") {
				state = event.state;
				var new_name = event.new_name;
				var old_name = state.get_name("parent");
				parent_puppet_id = state.parent().puppet_master_id || state.parent().id();
				command = new red.RenameStateCommand({
					statechart: { id: to_func(parent_puppet_id) },
					from: old_name,
					to: new_name
				});
				this.client_socket.post_command(command);
			} else if (type === 'set_transition_str') {
				transition = event.transition;
				var str = event.str;
				var transition_id = transition.puppet_master_id || transition.id();
				command = new red.SetTransitionEventCommand({
					transition: { id: to_func(transition_id) },
					event: str
				});
				this.client_socket.post_command(command);
			} else if (type === 'set_copies') {
				value = event.str;
				client = event.client;
				command = new red.SetCopiesCommand({
					parent: { id: to_func(client.obj_id) },
					value: value
				});
				this.client_socket.post_command(command);
			} else if (type === 'reset') {
				client = event.client;
				command = new red.ResetCommand({
					parent: { id: to_func(client.cobj_id) }
				});
				this.client_socket.post_command(command);
			} else if (type === 'make_concurrent') {
				state = event.state;
				var state_puppet_id = state.puppet_master_id || state.id();
				command = new red.MakeConcurrentCommand({
					statechart: { id: to_func(state_puppet_id) },
					concurrent: event.concurrent
				});
				this.client_socket.post_command(command);
			} else if (type === 'move_prop') {
				var from_obj = event.from_obj;
				var from_name = event.from_name;
				var target_obj = event.target_obj;
				var target_name = event.target_name;
				var above_below = event.above_below;
				console.log(target_obj);

				command = new red.MovePropAboveBelowCommand({
					from_obj: { id: to_func(from_obj.obj_id) },
					from_name: from_name,
					target_obj: { id: to_func(target_obj.obj_id) },
					target_name: target_name,
					above_below: above_below
				});
				this.client_socket.post_command(command);
			} else {
				console.log("Unhandled type " + type);
			}
		},

		undo: function() {
			this.client_socket.post_command("undo");
		},
		redo: function() {
			this.client_socket.post_command("redo");
		},
		reset: function() {
			this.client_socket.post_command("reset");
		},

		on_unload: function() {
			this.navigator.navigator("destroy");
			this.menu.menu("destroy").remove();
			this.client_socket.destroy();
		},

		_destroy: function () {
			this.on_unload();
		},

		_setOption: function(key, value) {
			this._super(key, value);
			if(key === "anotations") {
				this.navigator.navigator("option", key, value);
			}
		}
	});
}(red, jQuery));
<commit_msg>Removed some extinct options<commit_after>/*jslint nomen: true, vars: true, white: true */
/*jshint scripturl: true */
/*global red,esprima,able,uid,console,window,jQuery,Raphael */

(function (red, $) {
	"use strict";
	var cjs = red.cjs,
		_ = red._;

	var display;
    var platform = window.navigator.platform;

	var to_func = function (value) {
		return function () { return value; };
	};

	if(platform === "iPhone" || platform === "iPod") {
		display = "phone";
	} else if(platform === "iPad") {
		display = "tablet";
	} else {
		display = "desktop";
	}

	$.widget("red.editor", {
		options: {
			debug_ready: false,
			full_window: true,
			server_window: window.opener,
			client_id: "",
			single_col_navigation: display === "phone" || display === "tablet",
			view_type: display,
			annotations: {}
		},

		_create: function () {
			this.$on_command = $.proxy(this.on_command, this);
			this.element.addClass(this.option("view_type"))
						.attr({
							id: "editor"
						});

			if(this.option("full_window")) {
				$("html").addClass("full_window_editor");
			}
			var communication_mechanism;
			if(this.option("server_window") === window) {
				communication_mechanism = new red.SameWindowCommWrapper(this.option("client_id"));
			} else {
				communication_mechanism = new red.InterWindowCommWrapper(this.option("server_window"), this.option("client_id"));
			}

			this.client_socket = new red.ProgramStateClient({
				ready_func: this.option("debug_ready"),
				comm_mechanism: communication_mechanism
			}).on("message", function (data) {
				if (data.type === "color") {
					var color = data.value;
				}
			}, this).on("loaded", function (root_client) {
				this.load_viewer(root_client);
			}, this);

			this.element.text("Loading...");
			$(window).on("beforeunload", _.bind(function () {
				this.on_unload();
			}, this));
		},

		get_client_socket: function() {
			return this.client_socket;
		},

		load_viewer: function (root_client) {
			this.element.html("");
			this.menu = $("<div />").menu({
										title: "menu",
										items: {
											"Undo": {
												on_select: _.bind(this.undo, this)
											},
											"Redo": {
												on_select: _.bind(this.redo, this)
											},
											"Export": {
												on_select: _.bind(this["export"], this)
											}
										}
									})
									.appendTo(this.element);
									/*
			this.reset_button = $("<a />")	.addClass("reset button")
											.text("Reset")
											.appendTo(this.menu)
											.attr("href", "javascript:void(0)")
											.on("click", $.proxy(this.reset, this));
											*/

			this.navigator = $("<div />")	.appendTo(this.element)
											.navigator({
												root_client: root_client,
												single_col: this.option("single_col_navigation")
											})
											.on("command", this.$on_command);

			$(window).on("keydown", _.bind(function (event) {
				if (event.keyCode === 90 && (event.metaKey || event.ctrlKey)) {
					if (event.shiftKey) { this.redo(); }
					else { this.undo(); }
					event.stopPropagation();
					event.preventDefault();
				}/* else if(event.keyCode === 82 && (event.metaKey || event.ctrlKey)) { // 'r': prevent refresh
					event.stopPropagation();
					event.preventDefault();
				}*/
			}, this));
		},

		"export": function() {
			this.client_socket.post_command("export");
		},

		upload: function() {
		},
		save: function() {
		},
		save_as: function() {
		},
		open: function() {
		},

		on_command: function(event) {
			var type = event.command_type;
			var client, name, value, command, state, transition, statechart_puppet_id, parent_puppet_id;

			if(type === "add_property") {
				client = event.client;
				var prop_type;
				if(client.type() === "dict") {
					prop_type = "stateful_obj";
				} else {
					prop_type = "stateful_prop";
				}

				if(prop_type === "stateful_obj") {
					value = red.create("stateful_obj", undefined, true);
					value.do_initialize({
						direct_protos: red.create("stateful_prop", { can_inherit: false, statechart_parent: value })
					});
				} else if(prop_type === "stateful_prop") {
					value = red.create('stateful_prop');
				}

				command = new red.SetPropCommand({
					parent: { id: to_func(client.obj_id) },
					value: value,
					index: 0
				});
				this.client_socket.post_command(command);
			} else if(type === "rename") {
				client = event.client;
				command = new red.RenamePropCommand({
					parent: { id: to_func(client.obj_id) },
					from: event.from_name,
					to: event.to_name
				});
				this.client_socket.post_command(command);
			} else if(type === "inherit") {
				client = event.client;
				value = event.value;
				var prop_name = event.name;

				command = new red.InheritPropCommand({
					parent: { id: to_func(client.obj_id) },
					name: prop_name,
					value: { id: to_func(value.obj_id) }
				});
				this.client_socket.post_command(command);
			} else if(type === "unset") {
				client = event.client;
				command = new red.UnsetPropCommand({
					parent: { id: to_func(client.obj_id) },
					name: event.name
				});
				this.client_socket.post_command(command);
			} else if(type === "set_stateful_prop_for_state") {
				client = event.prop;
				state = event.state;
				value = red.create('cell', {str: ''});

				command = new red.SetStatefulPropValueCommand({
					stateful_prop: { id: to_func(client.obj_id) },
					state: { id: to_func(state.cobj_id) },
					value: value
				});
				this.client_socket.post_command(command);
			} else if(type === "unset_stateful_prop_for_state") {
				client = event.prop;
				state = event.state;

				command = new red.UnsetStatefulPropValueCommand({
					stateful_prop: { id: to_func(client.obj_id) },
					state: { id: to_func(state.cobj_id) }
				});
				this.client_socket.post_command(command);
			} else if(type === "set_str") {
				client = event.client;
				value = event.str;

				command = new red.ChangeCellCommand({
					cell: { id: to_func(client.cobj_id || client.obj_id) },
					str: value
				});
				this.client_socket.post_command(command);
			} else if(type === "add_state") {
				state = event.state;
				statechart_puppet_id = state.puppet_master_id || state.id();
				var substates = state.get_substates();

				var substates_size = _.size(substates);
				var state_name, make_start;

				if(substates_size === 0) {
					state_name = "init";
					make_start = true;
				} else {
					var orig_state_name = "state_" + substates_size;
					state_name = orig_state_name;
					var i = 1;
					while(_.has(substates, state_name)) {
						state_name = orig_state_name + "_" + i;
					}
					make_start = false;
				}

				command = new red.AddStateCommand({
					statechart: { id: to_func(statechart_puppet_id) },
					name: state_name,
					make_start: make_start
				});

				this.client_socket.post_command(command);
			} else if(type === "remove_state") {
				state = event.state;
				name = state.get_name("parent");
				parent_puppet_id = state.parent().puppet_master_id || state.parent().id();
				command = new red.RemoveStateCommand({
					statechart: { id: to_func(parent_puppet_id) },
					name: name
				});
				this.client_socket.post_command(command);
			} else if(type === "remove_transition") {
				transition = event.transition;
				var statechart = transition.root();
				command = new red.RemoveTransitionCommand({
					transition: { id: to_func(transition.puppet_master_id || transition.id()) },
					statechart: { id: to_func(statechart.puppet_master_id || transition.id()) }
				});
				this.client_socket.post_command(command);
			} else if(type === "set_type") {
				var to_type = event.type_name;
				name = event.prop_name;
				client = event.client;
				if(to_type === "Object") {
					value = red.create("stateful_obj", undefined, true);
					value.do_initialize({
						direct_protos: red.create("stateful_prop", { can_inherit: false, statechart_parent: value })
					});
				} else if(to_type === "Property") {
					value = red.create('stateful_prop');
				}

				command = new red.SetPropCommand({
					parent: { id: to_func(client.obj_id) },
					value: value,
					name: name
				});
				this.client_socket.post_command(command);
			} else if(type === "add_transition") {
				var from_state = event.from;
				var to_state = event.to;
				state = from_state.root();
				statechart_puppet_id = state.puppet_master_id || state.id();
				var from_puppet_id = from_state.puppet_master_id || from_state.id(),
					to_puppet_id = to_state.puppet_master_id || to_state.id();
				event = red.create_event("parsed", {str: "(event)", inert: true});
				command = new red.AddTransitionCommand({
					from: { id: to_func(from_puppet_id) },
					to: { id: to_func(to_puppet_id) },
					event: event,
					statechart: { id: to_func(statechart_puppet_id) }
				});
				this.client_socket.post_command(command);
			} else if(type === "set_transition_to") {
				transition = event.transition;
				state = event.to;
				statechart_puppet_id = state.puppet_master_id || state.id();
				command = new red.SetTransitionToCommand({
					transition: { id: to_func(transition.puppet_master_id || transition.id()) },
					statechart: { id: to_func(statechart_puppet_id) }
				});
				this.client_socket.post_command(command);
			} else if(type === "set_transition_from") {
				transition = event.transition;
				state = event.from;
				statechart_puppet_id = state.puppet_master_id || state.id();
				command = new red.SetTransitionFromCommand({
					transition: { id: to_func(transition.puppet_master_id || transition.id()) },
					statechart: { id: to_func(statechart_puppet_id) }
				});
				this.client_socket.post_command(command);
			} else if(type === "rename_state") {
				state = event.state;
				var new_name = event.new_name;
				var old_name = state.get_name("parent");
				parent_puppet_id = state.parent().puppet_master_id || state.parent().id();
				command = new red.RenameStateCommand({
					statechart: { id: to_func(parent_puppet_id) },
					from: old_name,
					to: new_name
				});
				this.client_socket.post_command(command);
			} else if (type === 'set_transition_str') {
				transition = event.transition;
				var str = event.str;
				var transition_id = transition.puppet_master_id || transition.id();
				command = new red.SetTransitionEventCommand({
					transition: { id: to_func(transition_id) },
					event: str
				});
				this.client_socket.post_command(command);
			} else if (type === 'set_copies') {
				value = event.str;
				client = event.client;
				command = new red.SetCopiesCommand({
					parent: { id: to_func(client.obj_id) },
					value: value
				});
				this.client_socket.post_command(command);
			} else if (type === 'reset') {
				client = event.client;
				command = new red.ResetCommand({
					parent: { id: to_func(client.cobj_id) }
				});
				this.client_socket.post_command(command);
			} else if (type === 'make_concurrent') {
				state = event.state;
				var state_puppet_id = state.puppet_master_id || state.id();
				command = new red.MakeConcurrentCommand({
					statechart: { id: to_func(state_puppet_id) },
					concurrent: event.concurrent
				});
				this.client_socket.post_command(command);
			} else if (type === 'move_prop') {
				var from_obj = event.from_obj;
				var from_name = event.from_name;
				var target_obj = event.target_obj;
				var target_name = event.target_name;
				var above_below = event.above_below;
				console.log(target_obj);

				command = new red.MovePropAboveBelowCommand({
					from_obj: { id: to_func(from_obj.obj_id) },
					from_name: from_name,
					target_obj: { id: to_func(target_obj.obj_id) },
					target_name: target_name,
					above_below: above_below
				});
				this.client_socket.post_command(command);
			} else {
				console.log("Unhandled type " + type);
			}
		},

		undo: function() {
			this.client_socket.post_command("undo");
		},
		redo: function() {
			this.client_socket.post_command("redo");
		},
		reset: function() {
			this.client_socket.post_command("reset");
		},

		on_unload: function() {
			this.navigator.navigator("destroy");
			this.menu.menu("destroy").remove();
			this.client_socket.destroy();
		},

		_destroy: function () {
			this.on_unload();
		},

		_setOption: function(key, value) {
			this._super(key, value);
			if(key === "anotations") {
				this.navigator.navigator("option", key, value);
			}
		}
	});
}(red, jQuery));
<|endoftext|>


<commit_before>import React from 'react'
import {Link} from 'react-router'
import {Row, Jumbotron, ListGroup, ListGroupItem} from 'react-bootstrap'

const Projects = [
  {
    link: 'wikipedia',
    name: 'Wikipedia Viewer'
  },
  {
    link: 'twitch',
    name: 'Twitch.tv Streamers Table'
  },
  {
    link: 'gardenize',
    name: 'Simple Q/A service for Gardenize junior js developer position'
  }
]

export class HomeView extends React.Component {
  render () {
    return (
      <Row>
        <Jumbotron>

Glad to see you, stranger :)

My name is Vlad, and I'm building applications to pass the FreeCodeCamp FrontEnd serticifation.

All of them builded with React and Redux. Here the full list:

          <ListGroup>
            {Projects.map(({link, name}) => <ListGroupItem
              key={link + name}
              >
              <Link to={link}>{name}</Link>
            </ListGroupItem>
            )}
          </ListGroup>
        </Jumbotron>
      </Row>
    )
  }
}

export default HomeView
<commit_msg>add calculator link to home<commit_after>import React from 'react'
import {Link} from 'react-router'
import {Row, Jumbotron, ListGroup, ListGroupItem} from 'react-bootstrap'

const Projects = [
  {
    link: 'wikipedia',
    name: 'Wikipedia Viewer'
  },
  {
    link: 'twitch',
    name: 'Twitch.tv Streamers Table'
  },
  {
    link: 'gardenize',
    name: 'Simple Q/A service for Gardenize junior js developer position'
  },
  {
    link: 'calculator',
    name: 'Calculator with keyboard support'
  }
]

export class HomeView extends React.Component {
  render () {
    return (
      <Row>
        <Jumbotron>

Glad to see you, stranger :)

My name is Vlad, and I'm building applications to pass the FreeCodeCamp FrontEnd serticifation.

All of them builded with React and Redux. Here the full list:

          <ListGroup>
            {Projects.map(({link, name}) => <ListGroupItem
              key={link + name}
              >
              <Link to={link}>{name}</Link>
            </ListGroupItem>
            )}
          </ListGroup>
        </Jumbotron>
      </Row>
    )
  }
}

export default HomeView
<|endoftext|>


<commit_before>import React from 'react';
import { Field, reduxForm } from 'redux-form';

import { compose } from 'recompose/compose';
import { withHandlers } from 'recompose/withHandlers';
import { setPropTypes } from 'recompose/setPropTypes';

import { auth } from 'vclub/redux/club/auth';

import styles from './AuthPage.css';

const validate = values => {
  const errors = {};

  if (!values.username) {
    errors.username = 'Пожалуйста, введите Ваше имя !!!';
  } else if (values.username.length > 15) {
    errors.username = 'Имя должно быть 15 символов или меньше';
  }

  return errors;
};

// eslint-disable-next-line react/prop-types
const AuthInputField = ({ input, type, placeholder, className, meta: { touched, error } }) => (

      <input
        {...input}
        type={type}
        placeholder={placeholder}
        className={className}
        autoFocus
      />
      {touched
      && error
      && {error}}

);

const enhance = compose(
  setPropTypes({
    dispatch: React.PropTypes.func.isRequired,
  }),
  withHandlers({
    onSubmit: (props) => (data) => {
      const { dispatch } = props;
      const { username, master, remember } = data;

      dispatch(auth({ username, master }, remember));
    },
  }),
  reduxForm({
    form: 'auth',
    initialValues: {
      username: '',
      master: false,
      remember: true,
    },
    validate,
  }),
);

const AuthPage = (props) => {
  const { handleSubmit } = props;

  return (

      <form className={styles.login} onSubmit={handleSubmit}>
        <fieldset className={styles.form_group}>

              <Field
                name="username"
                component={AuthInputField}
                type="text"
                placeholder="Имя..."
                className={styles.input_name}
                onFocus
              />

              <Field
                name="master"
                id="master"
                component="input"
                type="checkbox"
              />

Ведущий

              <Field
                name="remember"
                id="remember"
                component="input"
                type="checkbox"
              />

Запомнить

          <button
            className={styles.btn}
            type="submit"
          >
            Войти
          </button>
        </fieldset>
      </form>

  );
};

AuthPage.propTypes = {
  handleSubmit: React.PropTypes.func.isRequired,
};

export default enhance(AuthPage);
<commit_msg>fix recompose imports<commit_after>import React from 'react';
import { Field, reduxForm } from 'redux-form';

import compose from 'recompose/compose';
import withHandlers from 'recompose/withHandlers';
import setPropTypes from 'recompose/setPropTypes';

import { auth } from 'vclub/redux/club/auth';

import styles from './AuthPage.css';

const validate = values => {
  const errors = {};

  if (!values.username) {
    errors.username = 'Пожалуйста, введите Ваше имя !!!';
  } else if (values.username.length > 15) {
    errors.username = 'Имя должно быть 15 символов или меньше';
  }

  return errors;
};

// eslint-disable-next-line react/prop-types
const AuthInputField = ({ input, type, placeholder, className, meta: { touched, error } }) => (

      <input
        {...input}
        type={type}
        placeholder={placeholder}
        className={className}
        autoFocus
      />
      {touched
      && error
      && {error}}

);

const enhance = compose(
  setPropTypes({
    dispatch: React.PropTypes.func.isRequired,
  }),
  withHandlers({
    onSubmit: (props) => (data) => {
      const { dispatch } = props;
      const { username, master, remember } = data;

      dispatch(auth({ username, master }, remember));
    },
  }),
  reduxForm({
    form: 'auth',
    initialValues: {
      username: '',
      master: false,
      remember: true,
    },
    validate,
  }),
);

const AuthPage = (props) => {
  const { handleSubmit } = props;

  return (

      <form className={styles.login} onSubmit={handleSubmit}>
        <fieldset className={styles.form_group}>

              <Field
                name="username"
                component={AuthInputField}
                type="text"
                placeholder="Имя..."
                className={styles.input_name}
                onFocus
              />

              <Field
                name="master"
                id="master"
                component="input"
                type="checkbox"
              />

Ведущий

              <Field
                name="remember"
                id="remember"
                component="input"
                type="checkbox"
              />

Запомнить

          <button
            className={styles.btn}
            type="submit"
          >
            Войти
          </button>
        </fieldset>
      </form>

  );
};

AuthPage.propTypes = {
  handleSubmit: React.PropTypes.func.isRequired,
};

export default enhance(AuthPage);
<|endoftext|>


<commit_before>
(function(){
    // Simple vertical bar chart
    // -------------------------

    var ColumnChart = Datawrapper.Visualizations.ColumnChart = function() {

    };

    _.extend(ColumnChart.prototype, Datawrapper.Visualizations.RaphaelChart.prototype, {

        render: function(el) {
            var me = this, filterUI, sortBars, reverse, c, ds, chart_width, series_gap, row_gap, row;

            el = $(el);

            this.setRoot(el);

            row = 0;
            if (!_.isUndefined(me.get('selected-row'))) {
                row = me.get('selected-row', 0);
                if (row > me.chart.numRows()) row = 0;
            }

            filterUI = me.getFilterUI(row);
            if (filterUI) {
                $('#header').append(filterUI);
            }

            sortBars = me.get('sort-values');
            reverse = me.get('reverse-order');
            c = me.initCanvas({}, 0, filterUI ? filterUI.height() + 10 : 0);
            ds = me.chart.__dataset;
            chart_width = c.w - c.lpad - c.rpad;
            series_gap = 0.05; // pull from theme
            row_gap = 0.01;

            // 2d -> 1d
            if (me.chart.numRows() > 1) me.chart.filterRow(row);

            if (filterUI) c.tpad += 10;

            me.init();

            // compute maximum x-label height
            var lh = 0,
                n = me.chart.dataSeries().length;
            _.each(me.chart.dataSeries(), function(series, s) {
                lh = Math.max(lh, me.labelHeight(series.name, 'series', c.w / (n)));
            });
            c.bpad = lh+10;

            me.initDimensions();

            $('.tooltip').hide();

            if (!me.theme.columnChart.cutGridLines) me.horzGrid();

            var base = me.theme.colors.palette[me.get('base-color', 0)],
                bLch = chroma.color(base).lch(),
                ml = Math.min(bLch.l, 50),
                colors = [];

            colors = d3.range(ml, 91, (90 - ml) / (me.chart.numRows() - 1)).map(function(l) {
                return chroma.lch(l, bLch.c, bLch.h).hex();
            }).reverse();

            ds.eachRow(function(i) {
                me.setRowColor(i, colors[i % colors.length]);
            });

            _.each(me.chart.dataSeries(sortBars, reverse), function(series, s) {
                _.each(series.data, function(val, r) {
                    var d = me.barDimensions(series, s, r);
                    var fill = me.getBarColor(series, r, me.get('negative-color', false)),
                        stroke = chroma.color(fill).darken(14).hex();
                    // create bar
                    me.registerSeriesElement(c.paper.rect().attr(d).attr({
                        'stroke': stroke,
                        'fill': fill
                    }).data('strokeCol', stroke), series, r);

                    var val_y = val > 0 ? d.y - 10 : d.y + d.height + 10,
                        lbl_y = val <= 0 ? d.y - 10 : d.y + d.height + 5,
                        lblcl = ['series'],
                        lbl_w = c.w / (n+2),
                        valign = val > 0 ? 'top' : 'bottom',
                        halign = 'center',
                        alwaysShow = (me.chart.hasHighlight() && me.chart.isHighlighted(series)) || (d.width > 40);

                    var lpos = me.labelPosition(series, s, r, 'value'),
                        spos = me.labelPosition(series, s, r, 'series');

                    // add value labels
                    me.registerSeriesLabel(me.label(lpos.left, lpos.top, me.chart.formatValue(series.data[r]),{
                        w: lpos.width,
                        align: 'center',
                        cl: 'value outline ' + (alwaysShow ? '' : ' showOnHover')
                    }), series);

                    if (me.chart.hasHighlight() && me.chart.isHighlighted(series)) {
                        lblcl.push('highlighted');
                    }
                    if (d.bw < 30) {
                        halign = 'right';
                    }
                    if (d.bw < 20) {
                        lblcl.push('smaller');
                    }
                    // add series label
                    if (!/^X\.\d+$/.test(series.name) && r === 0) {
                        me.registerSeriesLabel(me.label(spos.left, spos.top, series.name, {
                            w: spos.width,
                            align: spos.halign,
                            valign: spos.valign,
                            cl: lblcl.join(' '),
                            rotate: d.bw < 30 ? -90 : 0
                        }), series);
                    }

                });
            });

            var y = c.h - me.__scales.y(0) - c.bpad;
            /*me.path([['M', c.lpad, y], ['L', c.w - c.rpad, y]], 'axis')
                .attr(me.theme.yAxis);*/

            // enable mouse events
            el.mousemove(_.bind(me.onMouseMove, me));

            if (me.chart.numRows() > 1) {
                // add legend
                var l = $('

'),
                    xo = 0;

                me.chart.__dataset.eachRow(function(r) {
                    div = $('

');
                    div.css({
                        background: me.getBarColor(null, r),
                        width: 12,
                        height: 12,
                        position: 'absolute',
                        left: xo,
                        top: 1
                    });
                    l.append(div);
                    lbl = me.label(xo + 15, 0, me.chart.__dataset.rowName(r), {
                        valign: 'left',
                        root: l
                    });
                    xo += me.labelWidth(me.chart.__dataset.rowName(r))+30;
                });
                l.css({
                    position: 'relative'
                });
                $('#header', c.root.parent()).append(l);
            }
            $('.showOnHover').hide();

            if (me.theme.columnChart.cutGridLines) me.horzGrid();
            if (me.__gridLines && me.__gridLines['0']) me.__gridLines['0'].toFront();
        },

        update: function(row) {
            var me = this;
            // re-filter dataset
            me.chart.filterRow(row);

            // update scales
            me.initDimensions();

            // update axis and grid
            me.horzGrid();

            // update bar heights and labels
            _.each(me.chart.dataSeries(), function(series, s) {
                _.each(me.__seriesElements[series.name], function(rect) {
                    var dim = me.barDimensions(series, s, 0);
                    rect.animate(dim, me.theme.duration, me.theme.easing);
                });

                _.each(me.__seriesLabels[series.name], function(lbl) {
                    var lpos;
                    if (lbl.hasClass('value')) {
                        // update value
                        lbl.text(me.chart.formatValue(series.data[0]));
                        lpos = me.labelPosition(series, s, 0, 'value');
                    } else if (lbl.hasClass('series')) {
                        // update series label position
                        lpos = me.labelPosition(series, s, 0, 'series');
                    }
                    if (lpos) {
                        lbl.animate({
                            x: lpos.left,
                            y: lpos.top,
                            align: lpos.halign,
                            valign: lpos.valign
                        }, me.theme.duration, me.theme.easing);
                    }
                });
            });
            me.__gridLines['0'].toFront();
        },

        getBarColor: function(series, row, useNegativeColor, colorful) {
            var me = this,
                main = series && useNegativeColor && series.data[row] < 0 ? 'negative' : 'main',
                hl = series && me.chart.hasHighlight() && me.chart.isHighlighted(series);

            return me.getSeriesColor(series, row, useNegativeColor);
        },

        initDimensions: function(r) {
            //
            var me = this, c = me.__canvas,
                dMin = 0, dMax = 0;
            _.each(me.chart.dataSeries(), function(series) {
                if (!isNaN(series.min)) dMin = Math.min(dMin, series.min);
                if (!isNaN(series.max)) dMax = Math.max(dMax, series.max);
            });
            me.__domain = [dMin, dMax];
            me.__scales = {
                y: d3.scale.linear().domain([dMin, dMax])
            };

            me.__scales.y.rangeRound([0, c.h - c.bpad - c.tpad]);
        },

        barDimensions: function(series, s, r) {
            var me = this,
                sc = me.__scales,
                c = me.__canvas,
                n = me.chart.dataSeries().length,
                w, h, x, y, i, cw, bw,
                pad = 0.35,
                vspace = 0.1,
                val = series.data[r];

            if (isNaN(val)) val = 0;

            if (c.w / n < 30) vspace = 0.05;

            cw = (c.w - c.lpad - c.rpad) * (1 - vspace - vspace);
            bw = cw / (n + (n-1) * pad);
            h = sc.y(val) - sc.y(0);
            w = Math.round(bw / series.data.length);
            if (h >= 0) {
                y = c.h - c.bpad - sc.y(0) - h;
            } else {
                y = c.h - c.bpad - sc.y(0);
                h *= -1;
            }
            x = Math.round((c.w - c.lpad - c.rpad) * vspace + c.lpad + s * (bw + bw * pad));
            return { width: w, height: h, x: x + Math.floor((w+1)*r), y: y, bx: x, bw: bw };
        },

        labelPosition: function(series, s, r, type) {
            var me = this, d = me.barDimensions(series, s, r),
                val = series.data[r],
                c = me.__canvas,
                lbl_top = val >= 0 || isNaN(val),
                valign = lbl_top ? 'top' : 'bottom',
                halign = 'center',
                lbl_w = c.w / (me.chart.dataSeries().length+2),
                val_y = lbl_top ? d.y - 10 : d.y + d.height + 10,
                lbl_y = !lbl_top ? d.y - 10 : d.y + d.height + 5;

            if (type == "value") {
                return { left: d.x + d.width * 0.5, top: val_y, width: d.width };
            } else if (type == "series") {
                if (d.bw < 30) {
                    //lblcl.push('rotate90');
                    lbl_y += 5;
                    lbl_w = 100;
                    halign = 'right'; // lbl_top ? 'right' : 'left';
                }
                if (d.bw < 20) {
                    lbl_w = 90;
                }
                return { left: d.bx + d.bw * 0.5, top: lbl_y, width: lbl_w, halign: halign, valign: valign };
            }
        },

        getDataRowByPoint: function(x, y) {
            return 0;
        },

        showTooltip: function() {

        },

        hideTooltip: function() {

        },

        horzGrid: function() {
            // draw tick marks and labels
            var me = this,
                yscale = me.__scales.y,
                c = me.__canvas,
                domain = me.__domain,
                styles = me.__styles,
                ticks = me.getYTicks(c.h, true),
                tickLabels = me.__tickLabels = me.__tickLabels || {},
                gridLines = me.__gridLines = me.__gridLines || {};

            ticks = ticks.filter(function(val, t) {
                return val >= domain[0] && val <= domain[1];
            });

            _.each(ticks, function(val, t) {
                var y = c.h - c.bpad - yscale(val), x = c.lpad, ly = y-10;
                // c.paper.text(x, y, val).attr(styles.labels).attr({ 'text-anchor': 'end' });
                if (me.theme.columnChart.cutGridLines) ly += 10;
                var key = String(val);
                // show or update label
                if (val !== 0) {
                    var lbl = tickLabels[key] = tickLabels[key] ||
                        me.label(x+2, ly, me.chart.formatValue(val, t == ticks.length-1, true),
                            { align: 'left', cl: 'axis', css: { opacity: 0 } });
                    lbl.animate({ x: c.lpad+2, y: ly, css: { opacity: 1 } }, me.theme.duration, me.theme.easing);
                }
                if (me.theme.yTicks) {
                    me.path([['M', c.lpad-25, y], ['L', c.lpad-20,y]], 'tick');
                }
                if (me.theme.horizontalGrid) {
                    var lattrs = { path: [['M', c.lpad, y], ['L', c.w - c.rpad,y]], opacity: 1 },
                        l = gridLines[key] = gridLines[key] || me.path(lattrs.path, 'grid');
                    l.toBack();
                    if (val === 0) {
                        lattrs = $.extend(me.theme.xAxis, lattrs);
                        l.toFront();
                    } else {
                        l.attr(me.theme.horizontalGrid);
                        lattrs = $.extend(me.theme.horizontalGrid, lattrs);
                    }
                    if (val !== 0 && me.theme.columnChart.cutGridLines) lattrs.stroke = me.theme.colors.background;
                    l.animate(lattrs, me.theme.duration, me.theme.easing);
                }
            });
            // hide invisible grid lines
            $.each(gridLines, function(val, line) {
                if (_.indexOf(ticks, Number(val)) < 0) {
                    var y = c.h - c.bpad - yscale(val), props;
                    props = $.extend(me.theme.horizontalGrid, { path: [['M', c.lpad, y], ['L', c.w - c.rpad, y]], opacity: 0 });
                    line.animate(props, me.theme.duration, me.theme.easing);
                    if (tickLabels[val]) {
                        var lbl = tickLabels[val];

                        tickLabels[val].animate({
                            x: c.lpad+2,
                            y: y + (me.theme.columnChart.cutGridLines ? -10 : 0),
                            css: {
                                opacity: 0
                            }
                        }, me.theme.duration, me.theme.easing );

                        // lattrs.top = Math.min(lattrs.top, c.h);
                        // tickLabels[val].animate(lattrs, { duration: me.theme.duration, easing: me.theme.easing });
                    }
                }
            });
        },

        hoverSeries: function(series) {
            var me = this;
            _.each(me.chart.dataSeries(), function(s) {
                _.each(me.__seriesLabels[s.name], function(lbl) {
                    if (series !== undefined && s.name == series.name) {
                        lbl.addClass('hover');
                        if (lbl.hasClass('showOnHover')) lbl.show(0.5);
                    } else {
                        lbl.removeClass('hover');
                        if (lbl.hasClass('showOnHover')) lbl.hide(0.5);
                    }
                    _.each(me.__seriesElements[s.name], function(el) {
                        var fill = me.getBarColor(s, el.data('row'), me.get('negative-color', false)), stroke;
                        if (series !== undefined && s.name == series.name) fill = chroma.color(fill).darken(14).hex();
                        stroke = chroma.color(fill).darken(18).hex();
                        if (el.attrs.fill != fill || el.attrs.stroke != stroke)
                            el.animate({ fill: fill, stroke: stroke }, 50);
                    });
                });
            });
        },

        unhoverSeries: function() {
            this.hoverSeries();
        }
    });

}).call(this);<commit_msg>checking for gridline exists<commit_after>
(function(){
    // Simple vertical bar chart
    // -------------------------

    var ColumnChart = Datawrapper.Visualizations.ColumnChart = function() {

    };

    _.extend(ColumnChart.prototype, Datawrapper.Visualizations.RaphaelChart.prototype, {

        render: function(el) {
            var me = this, filterUI, sortBars, reverse, c, ds, chart_width, series_gap, row_gap, row;

            el = $(el);

            this.setRoot(el);

            row = 0;
            if (!_.isUndefined(me.get('selected-row'))) {
                row = me.get('selected-row', 0);
                if (row > me.chart.numRows()) row = 0;
            }

            filterUI = me.getFilterUI(row);
            if (filterUI) {
                $('#header').append(filterUI);
            }

            sortBars = me.get('sort-values');
            reverse = me.get('reverse-order');
            c = me.initCanvas({}, 0, filterUI ? filterUI.height() + 10 : 0);
            ds = me.chart.__dataset;
            chart_width = c.w - c.lpad - c.rpad;
            series_gap = 0.05; // pull from theme
            row_gap = 0.01;

            // 2d -> 1d
            if (me.chart.numRows() > 1) me.chart.filterRow(row);

            if (filterUI) c.tpad += 10;

            me.init();

            // compute maximum x-label height
            var lh = 0,
                n = me.chart.dataSeries().length;
            _.each(me.chart.dataSeries(), function(series, s) {
                lh = Math.max(lh, me.labelHeight(series.name, 'series', c.w / (n)));
            });
            c.bpad = lh+10;

            me.initDimensions();

            $('.tooltip').hide();

            if (!me.theme.columnChart.cutGridLines) me.horzGrid();

            var base = me.theme.colors.palette[me.get('base-color', 0)],
                bLch = chroma.color(base).lch(),
                ml = Math.min(bLch.l, 50),
                colors = [];

            colors = d3.range(ml, 91, (90 - ml) / (me.chart.numRows() - 1)).map(function(l) {
                return chroma.lch(l, bLch.c, bLch.h).hex();
            }).reverse();

            ds.eachRow(function(i) {
                me.setRowColor(i, colors[i % colors.length]);
            });

            _.each(me.chart.dataSeries(sortBars, reverse), function(series, s) {
                _.each(series.data, function(val, r) {
                    var d = me.barDimensions(series, s, r);
                    var fill = me.getBarColor(series, r, me.get('negative-color', false)),
                        stroke = chroma.color(fill).darken(14).hex();
                    // create bar
                    me.registerSeriesElement(c.paper.rect().attr(d).attr({
                        'stroke': stroke,
                        'fill': fill
                    }).data('strokeCol', stroke), series, r);

                    var val_y = val > 0 ? d.y - 10 : d.y + d.height + 10,
                        lbl_y = val <= 0 ? d.y - 10 : d.y + d.height + 5,
                        lblcl = ['series'],
                        lbl_w = c.w / (n+2),
                        valign = val > 0 ? 'top' : 'bottom',
                        halign = 'center',
                        alwaysShow = (me.chart.hasHighlight() && me.chart.isHighlighted(series)) || (d.width > 40);

                    var lpos = me.labelPosition(series, s, r, 'value'),
                        spos = me.labelPosition(series, s, r, 'series');

                    // add value labels
                    me.registerSeriesLabel(me.label(lpos.left, lpos.top, me.chart.formatValue(series.data[r]),{
                        w: lpos.width,
                        align: 'center',
                        cl: 'value outline ' + (alwaysShow ? '' : ' showOnHover')
                    }), series);

                    if (me.chart.hasHighlight() && me.chart.isHighlighted(series)) {
                        lblcl.push('highlighted');
                    }
                    if (d.bw < 30) {
                        halign = 'right';
                    }
                    if (d.bw < 20) {
                        lblcl.push('smaller');
                    }
                    // add series label
                    if (!/^X\.\d+$/.test(series.name) && r === 0) {
                        me.registerSeriesLabel(me.label(spos.left, spos.top, series.name, {
                            w: spos.width,
                            align: spos.halign,
                            valign: spos.valign,
                            cl: lblcl.join(' '),
                            rotate: d.bw < 30 ? -90 : 0
                        }), series);
                    }

                });
            });

            var y = c.h - me.__scales.y(0) - c.bpad;
            /*me.path([['M', c.lpad, y], ['L', c.w - c.rpad, y]], 'axis')
                .attr(me.theme.yAxis);*/

            // enable mouse events
            el.mousemove(_.bind(me.onMouseMove, me));

            if (me.chart.numRows() > 1) {
                // add legend
                var l = $('

'),
                    xo = 0;

                me.chart.__dataset.eachRow(function(r) {
                    div = $('

');
                    div.css({
                        background: me.getBarColor(null, r),
                        width: 12,
                        height: 12,
                        position: 'absolute',
                        left: xo,
                        top: 1
                    });
                    l.append(div);
                    lbl = me.label(xo + 15, 0, me.chart.__dataset.rowName(r), {
                        valign: 'left',
                        root: l
                    });
                    xo += me.labelWidth(me.chart.__dataset.rowName(r))+30;
                });
                l.css({
                    position: 'relative'
                });
                $('#header', c.root.parent()).append(l);
            }
            $('.showOnHover').hide();

            if (me.theme.columnChart.cutGridLines) me.horzGrid();
            if (me.__gridLines && me.__gridLines['0']) me.__gridLines['0'].toFront();
        },

        update: function(row) {
            var me = this;
            // re-filter dataset
            me.chart.filterRow(row);

            // update scales
            me.initDimensions();

            // update axis and grid
            me.horzGrid();

            // update bar heights and labels
            _.each(me.chart.dataSeries(), function(series, s) {
                _.each(me.__seriesElements[series.name], function(rect) {
                    var dim = me.barDimensions(series, s, 0);
                    rect.animate(dim, me.theme.duration, me.theme.easing);
                });

                _.each(me.__seriesLabels[series.name], function(lbl) {
                    var lpos;
                    if (lbl.hasClass('value')) {
                        // update value
                        lbl.text(me.chart.formatValue(series.data[0]));
                        lpos = me.labelPosition(series, s, 0, 'value');
                    } else if (lbl.hasClass('series')) {
                        // update series label position
                        lpos = me.labelPosition(series, s, 0, 'series');
                    }
                    if (lpos) {
                        lbl.animate({
                            x: lpos.left,
                            y: lpos.top,
                            align: lpos.halign,
                            valign: lpos.valign
                        }, me.theme.duration, me.theme.easing);
                    }
                });
            });
            if (me.__gridLines['0']) me.__gridLines['0'].toFront();
        },

        getBarColor: function(series, row, useNegativeColor, colorful) {
            var me = this,
                main = series && useNegativeColor && series.data[row] < 0 ? 'negative' : 'main',
                hl = series && me.chart.hasHighlight() && me.chart.isHighlighted(series);

            return me.getSeriesColor(series, row, useNegativeColor);
        },

        initDimensions: function(r) {
            //
            var me = this, c = me.__canvas,
                dMin = 0, dMax = 0;
            _.each(me.chart.dataSeries(), function(series) {
                if (!isNaN(series.min)) dMin = Math.min(dMin, series.min);
                if (!isNaN(series.max)) dMax = Math.max(dMax, series.max);
            });
            me.__domain = [dMin, dMax];
            me.__scales = {
                y: d3.scale.linear().domain([dMin, dMax])
            };

            me.__scales.y.rangeRound([0, c.h - c.bpad - c.tpad]);
        },

        barDimensions: function(series, s, r) {
            var me = this,
                sc = me.__scales,
                c = me.__canvas,
                n = me.chart.dataSeries().length,
                w, h, x, y, i, cw, bw,
                pad = 0.35,
                vspace = 0.1,
                val = series.data[r];

            if (isNaN(val)) val = 0;

            if (c.w / n < 30) vspace = 0.05;

            cw = (c.w - c.lpad - c.rpad) * (1 - vspace - vspace);
            bw = cw / (n + (n-1) * pad);
            h = sc.y(val) - sc.y(0);
            w = Math.round(bw / series.data.length);
            if (h >= 0) {
                y = c.h - c.bpad - sc.y(0) - h;
            } else {
                y = c.h - c.bpad - sc.y(0);
                h *= -1;
            }
            x = Math.round((c.w - c.lpad - c.rpad) * vspace + c.lpad + s * (bw + bw * pad));
            return { width: w, height: h, x: x + Math.floor((w+1)*r), y: y, bx: x, bw: bw };
        },

        labelPosition: function(series, s, r, type) {
            var me = this, d = me.barDimensions(series, s, r),
                val = series.data[r],
                c = me.__canvas,
                lbl_top = val >= 0 || isNaN(val),
                valign = lbl_top ? 'top' : 'bottom',
                halign = 'center',
                lbl_w = c.w / (me.chart.dataSeries().length+2),
                val_y = lbl_top ? d.y - 10 : d.y + d.height + 10,
                lbl_y = !lbl_top ? d.y - 10 : d.y + d.height + 5;

            if (type == "value") {
                return { left: d.x + d.width * 0.5, top: val_y, width: d.width };
            } else if (type == "series") {
                if (d.bw < 30) {
                    //lblcl.push('rotate90');
                    lbl_y += 5;
                    lbl_w = 100;
                    halign = 'right'; // lbl_top ? 'right' : 'left';
                }
                if (d.bw < 20) {
                    lbl_w = 90;
                }
                return { left: d.bx + d.bw * 0.5, top: lbl_y, width: lbl_w, halign: halign, valign: valign };
            }
        },

        getDataRowByPoint: function(x, y) {
            return 0;
        },

        showTooltip: function() {

        },

        hideTooltip: function() {

        },

        horzGrid: function() {
            // draw tick marks and labels
            var me = this,
                yscale = me.__scales.y,
                c = me.__canvas,
                domain = me.__domain,
                styles = me.__styles,
                ticks = me.getYTicks(c.h, true),
                tickLabels = me.__tickLabels = me.__tickLabels || {},
                gridLines = me.__gridLines = me.__gridLines || {};

            ticks = ticks.filter(function(val, t) {
                return val >= domain[0] && val <= domain[1];
            });

            _.each(ticks, function(val, t) {
                var y = c.h - c.bpad - yscale(val), x = c.lpad, ly = y-10;
                // c.paper.text(x, y, val).attr(styles.labels).attr({ 'text-anchor': 'end' });
                if (me.theme.columnChart.cutGridLines) ly += 10;
                var key = String(val);
                // show or update label
                if (val !== 0) {
                    var lbl = tickLabels[key] = tickLabels[key] ||
                        me.label(x+2, ly, me.chart.formatValue(val, t == ticks.length-1, true),
                            { align: 'left', cl: 'axis', css: { opacity: 0 } });
                    lbl.animate({ x: c.lpad+2, y: ly, css: { opacity: 1 } }, me.theme.duration, me.theme.easing);
                }
                if (me.theme.yTicks) {
                    me.path([['M', c.lpad-25, y], ['L', c.lpad-20,y]], 'tick');
                }
                if (me.theme.horizontalGrid) {
                    var lattrs = { path: [['M', c.lpad, y], ['L', c.w - c.rpad,y]], opacity: 1 },
                        l = gridLines[key] = gridLines[key] || me.path(lattrs.path, 'grid');
                    l.toBack();
                    if (val === 0) {
                        lattrs = $.extend(me.theme.xAxis, lattrs);
                        l.toFront();
                    } else {
                        l.attr(me.theme.horizontalGrid);
                        lattrs = $.extend(me.theme.horizontalGrid, lattrs);
                    }
                    if (val !== 0 && me.theme.columnChart.cutGridLines) lattrs.stroke = me.theme.colors.background;
                    l.animate(lattrs, me.theme.duration, me.theme.easing);
                }
            });
            // hide invisible grid lines
            $.each(gridLines, function(val, line) {
                if (_.indexOf(ticks, Number(val)) < 0) {
                    var y = c.h - c.bpad - yscale(val), props;
                    props = $.extend(me.theme.horizontalGrid, { path: [['M', c.lpad, y], ['L', c.w - c.rpad, y]], opacity: 0 });
                    line.animate(props, me.theme.duration, me.theme.easing);
                    if (tickLabels[val]) {
                        var lbl = tickLabels[val];

                        tickLabels[val].animate({
                            x: c.lpad+2,
                            y: y + (me.theme.columnChart.cutGridLines ? -10 : 0),
                            css: {
                                opacity: 0
                            }
                        }, me.theme.duration, me.theme.easing );

                        // lattrs.top = Math.min(lattrs.top, c.h);
                        // tickLabels[val].animate(lattrs, { duration: me.theme.duration, easing: me.theme.easing });
                    }
                }
            });
        },

        hoverSeries: function(series) {
            var me = this;
            _.each(me.chart.dataSeries(), function(s) {
                _.each(me.__seriesLabels[s.name], function(lbl) {
                    if (series !== undefined && s.name == series.name) {
                        lbl.addClass('hover');
                        if (lbl.hasClass('showOnHover')) lbl.show(0.5);
                    } else {
                        lbl.removeClass('hover');
                        if (lbl.hasClass('showOnHover')) lbl.hide(0.5);
                    }
                    _.each(me.__seriesElements[s.name], function(el) {
                        var fill = me.getBarColor(s, el.data('row'), me.get('negative-color', false)), stroke;
                        if (series !== undefined && s.name == series.name) fill = chroma.color(fill).darken(14).hex();
                        stroke = chroma.color(fill).darken(18).hex();
                        if (el.attrs.fill != fill || el.attrs.stroke != stroke)
                            el.animate({ fill: fill, stroke: stroke }, 50);
                    });
                });
            });
        },

        unhoverSeries: function() {
            this.hoverSeries();
        }
    });

}).call(this);<|endoftext|>