<commit_before>/* ========================================================================
 * ZUI: ajaxaction.js
 * http://zui.sexy
 * ========================================================================
 * Copyright (c) 2014 cnezsoft.com; Licensed MIT
 * ======================================================================== */

!(function($, document, window){
    'use strict';

    var DISABLED = 'disabled';
    var ajaxaction = function(options, $element) {
        // console.log('ajaxaction', options, $element);
        options = $.extend({
            spinner: 'spinner-indicator'
        }, options);

        var callEvent = function(name, event) {
            if(options && $.isFunction(options[name])) {
                return options[name](event);
            }
        };

        if(options.confirm && !confirm(options.confirm)) return;

        if(callEvent('before') === false) return;
        if($element) {
            if($element.hasClass(DISABLED)) return false;
            $element.addClass(DISABLED);
            if(options.spinner) {
                var $spinner = $element.find('.icon-' + options.spinner);
                if($spinner.length) $spinner.removeClass('hidden');
                else $element.prepend('<i class="icon icon-spin icon-' + options.spinner + '"> </i>');
            }
        }

        $[options.method || 'get'](options.url, options.data, function(response, status){
            if(status == 'success') {
                try {
                    response = $.parseJSON(response);
                    if(response.result === 'success') {
                        callEvent('onResultSuccess', response);
                        if(response.message) {
                            $.messager.success(response.message);
                            if(response.locate) {
                                setTimeout(function(){location.href = response.locate;}, 1200);
                            }
                        } else {
                            if(response.locate) location.href = response.locate;
                        }
                    } else {
                        callEvent('onResultFailed', response);
                        if(response.message) {
                            $.messager.show(response.message);
                            if(response.locate) {
                                setTimeout(function(){location.href = response.locate;}, 1200);
                            }
                        }
                    }
                } catch(e) {
                    callEvent('onNoResponse');
                }
                callEvent('onSuccess', response);
            } else {
                callEvent('onError', status);
                if(window.v && window.v.lang.timeout) {
                    $.messager.danger(window.v.lang.timeout);
                }
            }

            if($element) {
                $element.removeClass(DISABLED);
                if(options.spinner) {
                    var $spinner = $element.find('.icon-' + options.spinner);
                    if($spinner.length) $spinner.addClass('hidden');
                }
            }
            callEvent('onComplete', {response: response, status: status});
        });
    };

    $.ajaxaction = ajaxaction;

    $.fn.ajaxaction = function(options) {
        return this.each(function(){
            var $this   = $(this);
            var thisOption = $.extend({url: $this.attr('href')}, $this.data(), options);
            $this.on(thisOption.trigger || 'click', function(e) {
                e.preventDefault();
                ajaxaction(thisOption, $this);
            });
        });
    };

    $(document).on('click', '.ajaxaction, [data-toggle="action"]', function(e) {
        var $this   = $(this);
        var options = $.extend({url: $this.attr('href')}, $this.data(), options);
        e.preventDefault();
        ajaxaction(options, $this);
    });
}(CoreLib, document, window));
<commit_msg> * change 'click' to $.TapName.<commit_after>/* ========================================================================
 * ZUI: ajaxaction.js
 * http://zui.sexy
 * ========================================================================
 * Copyright (c) 2014 cnezsoft.com; Licensed MIT
 * ======================================================================== */

!(function($, document, window){
    'use strict';

    var DISABLED = 'disabled';
    var ajaxaction = function(options, $element) {
        // console.log('ajaxaction', options, $element);
        options = $.extend({
            spinner: 'spinner-indicator'
        }, options);

        var callEvent = function(name, event) {
            if(options && $.isFunction(options[name])) {
                return options[name](event);
            }
        };

        if(options.confirm && !confirm(options.confirm)) return;

        if(callEvent('before') === false) return;
        if($element) {
            if($element.hasClass(DISABLED)) return false;
            $element.addClass(DISABLED);
            if(options.spinner) {
                var $spinner = $element.find('.icon-' + options.spinner);
                if($spinner.length) $spinner.removeClass('hidden');
                else $element.prepend('<i class="icon icon-spin icon-' + options.spinner + '"> </i>');
            }
        }

        $[options.method || 'get'](options.url, options.data, function(response, status){
            if(status == 'success') {
                try {
                    response = $.parseJSON(response);
                    if(response.result === 'success') {
                        callEvent('onResultSuccess', response);
                        if(response.message) {
                            $.messager.success(response.message);
                            if(response.locate) {
                                setTimeout(function(){location.href = response.locate;}, 1200);
                            }
                        } else {
                            if(response.locate) location.href = response.locate;
                        }
                    } else {
                        callEvent('onResultFailed', response);
                        if(response.message) {
                            $.messager.show(response.message);
                            if(response.locate) {
                                setTimeout(function(){location.href = response.locate;}, 1200);
                            }
                        }
                    }
                } catch(e) {
                    callEvent('onNoResponse');
                }
                callEvent('onSuccess', response);
            } else {
                callEvent('onError', status);
                if(window.v && window.v.lang.timeout) {
                    $.messager.danger(window.v.lang.timeout);
                }
            }

            if($element) {
                $element.removeClass(DISABLED);
                if(options.spinner) {
                    var $spinner = $element.find('.icon-' + options.spinner);
                    if($spinner.length) $spinner.addClass('hidden');
                }
            }
            callEvent('onComplete', {response: response, status: status});
        });
    };

    $.ajaxaction = ajaxaction;

    $.fn.ajaxaction = function(options) {
        return this.each(function(){
            var $this   = $(this);
            var thisOption = $.extend({url: $this.attr('href')}, $this.data(), options);
            $this.on(thisOption.trigger || $.TapName, function(e) {
                e.preventDefault();
                ajaxaction(thisOption, $this);
            });
        });
    };

    $(document).on($.TapName, '.ajaxaction, [data-toggle="action"]', function(e) {
        var $this   = $(this);
        var options = $.extend({url: $this.attr('href')}, $this.data(), options);
        e.preventDefault();
        ajaxaction(options, $this);
    });
}(CoreLib, document, window));
<|endoftext|>


<commit_before>jQuery.noConflict();
(function($) {
  window.contextPath = '';
  $.plugin('card_editor', (function() {
    var cardElement;
    function baseUrl() {
      var path = "/api/v2/projects/"
      return window.contextPath + path;
    }
    function card_uri() {
      return baseUrl() + window.mingleProject + "/cards/" + window.number + '.xml';
    }
    function card_attachments_url() {
      return baseUrl() + window.mingleProject + "/cards/" + window.number + "/attachments.xml";
    }
    function ajaxErrorHandler(x) {
      console.log(x);
      cardElement.card_editor('status', 'error');
    }
    var upload_dropfile = function(wikimateElement) {
      var dialog, progressbar;
      return {
        post_url: card_attachments_url(),
        field_name: 'file',
        start: function(xhr, file) {
          progressbar = $('<div/>').progressbar({ value: 0 });
          dialog = $('<div/>').append(progressbar).dialog({
            title: "Uploading",
            modal: true
          });
          xhr.upload.addEventListener("progress", function (e) {
            if (e.lengthComputable) {
              var loaded = Math.ceil((e.loaded / e.total) * 100);
              progressbar.progressbar("value", loaded);
            }
          }, false);
        },
        complete: function(result, file) {
          if (dialog) {
            dialog.dialog('close');
            dialog.remove();
            dialog = null;
            var created_location = result.target.getResponseHeader('Location');
            created_location = created_location.split("?")[0];
            var file_name = _.last(created_location.split("/"));
            var item = (/image/i).test(file.type) ? {type: 'image', text: "!" + file_name + "!"} : {type: 'paragraph', text: "[[" + file_name + "]]"};
            wikimateElement.wikimate("newItem", item).story_item('save');
          }
        }
      };
    }

    return {
      init: function(card) {
        window.mingleProject = card.project;
        window.number = card.number;
        cardElement = this;
        this.card_editor('status', 'loading');
        var $this = this.addClass('card_editor');
        $.ajax({
          url: card_uri(),
          dataType: 'xml',
          success: function(xmlDoc) {
            $this.card_editor('initWikiMate', xmlDoc);
            $this.card_editor('status', 'idle');
          },
          failure: ajaxErrorHandler
        });
        return this;
      },

      initWikiMate: function(cardDoc) {
        var editingCard = $(cardDoc);
        window.editingCardId = editingCard.find('card id').text();
        var story = window.wiki_parser.parse(editingCard.find('card description').text());
        var $this = this;
        this.empty().wikimate({story: story, change: function(event, action) {
          $this.card_editor('update', event, action);
        }}).dropfile(upload_dropfile(this));
      },
      update: function(event, action) {
        this.card_editor('status', 'updating');
        var desc = wiki_parser.dump(this.wikimate('story'));

        var $this = this;
        $.ajax({
          url: card_uri(),
          dataType: 'xml',
          data: {card: {description: desc}},
          type: 'PUT',
          success: function(r) {
            $this.card_editor('status', 'idle');
          },
          failure: ajaxErrorHandler
        });
        return this;
      },

      renderWiki: function(content, onSuccess) {
        var paramStr = $.param({
          content_provider: {id: window.editingCardId, type: 'card'},
          content: content
        });
        $.ajax({
          url: baseUrl() + window.mingleProject + "/render?" + paramStr,
          dataType: 'html',
          success: onSuccess,
          failure: ajaxErrorHandler
        });
      },

      status: function(newStatus) {
        switch(newStatus) {
          case 'loading':
          case 'updating':
            this.css('border-left', '2px solid yellow');
            break;
          case 'error':
            this.css('border-left', '2px solid red');
            break;
          default:
            this.css('border-left', '2px solid orange');
        }
      }
    };
  })());

  var match = window.location.href.match(/\/projects\/([\da-z_]+)\/cards\/(\d+)[^\/]*$/);
  if (match && $('#card-edit-link-top').length > 0) {
    path = window.location.href.split("/");
    if (path[3] != 'projects') {
      window.contextPath = '/' + path[3];
    }
    $('#content').card_editor({project: match[1], number: match[2]});
  }
})(jQuery);
<commit_msg>fix image upload for new Mingle 12.4 release<commit_after>jQuery.noConflict();
(function($) {
  window.contextPath = '';
  $.plugin('card_editor', (function() {
    var cardElement;
    function baseUrl() {
      var path = "/api/v2/projects/"
      return window.contextPath + path;
    }
    function card_uri() {
      return baseUrl() + window.mingleProject + "/cards/" + window.number + '.xml';
    }
    function card_attachments_url() {
      return baseUrl() + window.mingleProject + "/cards/" + window.number + "/attachments.xml";
    }
    function ajaxErrorHandler(x) {
      console.log(x);
      cardElement.card_editor('status', 'error');
    }
    var upload_dropfile = function(wikimateElement) {
      var dialog, progressbar;
      return {
        post_url: card_attachments_url(),
        field_name: 'file',
        start: function(xhr, file) {
          progressbar = $('<div/>').progressbar({ value: 0 });
          dialog = $('<div/>').append(progressbar).dialog({
            title: "Uploading",
            modal: true
          });
          xhr.upload.addEventListener("progress", function (e) {
            if (e.lengthComputable) {
              var loaded = Math.ceil((e.loaded / e.total) * 100);
              progressbar.progressbar("value", loaded);
            }
          }, false);
        },
        complete: function(result, file) {
          if (dialog) {
            dialog.dialog('close');
            dialog.remove();
            dialog = null;
            // Mingle sanitize_filename logic, from file_column plugin
            // filename = File.basename(filename.gsub("\\", "/")) # work-around for IE
            // filename.gsub!(/[^\w0-9\.\-_]/,"_")
            // filename = "_#{filename}" if filename =~ /^\.+$/
            // filename = "unnamed" if filename.size == 0
            var file_name = file.name
            file_name = file_name.gsub(/[^\w0-9\.\-_]/,"_")
            if (/^\.+$/.test(file_name)) {
              file_name = "_" + file_name;
            }
            if (file_name.length == 0) {
              file_name = "unnamed"
            }
            var item = (/image/i).test(file.type) ? {type: 'image', text: "!" + file_name + "!"} : {type: 'paragraph', text: "[[" + file_name + "]]"};
            wikimateElement.wikimate("newItem", item).story_item('save');
          }
        }
      };
    }

    return {
      init: function(card) {
        window.mingleProject = card.project;
        window.number = card.number;
        cardElement = this;
        this.card_editor('status', 'loading');
        var $this = this.addClass('card_editor');
        $.ajax({
          url: card_uri(),
          dataType: 'xml',
          success: function(xmlDoc) {
            $this.card_editor('initWikiMate', xmlDoc);
            $this.card_editor('status', 'idle');
          },
          failure: ajaxErrorHandler
        });
        return this;
      },

      initWikiMate: function(cardDoc) {
        var editingCard = $(cardDoc);
        window.editingCardId = editingCard.find('card id').text();
        var story = window.wiki_parser.parse(editingCard.find('card description').text());
        var $this = this;
        this.empty().wikimate({story: story, change: function(event, action) {
          $this.card_editor('update', event, action);
        }}).dropfile(upload_dropfile(this));
      },
      update: function(event, action) {
        this.card_editor('status', 'updating');
        var desc = wiki_parser.dump(this.wikimate('story'));

        var $this = this;
        $.ajax({
          url: card_uri(),
          dataType: 'xml',
          data: {card: {description: desc}},
          type: 'PUT',
          success: function(r) {
            $this.card_editor('status', 'idle');
          },
          failure: ajaxErrorHandler
        });
        return this;
      },

      renderWiki: function(content, onSuccess) {
        var paramStr = $.param({
          content_provider: {id: window.editingCardId, type: 'card'},
          content: content
        });
        $.ajax({
          url: baseUrl() + window.mingleProject + "/render?" + paramStr,
          dataType: 'html',
          success: onSuccess,
          failure: ajaxErrorHandler
        });
      },

      status: function(newStatus) {
        switch(newStatus) {
          case 'loading':
          case 'updating':
            this.css('border-left', '2px solid yellow');
            break;
          case 'error':
            this.css('border-left', '2px solid red');
            break;
          default:
            this.css('border-left', '2px solid orange');
        }
      }
    };
  })());

  var match = window.location.href.match(/\/projects\/([\da-z_]+)\/cards\/(\d+)[^\/]*$/);
  if (match && $('#card-edit-link-top').length > 0) {
    path = window.location.href.split("/");
    if (path[3] != 'projects') {
      window.contextPath = '/' + path[3];
    }
    $('#content').card_editor({project: match[1], number: match[2]});
  }
})(jQuery);
<|endoftext|>


<commit_before>import * as THREE from 'three';

import config from '../config';

export class Hud {

    // ##############################################
    // # Constructor ################################
    // ##############################################

    constructor() {
        this.canvas    = document.createElement('canvas');
        this.canvas.width  = 1024;
        this.canvas.height = 1024;

        this.bitmap      = this.canvas.getContext('2d');
        this.bitmap.font      = 'Normal 40px Changa';
        this.bitmap.textAlign = 'center';
        this.bitmap.fillStyle = 'rgba(245, 245, 245, 0.7)';
        this.bitmap.fillText('Initializing...', config.canvasWidth / 2, config.canvasHeight / 2);

        this.camera = new THREE.OrthographicCamera(
            -config.canvasWidth / 2, config.canvasWidth / 2,
            config.canvasHeight / 2, -config.canvasHeight / 2,
            0, 300
        );

        this.scene   = new THREE.Scene();
        this.texture = new THREE.Texture(this.canvas)
        this.texture.needsUpdate = true;
        let material = new THREE.MeshBasicMaterial({map: this.texture });
        material.transparent = true;

        let planeGeometry = new THREE.PlaneGeometry(config.canvasWidth, config.canvasHeight);
        let plane         = new THREE.Mesh(planeGeometry, material);
        this.scene.add(plane);
    }

    // ##############################################
    // # Public functions ###########################
    // ##############################################

    update() {
        this.bitmap.clearRect(0, 0, config.canvasWidth, config.canvasHeight);
        this.bitmap.fillText('RAD]', config.canvasWidth / 2, config.canvasHeight / 2);
        this.texture.needsUpdate = true;
    }
}

export default Hud;<commit_msg>Whitespace<commit_after>import * as THREE from 'three';

import config from '../config';

export class Hud {

    // ##############################################
    // # Constructor ################################
    // ##############################################

    constructor() {
        this.canvas = document.createElement('canvas');
        this.canvas.width  = 1024;
        this.canvas.height = 1024;

        this.bitmap           = this.canvas.getContext('2d');
        this.bitmap.font      = 'Normal 40px Changa';
        this.bitmap.textAlign = 'center';
        this.bitmap.fillStyle = 'rgba(245, 245, 245, 0.7)';
        this.bitmap.fillText('Initializing...', config.canvasWidth / 2, config.canvasHeight / 2);

        this.camera = new THREE.OrthographicCamera(
            -config.canvasWidth / 2, config.canvasWidth / 2,
            config.canvasHeight / 2, -config.canvasHeight / 2,
            0, 300
        );

        this.scene   = new THREE.Scene();
        this.texture = new THREE.Texture(this.canvas)
        this.texture.needsUpdate = true;
        let material = new THREE.MeshBasicMaterial({map: this.texture });
        material.transparent = true;

        let planeGeometry = new THREE.PlaneGeometry(config.canvasWidth, config.canvasHeight);
        let plane         = new THREE.Mesh(planeGeometry, material);
        this.scene.add(plane);
    }

    // ##############################################
    // # Public functions ###########################
    // ##############################################

    update() {
        this.bitmap.clearRect(0, 0, config.canvasWidth, config.canvasHeight);
        this.bitmap.fillText('RAD]', config.canvasWidth / 2, config.canvasHeight / 2);
        this.texture.needsUpdate = true;
    }
}

export default Hud;<|endoftext|>


<commit_before>var EMPTYFN = function(){};
var _createStandardXHR = function(){
	try{
		return new window.XMLHttpRequest();
	}
	catch(e){
		return false;
	}
};
var _createActiveXHR = function(){
	try{
		return new window.ActiveXObject("Microsoft.XMLHTTP");
	}
	catch(e){
		return false;
	}
};

module.exports = function(options){
	var dataType = options.dataType || "text";
	var suc = options.success || EMPTYFN;
	var error = options.error || EMPTYFN;
	var useXDomainRequestInIE = options.useXDomainRequestInIE;
	var xhr = _createStandardXHR() || _createActiveXHR();
	var type = options.type || "GET";
	var data = options.data || {};
	var tempData = "";
	var headers = options.headers || {};
	var isFileUpload = options.isFileUpload;
	var disableTimeStampInGet = options.disableTimeStampInGet;
	var key;
	var fileForm;
	var o;

	if(useXDomainRequestInIE && window.XDomainRequest){
		xhr = new XDomainRequest();
		xhr.onload = function(){
			var parsedJSON = {};
			try{
				parsedJSON = JSON.parse(xhr.responseText);
			}
			catch(e){}
			suc(parsedJSON, xhr);
		};
		xhr.ontimeout = function(){
			error(xhr.responseText, xhr, "XDomainRequest timeout.");
		};
		xhr.onerror = function(){
			error(xhr.responseText, xhr, "XDomainRequest error.");
		};
		xhr.open("POST", options.url);
		xhr.send(JSON.stringify(data));
		return xhr;
	}

	xhr.onreadystatechange = _onReadyStateChange;
	if(type.toLowerCase() === "get"){
		for(o in data){
			if(Object.prototype.hasOwnProperty.call(data, o)){
				tempData += o + "=" + encodeURI(data[o]) + "&";
			}
		}
		// todo: use Array.prototype.join
		tempData = tempData ? tempData.slice(0, -1) : tempData;
		options.url += (~options.url.indexOf("?") ? "&" : "?")
			+ (tempData ? tempData + "&" : tempData)
			// 在需要读取缓存资源时不加时间戳
			+ (disableTimeStampInGet ? "" : "_v=" + new Date().getTime());
	}
	else if(isFileUpload){
		fileForm = new FormData();
		fileForm.append("file", data.file);

		xhr.open("POST", options.url);
		xhr.setRequestHeader("Authorization", data.auth);
		xhr.send(fileForm);
		return xhr;
	}
	else{
		data = JSON.stringify(data);
	}
	xhr.open(type, options.url);
	if(xhr.setRequestHeader){
		headers["Content-Type"] = headers["Content-Type"] || "application/json";

		for(key in headers){
			if(Object.prototype.hasOwnProperty.call(headers, key)){
				xhr.setRequestHeader(key, headers[key]);
			}
		}
	}

	xhr.send(data);
	return xhr;

	function _onReadyStateChange(){
		var json;

		if(xhr.readyState === 4){
			if(xhr.status === 200){
				if(dataType === "text"){
					suc(xhr.responseText, xhr);
					return;
				}
				if(dataType === "json"){
					try{
						json = JSON.parse(xhr.responseText);
						suc(json, xhr);
					}
					catch(e){}
					return;
				}
				suc(xhr.response || xhr.responseText, xhr);
				return;
			}

			if(dataType == "json"){
				try{
					json = JSON.parse(xhr.responseText);
					error(json, xhr, "error response.");
				}
				catch(e){
					error(xhr.responseText, xhr, "JSON parse error.");
				}
				return;
			}
			error(xhr.responseText, xhr, "error response.");
		}
		else if(xhr.readyState === 0){
			error(xhr.responseText, xhr, "unexpected server error.");
		}
	}
};
<commit_msg>url参数只转中文<commit_after>var EMPTYFN = function(){};
var _createStandardXHR = function(){
	try{
		return new window.XMLHttpRequest();
	}
	catch(e){
		return false;
	}
};
var _createActiveXHR = function(){
	try{
		return new window.ActiveXObject("Microsoft.XMLHTTP");
	}
	catch(e){
		return false;
	}
};

module.exports = function(options){
	var dataType = options.dataType || "text";
	var suc = options.success || EMPTYFN;
	var error = options.error || EMPTYFN;
	var useXDomainRequestInIE = options.useXDomainRequestInIE;
	var xhr = _createStandardXHR() || _createActiveXHR();
	var type = options.type || "GET";
	var data = options.data || {};
	var tempData = "";
	var headers = options.headers || {};
	var isFileUpload = options.isFileUpload;
	var disableTimeStampInGet = options.disableTimeStampInGet;
	var key;
	var fileForm;
	var o;

	if(useXDomainRequestInIE && window.XDomainRequest){
		xhr = new XDomainRequest();
		xhr.onload = function(){
			var parsedJSON = {};
			try{
				parsedJSON = JSON.parse(xhr.responseText);
			}
			catch(e){}
			suc(parsedJSON, xhr);
		};
		xhr.ontimeout = function(){
			error(xhr.responseText, xhr, "XDomainRequest timeout.");
		};
		xhr.onerror = function(){
			error(xhr.responseText, xhr, "XDomainRequest error.");
		};
		xhr.open("POST", options.url);
		xhr.send(JSON.stringify(data));
		return xhr;
	}

	xhr.onreadystatechange = _onReadyStateChange;
	if(type.toLowerCase() === "get"){
		for(o in data){
			if(Object.prototype.hasOwnProperty.call(data, o)){
				let reg = new RegExp(/[^\x00-\xff]+/);
				if(reg.test(data[o])){
					tempData += o + "=" + encodeURIComponent(data[o]) + "&";
				}
				else{
					tempData += o + "=" + data[o] + "&";
				}
			}
		}
		// todo: use Array.prototype.join
		tempData = tempData ? tempData.slice(0, -1) : tempData;
		options.url += (~options.url.indexOf("?") ? "&" : "?")
			+ (tempData ? tempData + "&" : tempData)
			// 在需要读取缓存资源时不加时间戳
			+ (disableTimeStampInGet ? "" : "_v=" + new Date().getTime());
	}
	else if(isFileUpload){
		fileForm = new FormData();
		fileForm.append("file", data.file);

		xhr.open("POST", options.url);
		xhr.setRequestHeader("Authorization", data.auth);
		xhr.send(fileForm);
		return xhr;
	}
	else{
		data = JSON.stringify(data);
	}
	xhr.open(type, options.url);
	if(xhr.setRequestHeader){
		headers["Content-Type"] = headers["Content-Type"] || "application/json";

		for(key in headers){
			if(Object.prototype.hasOwnProperty.call(headers, key)){
				xhr.setRequestHeader(key, headers[key]);
			}
		}
	}

	xhr.send(data);
	return xhr;

	function _onReadyStateChange(){
		var json;

		if(xhr.readyState === 4){
			if(xhr.status === 200){
				if(dataType === "text"){
					suc(xhr.responseText, xhr);
					return;
				}
				if(dataType === "json"){
					try{
						json = JSON.parse(xhr.responseText);
						suc(json, xhr);
					}
					catch(e){}
					return;
				}
				suc(xhr.response || xhr.responseText, xhr);
				return;
			}

			if(dataType == "json"){
				try{
					json = JSON.parse(xhr.responseText);
					error(json, xhr, "error response.");
				}
				catch(e){
					error(xhr.responseText, xhr, "JSON parse error.");
				}
				return;
			}
			error(xhr.responseText, xhr, "error response.");
		}
		else if(xhr.readyState === 0){
			error(xhr.responseText, xhr, "unexpected server error.");
		}
	}
};
<|endoftext|>


<commit_before>/* ========================================================================
 * ZUI: contextmenu.js
 * http://zui.sexy
 * ========================================================================
 * Copyright (c) 2017-2018 cnezsoft.com; Licensed MIT
 * ======================================================================== */

(function($, undefined) {
    'use strict';

    var NAME = 'zui.contextmenu'; // model name

    var DEFAULTS = {
        // onShow: null,
        // onShown: null,
        // onHide: null,
        // onHidden: null,
        // itemCreator: null,
        // x: 0,
        // y: 0,
        // onClickItem: null,
        duration: 200,
    };

    var isShowingMenu = false;
    var ContextMenu = {};
    var targetId = 'zui-contextmenu-' + $.zui.uuid();
    var mouseX = 0, mouseY = 0;
    var listenMouseMove = function() {
        $(document).off('mousemove.' + NAME).on('mousemove.' + NAME, function(e) {
            mouseX = e.clientX;
            mouseY = e.clientY;
        });
        return ContextMenu;
    };
    var stopListenMouse = function() {
        $(document).off('mousemove.' + NAME);
        return ContextMenu;
    };
    var createMenuItem = function(item, index) {
        if (typeof item === 'string') {
            if (item === 'seperator' || item === 'divider' || item === '-' || item === '|') {
                item = {type: 'seperator'};
            } else {
                item = {label: item, id: index};
            }
        }
        if (item.type === 'seperator' || item.type === 'divider') {
            return $('

');
        }
        var $a = $('').attr({
            href: item.url || '###',
            'class': item.className,
            style: item.style
        }).toggleClass('disabled', item.disabled === true).data('item', item);
        if (item.html) {
            $a.html(item.html);
        } else {
            $a.text(item.label || item.text);
        }
        if (item.onClick) {
            $a.on('click', item.onClick);
        }
        return $('
').append($a);
    };

    var animationTimer = null;
    var hideContextMenu = function(id, callback) {
        if (typeof id === 'function') {
            callback = id;
            id = null;
        }

        if (animationTimer) {
            clearTimeout(animationTimer);
            animationTimer = null;
        }

        var $target = $('#' + targetId);
        if ($target.length) {
            var options = $target.data('options');
            if (!id || options.id === id) {
                var afterHide = function() {
                    $target.hide();
                    options.onHidden && options.onHidden();
                    callback && callback();
                };
                options.onHide && options.onHide();
                var animation = options.animation;
                $target.removeClass('in');
                if (animation) {
                    animationTimer = setTimeout(afterHide, options.duration);
                } else {
                    afterHide();
                }
            }
        }
        return ContextMenu;
    };

    var showContextMenu = function(items, options, callback) {
        if ($.isPlainObject(items)) {
            callback = options;
            options = items;
            items = options.items;
        }

        isShowingMenu = true;
        // hideContextMenu();

        options = $.extend({}, DEFAULTS, options);
        var x = options.x;
        var y = options.y;
        if (x === undefined) x = (options.event || options).clientX;
        if (x === undefined) x = mouseX;
        if (y === undefined) y = (options.event || options).clientY;
        if (y === undefined) y = mouseY;

        var $target = $('#' + targetId);
        if (!$target.length) {
            $target = $('

').appendTo('body');
        }
        var $menu = $target.find('.contextmenu-menu').off('click.' + NAME).on('click.' + NAME, 'a', function(e) {
            var $item = $(this);
            var clickResult = options.onClickItem && options.onClickItem($item.data('item'), $item, e);
            if (clickResult !== false) {
                hideContextMenu();
            }
        }).empty();;
        $target.hide().attr('class', 'contextmenu');
        var itemCreator = options.itemCreator || createMenuItem;
        var itemsType = typeof items;
        if (itemsType === 'string') {
            items = items.split(',');
        } else if (itemsType === 'function') {
            items = items(options);
        }
        $.each(items, function(index, item) {
            $menu.append(itemCreator(item, index, options));
        });

        // Show menu
        var animation = options.animation;
        var duration = options.duration;
        if (animation === true) options.animation = animation = 'fade';
        if (animationTimer) {
            clearTimeout(animationTimer);
            animationTimer = null;
        }
        var afterShow = function() {
            $target.addClass('in');
            options.onShown && options.onShown();
            callback && callback();
        };
        options.onShow && options.onShow();
        $target.data('options', {
            animation: animation,
            onHide: options.onHide,
            onHidden: options.onHidden,
            id: options.id,
            duration: duration
        });

        var $w = $(window);
        x = Math.max(0, Math.min(x, $w.width() - $menu.outerWidth()));
        y = Math.max(0, Math.min(y, $w.height() - $menu.outerHeight()));
        $target.css({
            left: x,
            top: y
        });

        if (animation) {
            $target.addClass('open').addClass(animation).show();
            animationTimer = setTimeout(function() {
                afterShow();
                isShowingMenu = false;
            }, options.duration);
        } else {
            $target.addClass('open').show();
            afterShow();
            animationTimer = setTimeout(function() {
                isShowingMenu = false;
            }, 200);
        }
        return ContextMenu;
    };

    $(document).on('click', function(e) {
        if (!isShowingMenu && !$(e.target).closest('.contextmenu').length) {
            hideContextMenu();
        }
    });

    $.extend(ContextMenu, {
        NAME: NAME,
        DEFAULTS: DEFAULTS,
        show: showContextMenu,
        hide: hideContextMenu,
        listenMouse: listenMouseMove
    });
    $.zui({ContextMenu: ContextMenu});

    // The contextmenu model class
    var ContextListener = function(element, options) {
        var that = this;
        that.name = NAME;
        that.$ = $(element);

        options = that.options = $.extend({trigger: 'contextmenu'}, ContextMenu.DEFAULTS, this.$.data(), options);

        var trigger = options.trigger;

        that.id = $.zui.uuid();
        var eventHandler = function(e) {
            if (e.type === 'mousedown' && e.button !== 2) {
                return;
            }
            var config = {
                x: e.clientX,
                y: e.clientY,
                event: e
            };
            if (options.itemsCreator) {
                config.items = options.itemsCreator.call(this, e);
            }
            that.show(config);
            e.preventDefault();
            e.returnValue = false; // 解决IE8右键弹出
            return false;
        };
        var eventName = trigger + '.' + NAME;
        if (options.selector) {
            that.$.on(eventName, options.selector, eventHandler);
        } else {
            that.$.on(eventName, eventHandler);
        }
    };

    ContextListener.prototype.destory = function () {
        that.$.off('.' + NAME);
    };

    ContextListener.prototype.hide = function (callback) {
        ContextMenu.hide(this.id, callback);
    };

    ContextListener.prototype.show = function (options, callback) {
        options = $.extend({}, this.options, options);
        ContextMenu.show(options, callback);
    };

    // Extense jquery element
    $.fn.contextmenu = function(option) {
        return this.each(function() {
            var $this = $(this);
            var data = $this.data(NAME);
            var options = typeof option == 'object' && option;

            if(!data) $this.data(NAME, (data = new ContextListener(this, options)));

            if(typeof option == 'string') data[option]();
        });
    };
    $.fn.contextmenu.Constructor = ContextListener;
}(jQuery, undefined));

<commit_msg> * fix diabled property not work.<commit_after>/* ========================================================================
 * ZUI: contextmenu.js
 * http://zui.sexy
 * ========================================================================
 * Copyright (c) 2017-2018 cnezsoft.com; Licensed MIT
 * ======================================================================== */

(function($, undefined) {
    'use strict';

    var NAME = 'zui.contextmenu'; // model name

    var DEFAULTS = {
        // onShow: null,
        // onShown: null,
        // onHide: null,
        // onHidden: null,
        // itemCreator: null,
        // x: 0,
        // y: 0,
        // onClickItem: null,
        duration: 200,
    };

    var isShowingMenu = false;
    var ContextMenu = {};
    var targetId = 'zui-contextmenu-' + $.zui.uuid();
    var mouseX = 0, mouseY = 0;
    var listenMouseMove = function() {
        $(document).off('mousemove.' + NAME).on('mousemove.' + NAME, function(e) {
            mouseX = e.clientX;
            mouseY = e.clientY;
        });
        return ContextMenu;
    };
    var stopListenMouse = function() {
        $(document).off('mousemove.' + NAME);
        return ContextMenu;
    };
    var createMenuItem = function(item, index) {
        if (typeof item === 'string') {
            if (item === 'seperator' || item === 'divider' || item === '-' || item === '|') {
                item = {type: 'seperator'};
            } else {
                item = {label: item, id: index};
            }
        }
        if (item.type === 'seperator' || item.type === 'divider') {
            return $('

');
        }
        var $a = $('').attr({
            href: item.url || '###',
            'class': item.className,
            style: item.style
        }).data('item', item);
        if (item.html) {
            $a.html(item.html);
        } else {
            $a.text(item.label || item.text);
        }
        if (item.onClick) {
            $a.on('click', item.onClick);
        }
        return $('
').toggleClass('disabled', item.disabled === true).append($a);
    };

    var animationTimer = null;
    var hideContextMenu = function(id, callback) {
        if (typeof id === 'function') {
            callback = id;
            id = null;
        }

        if (animationTimer) {
            clearTimeout(animationTimer);
            animationTimer = null;
        }

        var $target = $('#' + targetId);
        if ($target.length) {
            var options = $target.data('options');
            if (!id || options.id === id) {
                var afterHide = function() {
                    $target.hide();
                    options.onHidden && options.onHidden();
                    callback && callback();
                };
                options.onHide && options.onHide();
                var animation = options.animation;
                $target.removeClass('in');
                if (animation) {
                    animationTimer = setTimeout(afterHide, options.duration);
                } else {
                    afterHide();
                }
            }
        }
        return ContextMenu;
    };

    var showContextMenu = function(items, options, callback) {
        if ($.isPlainObject(items)) {
            callback = options;
            options = items;
            items = options.items;
        }

        isShowingMenu = true;
        // hideContextMenu();

        options = $.extend({}, DEFAULTS, options);
        var x = options.x;
        var y = options.y;
        if (x === undefined) x = (options.event || options).clientX;
        if (x === undefined) x = mouseX;
        if (y === undefined) y = (options.event || options).clientY;
        if (y === undefined) y = mouseY;

        var $target = $('#' + targetId);
        if (!$target.length) {
            $target = $('

').appendTo('body');
        }
        var $menu = $target.find('.contextmenu-menu').off('click.' + NAME).on('click.' + NAME, 'a', function(e) {
            var $item = $(this);
            var clickResult = options.onClickItem && options.onClickItem($item.data('item'), $item, e);
            if (clickResult !== false) {
                hideContextMenu();
            }
        }).empty();;
        $target.hide().attr('class', 'contextmenu');
        var itemCreator = options.itemCreator || createMenuItem;
        var itemsType = typeof items;
        if (itemsType === 'string') {
            items = items.split(',');
        } else if (itemsType === 'function') {
            items = items(options);
        }
        $.each(items, function(index, item) {
            $menu.append(itemCreator(item, index, options));
        });

        // Show menu
        var animation = options.animation;
        var duration = options.duration;
        if (animation === true) options.animation = animation = 'fade';
        if (animationTimer) {
            clearTimeout(animationTimer);
            animationTimer = null;
        }
        var afterShow = function() {
            $target.addClass('in');
            options.onShown && options.onShown();
            callback && callback();
        };
        options.onShow && options.onShow();
        $target.data('options', {
            animation: animation,
            onHide: options.onHide,
            onHidden: options.onHidden,
            id: options.id,
            duration: duration
        });

        var $w = $(window);
        x = Math.max(0, Math.min(x, $w.width() - $menu.outerWidth()));
        y = Math.max(0, Math.min(y, $w.height() - $menu.outerHeight()));
        $target.css({
            left: x,
            top: y
        });

        if (animation) {
            $target.addClass('open').addClass(animation).show();
            animationTimer = setTimeout(function() {
                afterShow();
                isShowingMenu = false;
            }, options.duration);
        } else {
            $target.addClass('open').show();
            afterShow();
            animationTimer = setTimeout(function() {
                isShowingMenu = false;
            }, 200);
        }
        return ContextMenu;
    };

    $(document).on('click', function(e) {
        if (!isShowingMenu && !$(e.target).closest('.contextmenu').length) {
            hideContextMenu();
        }
    });

    $.extend(ContextMenu, {
        NAME: NAME,
        DEFAULTS: DEFAULTS,
        show: showContextMenu,
        hide: hideContextMenu,
        listenMouse: listenMouseMove
    });
    $.zui({ContextMenu: ContextMenu});

    // The contextmenu model class
    var ContextListener = function(element, options) {
        var that = this;
        that.name = NAME;
        that.$ = $(element);

        options = that.options = $.extend({trigger: 'contextmenu'}, ContextMenu.DEFAULTS, this.$.data(), options);

        var trigger = options.trigger;

        that.id = $.zui.uuid();
        var eventHandler = function(e) {
            if (e.type === 'mousedown' && e.button !== 2) {
                return;
            }
            var config = {
                x: e.clientX,
                y: e.clientY,
                event: e
            };
            if (options.itemsCreator) {
                config.items = options.itemsCreator.call(this, e);
            }
            that.show(config);
            e.preventDefault();
            e.returnValue = false; // 解决IE8右键弹出
            return false;
        };
        var eventName = trigger + '.' + NAME;
        if (options.selector) {
            that.$.on(eventName, options.selector, eventHandler);
        } else {
            that.$.on(eventName, eventHandler);
        }
    };

    ContextListener.prototype.destory = function () {
        that.$.off('.' + NAME);
    };

    ContextListener.prototype.hide = function (callback) {
        ContextMenu.hide(this.id, callback);
    };

    ContextListener.prototype.show = function (options, callback) {
        options = $.extend({}, this.options, options);
        ContextMenu.show(options, callback);
    };

    // Extense jquery element
    $.fn.contextmenu = function(option) {
        return this.each(function() {
            var $this = $(this);
            var data = $this.data(NAME);
            var options = typeof option == 'object' && option;

            if(!data) $this.data(NAME, (data = new ContextListener(this, options)));

            if(typeof option == 'string') data[option]();
        });
    };
    $.fn.contextmenu.Constructor = ContextListener;
}(jQuery, undefined));

<|endoftext|>


<commit_before>import os from 'os';
import fs from 'fs';
import path from 'path';
import levenshtein from 'fast-levenshtein';
import { ipcRenderer } from 'electron';
import SearchService from './js/SearchService';
import InputValidationService from './js/InputValidationService';
import ExecutionService from './js/ExecutionService';
import InputHistory from './js/InputHistory';
import Helper from './js/Helper';

let searchService = new SearchService();
let inputValidationService = new InputValidationService();
let executionService = new ExecutionService();
let inputHistory = new InputHistory();
let helper = new Helper();

let selector = {
    content: '.content',
    input: 'input',
    value: '.result-value',
    path: '.result-path',
    inputTypeIcon: '.input-type-icon',
    theme: '#theme'
};

let shortCutFileExtension = '.lnk';
let startMenuFolders = [
    os.homedir() + '\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu',
    'C:\\ProgramData\\Microsoft\\Windows\\Start Menu'
];

let fileWatcher = searchService.initializeFileWatcher(startMenuFolders);

let shortCutFiles = searchService.getFilesFromDirectoriesRecursively(startMenuFolders, shortCutFileExtension);

let searchResult = [];
let searchResultIndex = 0;
let maxResultItems = 10;

let configFilePath = './config.json';
let defaultConfig = {
    theme: 'win10'
}

function InitializeElectronizrTheme() {
    if (fs.existsSync(configFilePath)) {
        fs.readFile(configFilePath, (err, data) => {
            if (err) throw err;
            data = JSON.parse(data);
            ChangeTheme(data.theme);
        });
    }
    else {
        fs.writeFileSync(configFilePath, JSON.stringify(defaultConfig));
        ChangeTheme(defaultConfig.theme);
    }
}

function DisplaySearchResult() {
    if (searchResult === undefined || searchResult.length === 0)
        return;

    if (searchResultIndex < 0)
        searchResultIndex = searchResult.length - 1;
    if (searchResultIndex > searchResult.length - 1)
        searchResultIndex = 0;

    $(selector.value).empty();
    $(selector.value).children('p').removeClass('active');

    for (let i = 0; i < searchResult.length; i++) {
        $(selector.value).append(`<p id="${i}">${searchResult[i].Name}</p>`);
        $(selector.value).find(`#${searchResultIndex}`).addClass('active');
        $(selector.path).html(searchResult[searchResultIndex].Path);
    }

    $(selector.path).html(searchResult[searchResultIndex].Path);
    ResizeWindow();
}

function GetSearchResult(value) {
    if (helper.StringIsUndefinedEmptyOrWhitespaces(value)) return;

    let allShortCuts = shortCutFiles;
    let apps = [];

    for (let shortcut of allShortCuts) {
        let displayName = path.basename(shortcut).replace(shortCutFileExtension, '');
        let fileName = path.basename(shortcut).toLowerCase().replace(shortCutFileExtension, '');
        let weight = GetWeight(fileName, value.toLowerCase());

        if (!StringContainsSubstring(fileName, value)) continue;
        if (SearchResultListContainsValue(apps, displayName)) continue;

        apps.push({
            Name: displayName,
            Path: `${shortcut}`,
            Weight: weight
        });
    }

    let sortedResult = apps.sort((a, b) => {
        if (a.Weight > b.Weight) return 1;
        if (a.Weight < b.Weight) return -1;
        return 0;
    });

    if (sortedResult.length > maxResultItems) {
        let newResult = [];
        for (let i = 0; i < maxResultItems; i++) {
            if (i == maxResultItems)
                break;
            newResult.push(sortedResult[i]);
        }
        return newResult;
    }

    return sortedResult;
}

function HideMainWindow() {
    ResetGui();
    ipcRenderer.sendSync('hide-main-window');
}

function ResetGui() {
    $(selector.input).val('');
    $(selector.value).empty();
    $(selector.path).empty();
    $(selector.inputTypeIcon).attr('class', 'fa input-type-icon');
    ResizeWindow();
}

function GetWeight(stringToSearch, value) {
    let result = [];
    let stringToSearchWords = SplitStringToArray(stringToSearch);
    let valueWords = SplitStringToArray(value);

    for (let word of stringToSearchWords)
        for (let value of valueWords)
            result.push(levenshtein.get(word, value));

    return GetAvg(result);
}

function GetAvg(array) {
    let sum = 0;

    for (let value of array)
        sum = sum + value;

    return sum / array.length;
}

function SplitStringToArray(string) {
    return string.split(/\s+/);
}

function StringContainsSubstring(stringToSearch, substring) {
    let wordsOfSubstring = SplitStringToArray(substring.toLowerCase());
    stringToSearch = stringToSearch.split(' ').join('').toLowerCase();

    for (let word of wordsOfSubstring)
        if (stringToSearch.indexOf(word) === -1)
            return false;

    return true;
}

function SearchResultListContainsValue(list, value) {
    for (let item of list) {
        if (item.Name === value)
            return true;
    }
    return false;
}

function UpdateAppList() {
    shortCutFiles = searchService.getFilesFromDirectoriesRecursively(startMenuFolders, shortCutFileExtension);
}

function ResizeWindow() {
    let height = $(selector.content).height();
    ipcRenderer.sendSync('resize-window', height);
}

function ChangeTheme(name) {
    let currentTheme = JSON.parse(fs.readFileSync(configFilePath)).theme;

    if (currentTheme !== name) {
        fs.writeFileSync(configFilePath, JSON.stringify({ theme: name }));
    }

    let stylePath = `./css/${name}-theme.css`;
    $(selector.theme).attr('href', stylePath);
}

function SetInputTypeIcon(input) {
    let icon = $(selector.inputTypeIcon);

    icon.attr('class', 'fa input-type-icon');

    if (inputValidationService.IsValidHttpOrHttpsUrl(input)) {
        icon.addClass('fa-globe');
    }

    if (inputValidationService.IsValidGoogleQuery(input)) {
        icon.addClass('fa-google');
    }

    if (inputValidationService.IsValidWikipediaQuery(input)) {
        icon.addClass('fa-wikipedia-w');
    }

    if (inputValidationService.IsShellCommand(input)) {
        icon.addClass('fa-terminal');
    }

    if (inputValidationService.IsValidWindowsPath(input)) {
        icon.addClass('fa-folder-o');
    }
}

function ValidateInputAndExecute(input) {
    if (inputValidationService.IsElectronizrCommand(input)) {
        executionService.HandleElectronizrCommand(input);
        return;
    }

    if (inputValidationService.IsValidGoogleQuery(input)) {
        executionService.HandleGoogleQuery(input)
        return;
    }

    if (inputValidationService.IsValidWikipediaQuery(input)) {
        executionService.HandleWikipediaQuery(input)
        return;
    }

    if (inputValidationService.IsValidHttpOrHttpsUrl(input)) {
        executionService.HandleUrlInput(input);
        return;
    }

    if (inputValidationService.IsValidWindowsPath(input)) {
        executionService.HandleWindowsPathInput(input);
        return;
    }

    if (inputValidationService.IsShellCommand(input)) {
        executionService.HandleShellCommand(input);
        return;
    }

    if (searchResult.length > 0) {
        let path = $(selector.path).html();
        executionService.HandleStartProgram(path);
        ResetGui();
        ipcRenderer.sendSync('hide-main-window');
    }
}

function OpenFileLocation(filePath) {
    var folder = path.dirname(filePath);
    console.log(folder);
    executionService.HandleWindowsPathInput(folder);
}

fileWatcher.on('change', (file, stat) => {
    UpdateAppList();
});

$(document).ready(InitializeElectronizrTheme());

// Input Text Change
$(selector.input).bind('input propertychange', function () {
    let input = $(this).val();
    searchResultIndex = 0;

    if (helper.StringIsUndefinedEmptyOrWhitespaces(input)) {
        ResetGui();
        return;
    }

    SetInputTypeIcon(input);
    searchResult = GetSearchResult(input);

    if (searchResult === undefined || searchResult.length === 0) {
        $(selector.value).html('');
        $(selector.path).html('');
        return;
    }
    else
        DisplaySearchResult();
});

// Prevent tab and arrow key from modifing input cursor
$(window).on('keydown', e => {
    if (e.keyCode === 27) {
        ipcRenderer.send('hide-main-window');
    }
    if (e.keyCode === 40 || e.keyCode === 9) {
        e.preventDefault();
    }
    if (e.keyCode == 38) {
        e.preventDefault();
    }
});

// Keyboard Events
$(selector.input).keyup(e => {
    // When user hits enter on keyboard
    if (e.keyCode === 13) {
        let input = $(selector.input).val()
        inputHistory.addItem(input);
        ValidateInputAndExecute(input);
    }

    if (e.ctrlKey && e.keyCode === 79) {
        if (searchResult.length > 0)
            OpenFileLocation($(selector.path).html());
    }

    else if (e.keyCode === 38) {
        $(selector.input).val(inputHistory.getPrevious());
        $(selector.input).trigger('propertychange');
    }
    else if (e.keyCode === 40) {
        if(inputHistory.index < inputHistory.history.length) {
            $(selector.input).val(inputHistory.getNext());
            $(selector.input).trigger('propertychange');
        }
    }

    // Select Next with ArrowKeyDown or Tab
    else if (!e.shiftKey && e.keyCode === 9) {
        searchResultIndex++;
        DisplaySearchResult();
    }
    // Select Next with ArrowKeyUp or Shift+Tab
    else if (e.shiftKey && e.keyCode === 9) {
        searchResultIndex--;
        DisplaySearchResult();
    }
});<commit_msg>Added Validation for empty string or whitespaces<commit_after>import os from 'os';
import fs from 'fs';
import path from 'path';
import levenshtein from 'fast-levenshtein';
import { ipcRenderer } from 'electron';
import SearchService from './js/SearchService';
import InputValidationService from './js/InputValidationService';
import ExecutionService from './js/ExecutionService';
import InputHistory from './js/InputHistory';
import Helper from './js/Helper';

let searchService = new SearchService();
let inputValidationService = new InputValidationService();
let executionService = new ExecutionService();
let inputHistory = new InputHistory();
let helper = new Helper();

let selector = {
    content: '.content',
    input: 'input',
    value: '.result-value',
    path: '.result-path',
    inputTypeIcon: '.input-type-icon',
    theme: '#theme'
};

let shortCutFileExtension = '.lnk';
let startMenuFolders = [
    os.homedir() + '\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu',
    'C:\\ProgramData\\Microsoft\\Windows\\Start Menu'
];

let fileWatcher = searchService.initializeFileWatcher(startMenuFolders);

let shortCutFiles = searchService.getFilesFromDirectoriesRecursively(startMenuFolders, shortCutFileExtension);

let searchResult = [];
let searchResultIndex = 0;
let maxResultItems = 10;

let configFilePath = './config.json';
let defaultConfig = {
    theme: 'win10'
}

function InitializeElectronizrTheme() {
    if (fs.existsSync(configFilePath)) {
        fs.readFile(configFilePath, (err, data) => {
            if (err) throw err;
            data = JSON.parse(data);
            ChangeTheme(data.theme);
        });
    }
    else {
        fs.writeFileSync(configFilePath, JSON.stringify(defaultConfig));
        ChangeTheme(defaultConfig.theme);
    }
}

function DisplaySearchResult() {
    if (searchResult === undefined || searchResult.length === 0)
        return;

    if (searchResultIndex < 0)
        searchResultIndex = searchResult.length - 1;
    if (searchResultIndex > searchResult.length - 1)
        searchResultIndex = 0;

    $(selector.value).empty();
    $(selector.value).children('p').removeClass('active');

    for (let i = 0; i < searchResult.length; i++) {
        $(selector.value).append(`<p id="${i}">${searchResult[i].Name}</p>`);
        $(selector.value).find(`#${searchResultIndex}`).addClass('active');
        $(selector.path).html(searchResult[searchResultIndex].Path);
    }

    $(selector.path).html(searchResult[searchResultIndex].Path);
    ResizeWindow();
}

function GetSearchResult(value) {
    if (helper.StringIsUndefinedEmptyOrWhitespaces(value)) return;

    let allShortCuts = shortCutFiles;
    let apps = [];

    for (let shortcut of allShortCuts) {
        let displayName = path.basename(shortcut).replace(shortCutFileExtension, '');
        let fileName = path.basename(shortcut).toLowerCase().replace(shortCutFileExtension, '');
        let weight = GetWeight(fileName, value.toLowerCase());

        if (!StringContainsSubstring(fileName, value)) continue;
        if (SearchResultListContainsValue(apps, displayName)) continue;

        apps.push({
            Name: displayName,
            Path: `${shortcut}`,
            Weight: weight
        });
    }

    let sortedResult = apps.sort((a, b) => {
        if (a.Weight > b.Weight) return 1;
        if (a.Weight < b.Weight) return -1;
        return 0;
    });

    if (sortedResult.length > maxResultItems) {
        let newResult = [];
        for (let i = 0; i < maxResultItems; i++) {
            if (i == maxResultItems)
                break;
            newResult.push(sortedResult[i]);
        }
        return newResult;
    }

    return sortedResult;
}

function HideMainWindow() {
    ResetGui();
    ipcRenderer.sendSync('hide-main-window');
}

function ResetGui() {
    $(selector.input).val('');
    $(selector.value).empty();
    $(selector.path).empty();
    $(selector.inputTypeIcon).attr('class', 'fa input-type-icon');
    ResizeWindow();
}

function GetWeight(stringToSearch, value) {
    let result = [];
    let stringToSearchWords = SplitStringToArray(stringToSearch);
    let valueWords = SplitStringToArray(value);

    for (let word of stringToSearchWords)
        for (let value of valueWords)
            result.push(levenshtein.get(word, value));

    return GetAvg(result);
}

function GetAvg(array) {
    let sum = 0;

    for (let value of array)
        sum = sum + value;

    return sum / array.length;
}

function SplitStringToArray(string) {
    return string.split(/\s+/);
}

function StringContainsSubstring(stringToSearch, substring) {
    let wordsOfSubstring = SplitStringToArray(substring.toLowerCase());
    stringToSearch = stringToSearch.split(' ').join('').toLowerCase();

    for (let word of wordsOfSubstring)
        if (stringToSearch.indexOf(word) === -1)
            return false;

    return true;
}

function SearchResultListContainsValue(list, value) {
    for (let item of list) {
        if (item.Name === value)
            return true;
    }
    return false;
}

function UpdateAppList() {
    shortCutFiles = searchService.getFilesFromDirectoriesRecursively(startMenuFolders, shortCutFileExtension);
}

function ResizeWindow() {
    let height = $(selector.content).height();
    ipcRenderer.sendSync('resize-window', height);
}

function ChangeTheme(name) {
    let currentTheme = JSON.parse(fs.readFileSync(configFilePath)).theme;

    if (currentTheme !== name) {
        fs.writeFileSync(configFilePath, JSON.stringify({ theme: name }));
    }

    let stylePath = `./css/${name}-theme.css`;
    $(selector.theme).attr('href', stylePath);
}

function SetInputTypeIcon(input) {
    let icon = $(selector.inputTypeIcon);

    icon.attr('class', 'fa input-type-icon');

    if (inputValidationService.IsValidHttpOrHttpsUrl(input)) {
        icon.addClass('fa-globe');
    }

    if (inputValidationService.IsValidGoogleQuery(input)) {
        icon.addClass('fa-google');
    }

    if (inputValidationService.IsValidWikipediaQuery(input)) {
        icon.addClass('fa-wikipedia-w');
    }

    if (inputValidationService.IsShellCommand(input)) {
        icon.addClass('fa-terminal');
    }

    if (inputValidationService.IsValidWindowsPath(input)) {
        icon.addClass('fa-folder-o');
    }
}

function ValidateInputAndExecute(input) {
    if(helper.StringIsUndefinedEmptyOrWhitespaces(input))
        return;

    if (inputValidationService.IsElectronizrCommand(input)) {
        executionService.HandleElectronizrCommand(input);
        return;
    }

    if (inputValidationService.IsValidGoogleQuery(input)) {
        executionService.HandleGoogleQuery(input)
        return;
    }

    if (inputValidationService.IsValidWikipediaQuery(input)) {
        executionService.HandleWikipediaQuery(input)
        return;
    }

    if (inputValidationService.IsValidHttpOrHttpsUrl(input)) {
        executionService.HandleUrlInput(input);
        return;
    }

    if (inputValidationService.IsValidWindowsPath(input)) {
        executionService.HandleWindowsPathInput(input);
        return;
    }

    if (inputValidationService.IsShellCommand(input)) {
        executionService.HandleShellCommand(input);
        return;
    }

    if (searchResult.length > 0) {
        let path = $(selector.path).html();
        executionService.HandleStartProgram(path);
        ResetGui();
        ipcRenderer.sendSync('hide-main-window');
    }
}

function OpenFileLocation(filePath) {
    var folder = path.dirname(filePath);
    console.log(folder);
    executionService.HandleWindowsPathInput(folder);
}

fileWatcher.on('change', (file, stat) => {
    UpdateAppList();
});

$(document).ready(InitializeElectronizrTheme());

// Input Text Change
$(selector.input).bind('input propertychange', function () {
    let input = $(this).val();
    searchResultIndex = 0;

    if (helper.StringIsUndefinedEmptyOrWhitespaces(input)) {
        ResetGui();
        return;
    }

    SetInputTypeIcon(input);
    searchResult = GetSearchResult(input);

    if (searchResult === undefined || searchResult.length === 0) {
        $(selector.value).html('');
        $(selector.path).html('');
        return;
    }
    else
        DisplaySearchResult();
});

// Prevent tab and arrow key from modifing input cursor
$(window).on('keydown', e => {
    if (e.keyCode === 27) {
        ipcRenderer.send('hide-main-window');
    }
    if (e.keyCode === 40 || e.keyCode === 9) {
        e.preventDefault();
    }
    if (e.keyCode == 38) {
        e.preventDefault();
    }
});

// Keyboard Events
$(selector.input).keyup(e => {
    // When user hits enter on keyboard
    if (e.keyCode === 13) {
        let input = $(selector.input).val();

        if(!helper.StringIsUndefinedEmptyOrWhitespaces(input))
            inputHistory.addItem(input);

        ValidateInputAndExecute(input);
    }

    if (e.ctrlKey && e.keyCode === 79) {
        if (searchResult.length > 0)
            OpenFileLocation($(selector.path).html());
    }

    else if (e.keyCode === 38) {
        $(selector.input).val(inputHistory.getPrevious());
        $(selector.input).trigger('propertychange');
    }
    else if (e.keyCode === 40) {
        if(inputHistory.index < inputHistory.history.length) {
            $(selector.input).val(inputHistory.getNext());
            $(selector.input).trigger('propertychange');
        }
    }

    // Select Next with ArrowKeyDown or Tab
    else if (!e.shiftKey && e.keyCode === 9) {
        searchResultIndex++;
        DisplaySearchResult();
    }
    // Select Next with ArrowKeyUp or Shift+Tab
    else if (e.shiftKey && e.keyCode === 9) {
        searchResultIndex--;
        DisplaySearchResult();
    }
});<|endoftext|>


<commit_before>export default [
  {
    test: /^(text|application)\//,
    loader: (type, seed) => textLoader(type, seed),
    composer: (file) => Promise.resolve(file.text)
  },
  {
    test: /^(image|audio|video)\//,
    loader: (type, seed) => blobLoader(type, seed),
    composer: (file) => blobToBase64(file.blob)
  },
  {
    // The Sentinel (will throw error)
    test: /./,
    loader: null,
    composer: null
  }
];

export const defaultValue = {
  key: null,
  name: '',
  type: '',
  isText: true,
  text: '',
  blob: null,
  blobURL: null,
  options: {
    isEntryPoint: false,
    isReadOnly: false,
  },
  author: {
    name: '',
    url: '',
  },
};

const getUniqueId = (i => () => ++i)(0);

export const merger = (...args) => {
  const parts = [{}].concat(defaultValue).concat(args);
  const file = Object.assign.apply(null, parts); // merge objects
  file.key = getUniqueId(); // unique key (Number)
  return file;
};

export const textLoader = (type, seed) =>
  new Promise((resolve, reject) => {
    if (sanitize(seed, reject)) return;

    // when Blob => text, it must be asynchronous
    new Promise((resolve, reject) => {
      if (typeof seed.text === 'string') {
        resolve(seed.text);
        return;
      }
      const reader = new FileReader();
      reader.onload = (event) => {
        resolve(event.target.result);
      };
      reader.readAsText(seed.blob);
    })
    .then(text => resolve(merger({
      name: seed.name,
      type,
      isText: true,
      text,
      options: Object.assign({}, defaultValue.options, seed.options)
    })));
  });

export const blobLoader = (type, seed) =>
  new Promise((resolve, reject) => {
    if (sanitize(seed, reject)) return;

    const blob = seed.blob || (base64 => {
      var bin = atob(base64);
      var byteArray = new Uint8Array(bin.length);
      for (var i = bin.length - 1; i >= 0; i--) {
        byteArray[i] = bin.charCodeAt(i);
      }
      return new Blob([byteArray.buffer], { type });
    })(seed.text);

    resolve(merger({
      name: seed.name,
      type,
      isText: false,
      blob,
      blobURL: URL.createObjectURL(seed.blob),
      options: Object.assign({}, defaultValue.options, seed.options)
    }));
  });

const blobToBase64 = (blob) =>
  new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = (event) => {
      const { result } = event.target;
      resolve(result.substr(result.indexOf(',') + 1));
    };
    reader.readAsDataURL(blob);
  });

const sanitize = (seed, reject) => {
  if (typeof seed.text !== 'string' && !seed.blob) {
    reject(new Error(`Needed text or blob, but given: ${JSON.stringify(seed)}`));
    return true;
  }
  return false;
};
<commit_msg>bug fix<commit_after>export default [
  {
    test: /^(text|application)\//,
    loader: (type, seed) => textLoader(type, seed),
    composer: (file) => Promise.resolve(file.text)
  },
  {
    test: /^(image|audio|video)\//,
    loader: (type, seed) => blobLoader(type, seed),
    composer: (file) => blobToBase64(file.blob)
  },
  {
    // The Sentinel (will throw error)
    test: /./,
    loader: null,
    composer: null
  }
];

export const defaultValue = {
  key: null,
  name: '',
  type: '',
  isText: true,
  text: '',
  blob: null,
  blobURL: null,
  options: {
    isEntryPoint: false,
    isReadOnly: false,
  },
  author: {
    name: '',
    url: '',
  },
};

const getUniqueId = (i => () => ++i)(0);

export const merger = (...args) => {
  const parts = [{}].concat(defaultValue).concat(args);
  const file = Object.assign.apply(null, parts); // merge objects
  file.key = getUniqueId(); // unique key (Number)
  return file;
};

export const textLoader = (type, seed) =>
  new Promise((resolve, reject) => {
    if (sanitize(seed, reject)) return;

    // when Blob => text, it must be asynchronous
    new Promise((resolve, reject) => {
      if (typeof seed.text === 'string') {
        resolve(seed.text);
        return;
      }
      const reader = new FileReader();
      reader.onload = (event) => {
        resolve(event.target.result);
      };
      reader.readAsText(seed.blob);
    })
    .then(text => resolve(merger({
      name: seed.name,
      type,
      isText: true,
      text,
      options: Object.assign({}, defaultValue.options, seed.options)
    })));
  });

export const blobLoader = (type, seed) =>
  new Promise((resolve, reject) => {
    if (sanitize(seed, reject)) return;

    const blob = seed.blob || (base64 => {
      var bin = atob(base64);
      var byteArray = new Uint8Array(bin.length);
      for (var i = bin.length - 1; i >= 0; i--) {
        byteArray[i] = bin.charCodeAt(i);
      }
      return new Blob([byteArray.buffer], { type });
    })(seed.text);

    resolve(merger({
      name: seed.name,
      type,
      isText: false,
      blob,
      blobURL: URL.createObjectURL(blob),
      options: Object.assign({}, defaultValue.options, seed.options)
    }));
  });

const blobToBase64 = (blob) =>
  new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = (event) => {
      const { result } = event.target;
      resolve(result.substr(result.indexOf(',') + 1));
    };
    reader.readAsDataURL(blob);
  });

const sanitize = (seed, reject) => {
  if (typeof seed.text !== 'string' && !seed.blob) {
    reject(new Error(`Needed text or blob, but given: ${JSON.stringify(seed)}`));
    return true;
  }
  return false;
};
<|endoftext|>


<commit_before>/**
*  introScreen.js
*  _____________________________________________________________________________
*
*  @author William Malone (www.williammalone.com)
*/

/*global window, BLOCKS, Image */

BLOCKS.introScreen = function (spec, game) {

	"use strict";

	var introScreen = BLOCKS.eventDispatcher(),
		bg,
		clock,
		layer,
		destroyed,
		container = BLOCKS.container(game),

		load = function () {

			spec.bg.image = game.imageLoader.loadNow(spec.bg);
			spec.bg.image.onload = prepare;
		},

		onTick = function () {

			update();
			render();
		},

		prepare = function () {

			if (!destroyed) {

				layer = game.addLayer("intro", {
					zIndex: 1
				});

				bg = BLOCKS.slice({
					layer: layer,
					image: spec.bg.image
				});

				clock = BLOCKS.clock();
				clock.addEventListener("tick", onTick);
				clock.start();
			}
		},

		update = function () {

			//container.update();
			bg.update();
		},

		render = function () {

			//container.render(game);

			if (layer.dirty) {
				bg.dirty = true;
				//layer.clear();
			}

			bg.render(game);
		};

	introScreen.destroy = function () {

		destroyed = true;

		if (clock) {
			clock.destroy();
		}

		if (bg) {
			bg.destroy();
		}

		if (layer) {
			game.removeLayer("intro");
		}

		introScreen = null;
	};

	load();

	return introScreen;
};<commit_msg>Cleaned Up Unnecessary IntroScreen Variables<commit_after>/**
*  introScreen.js
*  _____________________________________________________________________________
*
*  @author William Malone (www.williammalone.com)
*/

/*global window, BLOCKS, Image */

BLOCKS.introScreen = function (spec, game) {

	"use strict";

	var introScreen = BLOCKS.eventDispatcher(),
		bg,
		clock,
		layer,
		destroyed,

		load = function () {

			spec.bg.image = game.imageLoader.loadNow(spec.bg);
			spec.bg.image.onload = prepare;
		},

		onTick = function () {

			update();
			render();
		},

		prepare = function () {

			if (!destroyed) {

				layer = game.addLayer("intro", {
					zIndex: 1
				});

				bg = BLOCKS.slice({
					layer: layer,
					image: spec.bg.image
				});

				clock = BLOCKS.clock();
				clock.addEventListener("tick", onTick);
				clock.start();
			}
		},

		update = function () {

			bg.update();
		},

		render = function () {

			if (layer.dirty) {
				bg.dirty = true;
			}

			bg.render(game);
		};

	introScreen.destroy = function () {

		destroyed = true;

		if (clock) {
			clock.destroy();
		}

		if (bg) {
			bg.destroy();
		}

		if (layer) {
			game.removeLayer("intro");
		}

		introScreen = null;
	};

	load();

	return introScreen;
};<|endoftext|>


<commit_before>/*
CinsImp
Field

*********************************************************************************
Copyright (c) 2009-2015, Joshua Hawcroft
All rights reserved.

 May all beings have happiness and the cause of happiness.
 May all beings be free of suffering and the cause of suffering.
 May all beings rejoice for the supreme happiness which is without suffering.
 May all beings abide in the great equanimity; free of attachment and delusion.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of the product nor the
      names of its contributors may be used to endorse or promote products
      derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

var CinsImp = CinsImp || {};
CinsImp.Model = CinsImp.Model || {};

var Model = CinsImp.Model;

// **TODO gradually apply ALL styling within the code, without stylesheets

/*****************************************************************************************
Construction, Defaults and Serialisation
*/

Model.Field = function(in_def, in_layer)
{
	/* create the object */
	LayerObject.call(this, in_def, in_layer);
	this._data =
	{
		'content': ''
	};

	/* init defaults */
	if (!in_def)
	{
		Util.array_apply(this._def,
		{
			'border': true,
			'shadow': false,
			'scroll': false,
			'locked': false,
			'dont_wrap': false,
			'auto_tab': false,
			'wide_margins': false,
			'auto_select': false,
			'selection': '',
			'picklist': '',

			'content': ''
		});
		this.set_size([200, 85]);
	}
}
var Field = Model.Field;
Util.classInheritsFrom(Field, Model.LayerObject);
Field.TYPE = 'field';

Field.prototype.get_type = function()
{
	return Field.TYPE;
}

/*****************************************************************************************
DOM View
*/

Field.prototype.create_dom = function(in_view)
{
	this.parent.create_dom.call(this, in_view);

	this._div.classList.add('fld');

	this._inner = document.createElement('div');
	this._div.appendChild(this._inner);
	this._inner.style.boxSizing = 'border-box';

	return this._div;
}

Field.prototype._dom_rebuild = function()
{
	this._div.style.border = (this.get_attr('border') ? '1px solid black' : '');
	this._div.style.backgroundColor = Util.color_to_css(this.get_attr('border'));
	this._div.style.boxShadow = (this.get_attr('shadow') ? '2px 2px 2px 2px rgba(0,0,0,0.75)' : '');

	this._inner.style.overflowY = (this.get_attr('scroll') ? 'scroll' : 'hidden');
	this._inner.style.padding = (this.get_attr('wide_margins') ? '10px' : '0px');
	this._inner.style.whiteSpace = (this.get_attr('dont_wrap') ? 'nowrap' : 'normal');

	this._apply_text_attrs(this._inner);
}

Field.prototype._attribute_written = function(in_attr, in_value)
{
	switch (in_attr)
	{
	case 'content':
		if (this._div) this._inner.innerHTML = in_value;
		break;
	}
}

Field.prototype._attribute_reading = function(in_attr)
{
	if (this._div && in_attr == 'content')
		this.set_attr(in_attr, this._inner.innerHTML);
}

/*****************************************************************************************
DOM Interaction, Events
*/

Field.prototype.set_dom_editability = function(in_edit, in_show_content)
{
	var editable = (in_edit && !this.get_attr('locked'));

	this._inner.style.visibility = (in_show_content ? 'visible' : 'hidden');
	this._inner.contentEditable = editable;

	this._inner.style.cursor = (editable ? 'text' : '');

	var state = (editable ? 'text' : 'none');
	this._inner.style.userSelect = state;
	this._inner.style.MozUserSelect = state;
	this._inner.style.webkitUserSelect = state;
	this._inner.style.webkitTouchCallout = state;
	this._inner.style.khtmlUserSelect = state;
	this._inner.style.msUserSelect = state;
}

CinsImp._script_loaded('Model.Field');

<commit_msg>fixed bug with field colour<commit_after>/*
CinsImp
Field

*********************************************************************************
Copyright (c) 2009-2015, Joshua Hawcroft
All rights reserved.

 May all beings have happiness and the cause of happiness.
 May all beings be free of suffering and the cause of suffering.
 May all beings rejoice for the supreme happiness which is without suffering.
 May all beings abide in the great equanimity; free of attachment and delusion.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of the product nor the
      names of its contributors may be used to endorse or promote products
      derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

var CinsImp = CinsImp || {};
CinsImp.Model = CinsImp.Model || {};

var Model = CinsImp.Model;

// **TODO gradually apply ALL styling within the code, without stylesheets

/*****************************************************************************************
Construction, Defaults and Serialisation
*/

Model.Field = function(in_def, in_layer)
{
	/* create the object */
	LayerObject.call(this, in_def, in_layer);
	this._data =
	{
		'content': ''
	};

	/* init defaults */
	if (!in_def)
	{
		Util.array_apply(this._def,
		{
			'border': true,
			'shadow': false,
			'scroll': false,
			'locked': false,
			'dont_wrap': false,
			'auto_tab': false,
			'wide_margins': false,
			'auto_select': false,
			'selection': '',
			'picklist': '',

			'content': ''
		});
		this.set_size([200, 85]);
	}
}
var Field = Model.Field;
Util.classInheritsFrom(Field, Model.LayerObject);
Field.TYPE = 'field';

Field.prototype.get_type = function()
{
	return Field.TYPE;
}

/*****************************************************************************************
DOM View
*/

Field.prototype.create_dom = function(in_view)
{
	this.parent.create_dom.call(this, in_view);

	this._div.classList.add('fld');

	this._inner = document.createElement('div');
	this._div.appendChild(this._inner);
	this._inner.style.boxSizing = 'border-box';

	return this._div;
}

Field.prototype._dom_rebuild = function()
{
	this._div.style.border = (this.get_attr('border') ? '1px solid black' : '');
	this._div.style.backgroundColor = Util.color_to_css(this.get_attr('color'));
	this._div.style.boxShadow = (this.get_attr('shadow') ? '2px 2px 2px 2px rgba(0,0,0,0.75)' : '');

	this._inner.style.overflowY = (this.get_attr('scroll') ? 'scroll' : 'hidden');
	this._inner.style.padding = (this.get_attr('wide_margins') ? '10px' : '0px');
	this._inner.style.whiteSpace = (this.get_attr('dont_wrap') ? 'nowrap' : 'normal');

	this._apply_text_attrs(this._inner);
}

Field.prototype._attribute_written = function(in_attr, in_value)
{
	switch (in_attr)
	{
	case 'content':
		if (this._div) this._inner.innerHTML = in_value;
		break;
	}
}

Field.prototype._attribute_reading = function(in_attr)
{
	if (this._div && in_attr == 'content')
		this.set_attr(in_attr, this._inner.innerHTML);
}

/*****************************************************************************************
DOM Interaction, Events
*/

Field.prototype.set_dom_editability = function(in_edit, in_show_content)
{
	var editable = (in_edit && !this.get_attr('locked'));

	this._inner.style.visibility = (in_show_content ? 'visible' : 'hidden');
	this._inner.contentEditable = editable;

	this._inner.style.cursor = (editable ? 'text' : '');

	var state = (editable ? 'text' : 'none');
	this._inner.style.userSelect = state;
	this._inner.style.MozUserSelect = state;
	this._inner.style.webkitUserSelect = state;
	this._inner.style.webkitTouchCallout = state;
	this._inner.style.khtmlUserSelect = state;
	this._inner.style.msUserSelect = state;
}

CinsImp._script_loaded('Model.Field');

<|endoftext|>


<commit_before>function Recognition() {

    var VERSION = '0.2',
        kanjis = {};

    this.kanjis = kanjis;

    init();

    function init() {
        var data = localStorage.getItem("recog"),
            version = localStorage.getItem("recog_version");

        if (data !== null) {
            if (version != VERSION) {
                downloadData();
            } else {
                doInit(JSON.parse(data));
            }
        } else {
            downloadData();
        }

        function downloadData() {
            sendRequest("data/recog-" + VERSION + ".json", function (data) {
                localStorage.setItem("recog", data);
                localStorage.setItem("recog_version", VERSION);
                doInit(JSON.parse(data));
            });
        }
    }

    function doInit(recog) {
        for (var k in recog) {
            var kanji = new Kanji(k, recog[k]);

            var sub = kanjis[kanji.strokes.length];
            if (!sub) {
                sub = {};
                kanjis[kanji.strokes.length] = sub;
            }
            sub[kanji.symbol] = kanji;
        }
    }

    function Kanji(symbol, strokesRecogData) {
        this.symbol = symbol;
        this.strokes = [];

        if (strokesRecogData) {
            parseRecogData(strokesRecogData, this.strokes);
        }

        function parseRecogData(strokesRecogData, strokes) {
            var rnd = Math.floor(Math.random() * 10 + 1);
            for (var i = 0; i < rnd; i++) {
                strokes[i] = i + rnd;
            }
        }
    }

    function Stroke() {

    }

}<commit_msg>parse stroke data<commit_after>function Recognition() {

    var VERSION = '0.2',
        kanjis = {};

    this.kanjis = kanjis;

    init();

    function init() {
        var data = localStorage.getItem("recog"),
            version = localStorage.getItem("recog_version");

        if (data !== null) {
            if (version != VERSION) {
                downloadData();
            } else {
                doInit(JSON.parse(data));
            }
        } else {
            downloadData();
        }

        function downloadData() {
            sendRequest("data/recog-" + VERSION + ".json", function (data) {
                localStorage.setItem("recog", data);
                localStorage.setItem("recog_version", VERSION);
                doInit(JSON.parse(data));
            });
        }
    }

    function doInit(recog) {
        var start = new Date;
        console.log("Parse start: " + start);
        for (var k in recog) {
            if (!recog.hasOwnProperty(k)) {
                continue;
            }

            var kanji = new Kanji(k, recog[k]),
                sub = kanjis[kanji.strokes.length];

            if (!sub) {
                sub = {};
                kanjis[kanji.strokes.length] = sub;
            }
            sub[kanji.symbol] = kanji;
        }
        console.log("Parse complete in: " + ((new Date - start) / 1000) + " sec");
    }

    function Kanji(symbol, strokesRecogData) {
        this.symbol = symbol;
        this.strokes = [];

        if (strokesRecogData) {
            parseRecogData(strokesRecogData, this.strokes);
        }

        function parseRecogData(strokesRecogData, strokes) {
            strokesRecogData = strokesRecogData.replace(/x/g, "00").replace(/y/g, "ff");
            if (strokesRecogData.length % 8 != 0) {
                //console.log("Wrong data for " + symbol + ": \"" + strokesRecogData + "\"");
                return;
            }
            var count = strokesRecogData.length / 8;
            for (var i = 0; i < count; i++) {
                var stroke = strokesRecogData.substr(i * 8, 8);
                strokes[i] = [
                    parseInt(stroke.substr(0, 2), 16),
                    parseInt(stroke.substr(2, 2), 16),
                    parseInt(stroke.substr(4, 2), 16),
                    parseInt(stroke.substr(6, 2), 16)
                ];
            }
        }
    }

    function Stroke() {

    }

}<|endoftext|>