<commit_before>/**
 * Pimcore
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://www.pimcore.org/license
 *
 * @copyright  Copyright (c) 2009-2014 pimcore GmbH (http://www.pimcore.org)
 * @license    http://www.pimcore.org/license     New BSD License
 */

pimcore.registerNS("pimcore.object.classes.data.multiselect");
pimcore.object.classes.data.multiselect = Class.create(pimcore.object.classes.data.data, {

    type: "multiselect",
    /**
     * define where this datatype is allowed
     */
    allowIn: {
        object: true,
        objectbrick: true,
        fieldcollection: true,
        localizedfield: true
    },

    initialize: function (treeNode, initData) {
        this.type = "multiselect";

        this.initData(initData);

        // overwrite default settings
        this.availableSettingsFields = ["name","title","tooltip","mandatory","noteditable","invisible",
            "visibleGridView","visibleSearch","style"];

        this.treeNode = treeNode;
    },

    getTypeName: function () {
        return t("multiselect");
    },

    getGroup: function () {
        return "select";
    },

    getIconClass: function () {
        return "pimcore_icon_multiselect";
    },

    getLayout: function ($super) {

        if(typeof this.datax.options != "object") {
            this.datax.options = [];
        }

        this.valueStore = new Ext.data.JsonStore({
            fields: ["key", "value"],
            data: this.datax.options
        });

        this.valueGrid = new Ext.grid.EditorGridPanel({
            tbar: [{
                xtype: "tbtext",
                text: t("selection_options")
            }, "-", {
                xtype: "button",
                iconCls: "pimcore_icon_add",
                handler: function () {
                    var u = new this.valueStore.recordType({
                        key: "",
                        value: ""
                    });
                    this.valueStore.insert(0, u);
                }.bind(this)
            }],
            style: "margin-top: 10px",
            store: this.valueStore,
            disabled: this.isInCustomLayoutEditor(),
            selModel:new Ext.grid.RowSelectionModel({singleSelect:true}),
            columnLines: true,
            columns: [
                {header: t("display_name"), sortable: false, dataIndex: 'key', editor: new Ext.form.TextField({}),
                                                    width: 200},
                {header: t("value"), sortable: false, dataIndex: 'value', editor: new Ext.form.TextField({}),
                                                    width: 200},
                {
                    xtype:'actioncolumn',
                    width:30,
                    items:[
                        {
                            tooltip:t('up'),
                            icon:"/pimcore/static/img/icon/arrow_up.png",
                            handler:function (grid, rowIndex) {
                                if (rowIndex > 0) {
                                    var rec = grid.getStore().getAt(rowIndex);
                                    grid.getStore().removeAt(rowIndex);
                                    grid.getStore().insert(rowIndex - 1, [rec]);
                                }
                            }.bind(this)
                        }
                    ]
                },
                {
                    xtype:'actioncolumn',
                    width:30,
                    items:[
                        {
                            tooltip:t('down'),
                            icon:"/pimcore/static/img/icon/arrow_down.png",
                            handler:function (grid, rowIndex) {
                                if (rowIndex < (grid.getStore().getCount() - 1)) {
                                    var rec = grid.getStore().getAt(rowIndex);
                                    grid.getStore().removeAt(rowIndex);
                                    grid.getStore().insert(rowIndex + 1, [rec]);
                                }
                            }.bind(this)
                        }
                    ]
                },
                {
                    xtype: 'actioncolumn',
                    width: 30,
                    items: [
                        {
                            tooltip: t('remove'),
                            icon: "/pimcore/static/img/icon/cross.png",
                            handler: function (grid, rowIndex) {
                                grid.getStore().removeAt(rowIndex);
                            }.bind(this)
                        }
                    ]
                }
            ],
            autoHeight: true
        });

        $super();

        this.specificPanel.removeAll();
        this.specificPanel.add([
            {
                xtype: "spinnerfield",
                fieldLabel: t("width"),
                name: "width",
                value: this.datax.width
            },
            {
                xtype: "spinnerfield",
                fieldLabel: t("height"),
                name: "height",
                value: this.datax.height
            },this.valueGrid
        ]);

        return this.layout;
    },

    applyData: function ($super) {

        $super();

        var options = [];

        this.valueStore.commitChanges();
        this.valueStore.each(function (rec) {
            options.push({
                key: rec.get("key"),
                value: rec.get("value")
            });
        });

        this.datax.options = options;
    },

    applySpecialData: function(source) {
        if (source.datax) {
            if (!this.datax) {
                this.datax =  {};
            }
            Ext.apply(this.datax,
                {
                    options: source.datax.options,
                    width: source.datax.width,
                    height: source.datax.height
                });
        }
    }
});
<commit_msg>PIMCORE-2433 - Add drag and ordering for multiselect options in class definition, like new select features.<commit_after>/**
 * Pimcore
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://www.pimcore.org/license
 *
 * @copyright  Copyright (c) 2009-2014 pimcore GmbH (http://www.pimcore.org)
 * @license    http://www.pimcore.org/license     New BSD License
 */

pimcore.registerNS("pimcore.object.classes.data.multiselect");
pimcore.object.classes.data.multiselect = Class.create(pimcore.object.classes.data.data, {

    type: "multiselect",
    /**
     * define where this datatype is allowed
     */
    allowIn: {
        object: true,
        objectbrick: true,
        fieldcollection: true,
        localizedfield: true
    },

    initialize: function (treeNode, initData) {
        this.type = "multiselect";

        this.initData(initData);

        // overwrite default settings
        this.availableSettingsFields = ["name","title","tooltip","mandatory","noteditable","invisible",
            "visibleGridView","visibleSearch","style"];

        this.treeNode = treeNode;
    },

    getTypeName: function () {
        return t("multiselect");
    },

    getGroup: function () {
        return "select";
    },

    getIconClass: function () {
        return "pimcore_icon_multiselect";
    },

    getLayout: function ($super) {

        if(typeof this.datax.options != "object") {
            this.datax.options = [];
        }

        this.valueStore = new Ext.data.JsonStore({
            fields: ["key", "value"],
            data: this.datax.options
        });

        this.valueGrid = new Ext.grid.EditorGridPanel({
            enableDragDrop: true,
            ddGroup: 'objectclassmultiselect',
            tbar: [{
                xtype: "tbtext",
                text: t("selection_options")
            }, "-", {
                xtype: "button",
                iconCls: "pimcore_icon_add",
                handler: function () {
                    var u = new this.valueStore.recordType({
                        key: "",
                        value: ""
                    });
                    this.valueStore.insert(0, u);
                }.bind(this)
            }],
            style: "margin-top: 10px",
            store: this.valueStore,
            disabled: this.isInCustomLayoutEditor(),
            selModel:new Ext.grid.RowSelectionModel({singleSelect:true}),
            columnLines: true,
            columns: [
                {header: t("display_name"), sortable: true, dataIndex: 'key', editor: new Ext.form.TextField({}),
                                                    width: 200},
                {header: t("value"), sortable: true, dataIndex: 'value', editor: new Ext.form.TextField({}),
                                                    width: 200},
                {
                    xtype:'actioncolumn',
                    width:30,
                    items:[
                        {
                            tooltip:t('up'),
                            icon:"/pimcore/static/img/icon/arrow_up.png",
                            handler:function (grid, rowIndex) {
                                if (rowIndex > 0) {
                                    var rec = grid.getStore().getAt(rowIndex);
                                    grid.getStore().removeAt(rowIndex);
                                    grid.getStore().insert(rowIndex - 1, [rec]);
                                }
                            }.bind(this)
                        }
                    ]
                },
                {
                    xtype:'actioncolumn',
                    width:30,
                    items:[
                        {
                            tooltip:t('down'),
                            icon:"/pimcore/static/img/icon/arrow_down.png",
                            handler:function (grid, rowIndex) {
                                if (rowIndex < (grid.getStore().getCount() - 1)) {
                                    var rec = grid.getStore().getAt(rowIndex);
                                    grid.getStore().removeAt(rowIndex);
                                    grid.getStore().insert(rowIndex + 1, [rec]);
                                }
                            }.bind(this)
                        }
                    ]
                },
                {
                    xtype: 'actioncolumn',
                    width: 30,
                    items: [
                        {
                            tooltip: t('remove'),
                            icon: "/pimcore/static/img/icon/cross.png",
                            handler: function (grid, rowIndex) {
                                grid.getStore().removeAt(rowIndex);
                            }.bind(this)
                        }
                    ]
                }
            ],
            autoHeight: true
        });

        this.valueGrid.on("afterrender", function () {

            var dropTargetEl = this.valueGrid.getEl();
            var gridDropTarget = new Ext.dd.DropZone(dropTargetEl, {
                ddGroup    : 'objectclassmultiselect',
                getTargetFromEvent: function(e) {
                    return this.valueGrid.getEl().dom;
                }.bind(this),
                onNodeOver: function (overHtmlNode, ddSource, e, data) {
                    if(data["grid"] && data["grid"] == this.valueGrid) {
                        return Ext.dd.DropZone.prototype.dropAllowed;
                    }
                    return Ext.dd.DropZone.prototype.dropNotAllowed;
                }.bind(this),
                onNodeDrop : function(target, dd, e, data) {
                    if(data["grid"] && data["grid"] == this.valueGrid) {
                        var rowIndex = this.valueGrid.getView().findRowIndex(e.target);
                        if(rowIndex !== false) {
                            var store = this.valueGrid.getStore();
                            var rec = store.getAt(data.rowIndex);
                            store.removeAt(data.rowIndex);
                            store.insert(rowIndex, [rec]);
                        }
                    }
                    return false;
                }.bind(this)
            });
        }.bind(this));

        $super();

        this.specificPanel.removeAll();
        this.specificPanel.add([
            {
                xtype: "spinnerfield",
                fieldLabel: t("width"),
                name: "width",
                value: this.datax.width
            },
            {
                xtype: "spinnerfield",
                fieldLabel: t("height"),
                name: "height",
                value: this.datax.height
            },this.valueGrid
        ]);

        return this.layout;
    },

    applyData: function ($super) {

        $super();

        var options = [];

        this.valueStore.commitChanges();
        this.valueStore.each(function (rec) {
            options.push({
                key: rec.get("key"),
                value: rec.get("value")
            });
        });

        this.datax.options = options;
    },

    applySpecialData: function(source) {
        if (source.datax) {
            if (!this.datax) {
                this.datax =  {};
            }
            Ext.apply(this.datax,
                {
                    options: source.datax.options,
                    width: source.datax.width,
                    height: source.datax.height
                });
        }
    }
});
<|endoftext|>


<commit_before>/*
Name: mag-store v0.1.1
Description: remote json api
Author: Michael Glazer
License: MIT
Homepage: https://github.com/magnumjs/mag.js
@requires mag.js & mag addons
(c) 2016
*/

mag.store = function(id, mod, props) {

  if (typeof id === 'object') {
    props = id;
  }

  props = props || {}
  options = props.store || {};

  var storageType = window[options.storageType || 'sessionStorage']
  var initialState = options.cache
  var expires = options.expires || 3000;
  var loop = options.loop || false;
  // http://jsonblob.com/api/jsonBlob/
  var res = 'https://api.myjson.com/bins/'
  var resource = options.resource || res; // jsonblod OR myjson
  var SOURCE_URL = options.url || options.collection && resource + options.collection || res + id;
  var listeners = [];
  var saving = false;

  if (loop) {
    setInterval(function() {
      if (!saving) {
        synchRemote()
          .then(function() {
            if (!saving) notify(getCache());
          })
      }
    }, expires);
  }

  var notify = function(state) {
    listeners.forEach(function(callback) {
      callback(state);
    });
  }

  var merge = function(local, remote) {
    //Loop remote:
    var ndata = []
    remote.forEach(function(ritem) {

      var lfound = local.find(function(litem) {
        return litem._id === ritem._id
      })
      if (lfound && lfound._time > ritem._time) {
        ndata.push(lfound)
      } else {
        ndata.push(ritem);
      }
    })
    return ndata;
  };

  var synchRemote = function() {
    var cacheCopy = getCache();
    return mag.request({
      url: SOURCE_URL
    }).then(function(rdata) {
      if (JSON.stringify(rdata) !== JSON.stringify(cacheCopy)) {
        // merge
        var ndata = merge(cacheCopy, rdata);
        setCache(ndata)
      }
      return ndata || rdata;
    });
  }

  var saveData = function(ndata) {

    var cacheCopy = getCache();
    // get remote latest
    return mag.request({
      url: SOURCE_URL
    }).then(function(rdata) {
      if (JSON.stringify(rdata) !== JSON.stringify(cacheCopy)) {
        // merge
        ndata = merge(ndata, rdata);
      }

      //Reset caches:
      setCache(ndata);

      return mag.request({
        url: SOURCE_URL,
        method: 'put',
        data: JSON.stringify(ndata),
        headers: [{
          "Content-Type": "application/json; charset=utf-8"
        }]
      }).then(function(data) {
        saving = false;
        return data;
      })
    });

  }

  var timer2;
  var getData = function() {
    var def = mag.deferred();

    clearTimeout(timer2);
    timer2 = setTimeout(function() {
      synchRemote()
        .then(function() {
          def.resolve(getCache())
        })
    });

    return def.promise;
  }

  //Privates :
  var cache;

  function setCache(data) {
    cache = data;
    storageType.setItem(SOURCE_URL, JSON.stringify(data))
    return mag.copy(data);
  }

  function getCache() {
    cache = JSON.parse(storageType.getItem(SOURCE_URL));
    return mag.copy(cache);
  }

  var findAll = function(query) {
    var data = getData();
    // get with no query
    if (!query) return data;

    //With query:
    // filter
    return data.then(function(rdata) {
      return rdata.filter(function(item) {
        var ret = false;
        for (var prop in query) {
          if (query[prop] === item[prop]) ret = true;
        }
        return ret;
      })
    })

  };

  var genId = function() {
    return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
  }
  var addNew = function(ndata) {
    var data = mag.copy(cache);

    // add id and time fields
    ndata._id = genId() + genId() + genId() + genId();
    ndata._time = Date.now();

    data.push(ndata);

    return save(data);
  }

  var deleteBy = function(query) {
    var data = getCache();

    var foundIndex = data.findIndex(function(item) {
      return item._id === query._id;
    });
    if (!~foundIndex) throw Error('mag.store - index not found');
    data.splice(foundIndex, 1);

    return save(data);
  };

  var update = function(query, change) {
    var data = getCache();

    var foundIndex = data.findIndex(function(item) {
      return item._id === query._id;
    });

    if (!~foundIndex) throw Error('mag.store - index not found');
    //Merge:
    for (var prop in data[foundIndex]) {
      if (typeof change[prop] !== 'undefined') data[foundIndex][prop] = change[prop];
    }
    data[foundIndex]._time = Date.now();

    return save(data);
  };

  var timer, delay = expires;
  var lastState;

  var check = function() {
    if (JSON.stringify(lastState) !== JSON.stringify(cache)) {
      // save to remote url
      saveData(lastState).then(function() {
        notify(getCache());
      })
    }
  }
  var save = function(data) {
    saving = true;
    // debounce changes -- check for diffs
    // then save to source url
    clearTimeout(timer);
    timer = setTimeout(function() {
      check();
    }, delay);

    return lastState = data;
  }

  var createNew = function(initialData) {
    saving = true;
    initialData = initialData || [];

    // POST to url
    // returns based on framework

    // myjson
    var getCreateId = function(responseData, responseHeaders) {
      //  {"uri":"https://api.myjson.com/bins/:id"}
      var id = responseData.uri.split('/').pop();
      return id;
    }

    return mag.request({
      url: SOURCE_URL,
      method: 'post',
      data: JSON.stringify(initialData),
      headers: [{
        "Content-Type": "application/json; charset=utf-8"
      }]
    }).then(function(data, headers) {
      saving = false;

      var newId = getCreateId(data, headers);

      return newId;
    })

  }

  var api = {
    subscribe: function(cb) {
      listeners.push(cb);
    },
    synch: synchRemote,
    create: createNew,
    clear: function() {
      // set collection to empty
      return saveData([]);
    },
    find: findAll,
    remove: deleteBy,
    update: update,
    insert: addNew,
    reset: function() {
      return setCache(null)
    }
  }

  if (id && mod) {
    var app;
    props[id] = api;

    if(typeof mod !== 'function'){
      app = mag.create(id, mod, props);
    } else {
      app = mod(id, props);
    }
    api.subscribe(function(state) {
      app(props).getState()[id] = state;
    });

    return app;
  } else {
    return api;
  }
}
<commit_msg>Update mag-store.js<commit_after>/*
Name: mag-store v0.1.1
Description: remote json api
Author: Michael Glazer
License: MIT
Homepage: https://github.com/magnumjs/mag.js
@requires mag.js & mag addons
(c) 2016
*/

mag.store = function(id, mod, props) {

  if (typeof id === 'object') {
    props = id;
  }

  props = props || {}
  options = props.store || {};

  var storageType = window[options.storageType || 'sessionStorage']
  var initialState = options.cache
  var expires = options.expires || 3000;
  var loop = options.loop || false;
  // http://jsonblob.com/api/jsonBlob/
  var res = 'https://api.myjson.com/bins/'
  var resource = options.resource || res; // jsonblod OR myjson
  var SOURCE_URL = options.url || options.collection && resource + options.collection || res + id;
  var listeners = [];
  var saving = false;

  if (loop) {
    setInterval(function() {
      if (!saving) {
        synchRemote()
          .then(function() {
            if (!saving) notify(getCache());
          })
      }
    }, expires);
  }

  var notify = function(state) {
    listeners.forEach(function(callback) {
      callback(state);
    });
  }

  var merge = function(local, remote) {
    //Loop remote:
    var ndata = []
    remote.forEach(function(ritem) {

      var lfound = local && local.find(function(litem) {
        return litem._id === ritem._id
      })
      if (lfound && lfound._time > ritem._time) {
        ndata.push(lfound)
      } else {
        ndata.push(ritem);
      }
    })
    return ndata;
  };

  var synchRemote = function() {
    var cacheCopy = getCache();
    return mag.request({
      url: SOURCE_URL
    }).then(function(rdata) {
      if (JSON.stringify(rdata) !== JSON.stringify(cacheCopy)) {
        // merge
        var ndata = merge(cacheCopy, rdata);
        setCache(ndata)
      }
      return ndata || rdata;
    });
  }

  var saveData = function(ndata) {

    var cacheCopy = getCache();
    // get remote latest
    return mag.request({
      url: SOURCE_URL
    }).then(function(rdata) {
      if (JSON.stringify(rdata) !== JSON.stringify(cacheCopy)) {
        // merge
        ndata = merge(ndata, rdata);
      }

      //Reset caches:
      setCache(ndata);

      return mag.request({
        url: SOURCE_URL,
        method: 'put',
        data: JSON.stringify(ndata),
        headers: [{
          "Content-Type": "application/json; charset=utf-8"
        }]
      }).then(function(data) {
        saving = false;
        return data;
      })
    });

  }

  var timer2;
  var getData = function() {
    var def = mag.deferred();

    clearTimeout(timer2);
    timer2 = setTimeout(function() {
      synchRemote()
        .then(function() {
          def.resolve(getCache())
        })
    });

    return def.promise;
  }

  //Privates :
  var cache;

  function setCache(data) {
    cache = data;
    storageType.setItem(SOURCE_URL, JSON.stringify(data))
    return mag.copy(data);
  }

  function getCache() {
    cache = JSON.parse(storageType.getItem(SOURCE_URL));
    return mag.copy(cache);
  }

  var findAll = function(query) {
    var data = getData();
    // get with no query
    if (!query) return data;

    //With query:
    // filter
    return data.then(function(rdata) {
      return rdata.filter(function(item) {
        var ret = false;
        for (var prop in query) {
          if (query[prop] === item[prop]) ret = true;
        }
        return ret;
      })
    })

  };

  var genId = function() {
    return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
  }
  var addNew = function(ndata) {
    var data = mag.copy(cache);

    // add id and time fields
    ndata._id = genId() + genId() + genId() + genId();
    ndata._time = Date.now();

    data.push(ndata);

    return save(data);
  }

  var deleteBy = function(query) {
    var data = getCache();

    var foundIndex = data.findIndex(function(item) {
      return item._id === query._id;
    });
    if (!~foundIndex) throw Error('mag.store - index not found');
    data.splice(foundIndex, 1);

    return save(data);
  };

  var update = function(query, change) {
    var data = getCache();

    var foundIndex = data.findIndex(function(item) {
      return item._id === query._id;
    });

    if (!~foundIndex) throw Error('mag.store - index not found');
    //Merge:
    for (var prop in data[foundIndex]) {
      if (typeof change[prop] !== 'undefined') data[foundIndex][prop] = change[prop];
    }
    data[foundIndex]._time = Date.now();

    return save(data);
  };

  var timer, delay = expires;
  var lastState;

  var check = function() {
    if (JSON.stringify(lastState) !== JSON.stringify(cache)) {
      // save to remote url
      saveData(lastState).then(function() {
        notify(getCache());
      })
    }
  }
  var save = function(data) {
    saving = true;
    // debounce changes -- check for diffs
    // then save to source url
    clearTimeout(timer);
    timer = setTimeout(function() {
      check();
    }, delay);

    return lastState = data;
  }

  var createNew = function(initialData) {
    saving = true;
    initialData = initialData || [];

    // POST to url
    // returns based on framework

    // myjson
    var getCreateId = function(responseData, responseHeaders) {
      //  {"uri":"https://api.myjson.com/bins/:id"}
      var id = responseData.uri.split('/').pop();
      return id;
    }

    return mag.request({
      url: SOURCE_URL,
      method: 'post',
      data: JSON.stringify(initialData),
      headers: [{
        "Content-Type": "application/json; charset=utf-8"
      }]
    }).then(function(data, headers) {
      saving = false;

      var newId = getCreateId(data, headers);

      return newId;
    })

  }

  var api = {
    subscribe: function(cb) {
      listeners.push(cb);
    },
    synch: synchRemote,
    create: createNew,
    clear: function() {
      // set collection to empty
      return saveData([]);
    },
    find: findAll,
    remove: deleteBy,
    update: update,
    insert: addNew,
    reset: function() {
      return setCache(null)
    }
  }

  if (id && mod) {
    var app;
    props[id] = api;

    if (typeof mod !== 'function') {
      app = mag.create(id, mod, props);
    } else {
      app = mod(id, props);
    }
    api.subscribe(function(state) {
      app(props).getState()[id] = state;
    });

    return app;
  } else {
    return api;
  }
}
<|endoftext|>


<commit_before>/**
 *	Angular directive to truncate multi-line text to visible height
 *
 *	@param bind (angular bound value to append) REQUIRED
 *	@param ellipsisAppend (string) string to append at end of truncated text after ellipsis, can be HTML OPTIONAL
 *	@param ellipsisAppendClick (function) function to call if ellipsisAppend is clicked (ellipsisAppend must be clicked) OPTIONAL
 *	@param ellipsisSymbol (string) string to use as ellipsis, replaces default '...' OPTIONAL
 *	@param ellipsisSeparator (string) separator to split string, replaces default ' ' OPTIONAL
 *
 *	@example

 *	@example

 *	@example

 *	@example

 *
 */
angular.module('dibari.angular-ellipsis', [])

.directive('ellipsis', ['$timeout', '$window', '$sce', function($timeout, $window, $sce) {

	var AsyncDigest = function(delay) {
		var timeout = null;
		var queue = [];

		this.remove = function(fn) {
			if (queue.indexOf(fn) !== -1) {
				queue.splice(queue.indexOf(fn), 1);
				if (queue.length === 0) {
					$timeout.cancel(timeout);
					timeout = null;
				}
			}
		};
		this.add = function(fn) {
			if (queue.indexOf(fn) === -1) {
				queue.push(fn);
			}
			if (!timeout) {
				timeout = $timeout(function() {
					var copy = queue.slice();
					timeout = null;
					// reset scheduled array first in case one of the functions throws an error
					queue.length = 0;
					copy.forEach(function(fn) {
						fn();
					});
				}, delay);
			}
		};
	};

	var asyncDigestImmediate = new AsyncDigest(0);
	var asyncDigestDebounced = new AsyncDigest(75);

	return {
		restrict: 'A',
		scope: {
			ngBind: '=',
			ngBindHtml: '=',
			ellipsisAppend: '@',
			ellipsisAppendClick: '&',
			ellipsisSymbol: '@',
			ellipsisSeparator: '@',
			useParent: "@",
			ellipsisSeparatorReg: '='
		},
		compile: function(elem, attr, linker) {

			return function(scope, element, attributes) {
				/* Window Resize Variables */
				attributes.lastWindowResizeTime = 0;
				attributes.lastWindowResizeWidth = 0;
				attributes.lastWindowResizeHeight = 0;
				attributes.lastWindowTimeoutEvent = null;
				/* State Variables */
				attributes.isTruncated = false;

				function getParentHeight(element) {
					var heightOfChildren = 0;
					angular.forEach(element.parent().children(), function(child) {
						if (child != element[0]) {
							heightOfChildren += child.clientHeight;
						}
					});
					return element.parent()[0].clientHeight - heightOfChildren;
				}

				function buildEllipsis() {
					var binding = scope.ngBind || scope.ngBindHtml;
					var isTrustedHTML = false;
					if($sce.isEnabled() && angular.isObject(binding) && $sce.getTrustedHtml(binding)) {
						isTrustedHTML = true;
						binding = $sce.getTrustedHtml(binding);
					}
					if (binding) {
						var isHtml = (!(!!scope.ngBind) && !!(scope.ngBindHtml));
						var i = 0,
							ellipsisSymbol = (typeof(attributes.ellipsisSymbol) !== 'undefined') ? attributes.ellipsisSymbol : '…',
							ellipsisSeparator = (typeof(scope.ellipsisSeparator) !== 'undefined') ? attributes.ellipsisSeparator : ' ',
							ellipsisSeparatorReg = (typeof(scope.ellipsisSeparatorReg) !== 'undefined') ? scope.ellipsisSeparatorReg : false,
							appendString = (typeof(scope.ellipsisAppend) !== 'undefined' && scope.ellipsisAppend !== '') ? ellipsisSymbol + '' + scope.ellipsisAppend + '' : ellipsisSymbol,
							bindArray = ellipsisSeparatorReg ? binding.match(ellipsisSeparatorReg) : binding.split(ellipsisSeparator);

						attributes.isTruncated = false;
						if (isHtml) {
							element.html(binding);
						} else {
							element.text(binding);
						}

						// If text has overflow
						if (isOverflowed(element, scope.useParent)) {
							var bindArrayStartingLength = bindArray.length,
								initialMaxHeight = scope.useParent ? getParentHeight(element) : element[0].clientHeight;

							if (isHtml) {
								element.html(binding + appendString);
							} else {
								element.text(binding).html(element.html() + appendString);
							}
							//Set data-overflow on element for targeting
							element.attr('data-overflowed', 'true');

							// Set complete text and remove one word at a time, until there is no overflow
							for (; i < bindArrayStartingLength; i++) {
								bindArray.pop();

								if (isHtml) {
									element.html(bindArray.join(ellipsisSeparator) + appendString);
								} else {
									element.text(bindArray.join(ellipsisSeparator)).html(element.html() + appendString);
								}

								if ((scope.useParent ? element.parent()[0] : element[0]).scrollHeight < initialMaxHeight || isOverflowed(element, scope.useParent) === false) {
									attributes.isTruncated = true;
									break;
								}
							}

							// If append string was passed and append click function included
							if (ellipsisSymbol != appendString && typeof(scope.ellipsisAppendClick) !== 'undefined' && scope.ellipsisAppendClick !== '') {
								element.find('span').bind("click", function(e) {
									scope.$apply(function() {
										scope.ellipsisAppendClick.call(scope, {
											event: e
										});
									});
								});
							}

							if(!isTrustedHTML && $sce.isEnabled())
							{
								$sce.trustAsHtml(binding);
							}
						}
						else{
							element.attr('data-overflowed', 'false');
						}
					}
				}

				/**
				 *	Test if element has overflow of text beyond height or max-height
				 *
				 *	@param element (DOM object)
				 *
				 *	@return bool
				 *
				 */
				function isOverflowed(thisElement, useParent) {
					thisElement = useParent ? thisElement.parent() : thisElement;
					return thisElement[0].scrollHeight > thisElement[0].clientHeight;
				}

				/**
				 *	Watchers
				 */

				/**
				 *	Execute ellipsis truncate on ngBind update
				 */
				scope.$watch('ngBind', function() {
					asyncDigestImmediate.add(buildEllipsis);
				});

				/**
				 *	Execute ellipsis truncate on ngBindHtml update
				 */
				scope.$watch('ngBindHtml', function() {
					asyncDigestImmediate.add(buildEllipsis);
				});

				/**
				 *	Execute ellipsis truncate on ngBind update
				 */
				scope.$watch('ellipsisAppend', function() {
					buildEllipsis();
				});

				/**
				*	Execute ellipsis truncate when element becomes visible
				*/
				scope.$watch(function() { return element[0].offsetWidth != 0 && element[0].offsetHeight != 0 }, function() {
					asyncDigestDebounced.add(buildEllipsis);
				});

				function checkWindowForRebuild() {
					if (attributes.lastWindowResizeWidth != window.innerWidth || attributes.lastWindowResizeHeight != window.innerHeight) {
						buildEllipsis();
					}

					attributes.lastWindowResizeWidth = window.innerWidth;
					attributes.lastWindowResizeHeight = window.innerHeight;
				}

				var unbindRefreshEllipsis = scope.$on('dibari:refresh-ellipsis', function() {
					asyncDigestImmediate.add(buildEllipsis);
				});
				/**
				 *	When window width or height changes - re-init truncation
				 */

				function onResize() {
					asyncDigestDebounced.add(checkWindowForRebuild);
				}

				var $win = angular.element($window);
				$win.bind('resize', onResize);

				/**
				 * Clean up after ourselves
				 */
				scope.$on('$destroy', function() {
					$win.unbind('resize', onResize);
					asyncDigestImmediate.remove(buildEllipsis);
					asyncDigestDebounced.remove(checkWindowForRebuild);
					if (unbindRefreshEllipsis) {
						unbindRefreshEllipsis();
						unbindRefreshEllipsis = null;
					}
				});

			};
		}
	};
}]);
<commit_msg>Fixing an issue: Action assigned to data-ellipsis-append-click will be called more than one time<commit_after>/**
 *	Angular directive to truncate multi-line text to visible height
 *
 *	@param bind (angular bound value to append) REQUIRED
 *	@param ellipsisAppend (string) string to append at end of truncated text after ellipsis, can be HTML OPTIONAL
 *	@param ellipsisAppendClick (function) function to call if ellipsisAppend is clicked (ellipsisAppend must be clicked) OPTIONAL
 *	@param ellipsisSymbol (string) string to use as ellipsis, replaces default '...' OPTIONAL
 *	@param ellipsisSeparator (string) separator to split string, replaces default ' ' OPTIONAL
 *
 *	@example

 *	@example

 *	@example

 *	@example

 *
 */
angular.module('dibari.angular-ellipsis', [])

.directive('ellipsis', ['$timeout', '$window', '$sce', function($timeout, $window, $sce) {

	var AsyncDigest = function(delay) {
		var timeout = null;
		var queue = [];

		this.remove = function(fn) {
			if (queue.indexOf(fn) !== -1) {
				queue.splice(queue.indexOf(fn), 1);
				if (queue.length === 0) {
					$timeout.cancel(timeout);
					timeout = null;
				}
			}
		};
		this.add = function(fn) {
			if (queue.indexOf(fn) === -1) {
				queue.push(fn);
			}
			if (!timeout) {
				timeout = $timeout(function() {
					var copy = queue.slice();
					timeout = null;
					// reset scheduled array first in case one of the functions throws an error
					queue.length = 0;
					copy.forEach(function(fn) {
						fn();
					});
				}, delay);
			}
		};
	};

	var asyncDigestImmediate = new AsyncDigest(0);
	var asyncDigestDebounced = new AsyncDigest(75);

	return {
		restrict: 'A',
		scope: {
			ngBind: '=',
			ngBindHtml: '=',
			ellipsisAppend: '@',
			ellipsisAppendClick: '&',
			ellipsisSymbol: '@',
			ellipsisSeparator: '@',
			useParent: "@",
			ellipsisSeparatorReg: '='
		},
		compile: function(elem, attr, linker) {

			return function(scope, element, attributes) {
				/* Window Resize Variables */
				attributes.lastWindowResizeTime = 0;
				attributes.lastWindowResizeWidth = 0;
				attributes.lastWindowResizeHeight = 0;
				attributes.lastWindowTimeoutEvent = null;
				/* State Variables */
				attributes.isTruncated = false;

				function getParentHeight(element) {
					var heightOfChildren = 0;
					angular.forEach(element.parent().children(), function(child) {
						if (child != element[0]) {
							heightOfChildren += child.clientHeight;
						}
					});
					return element.parent()[0].clientHeight - heightOfChildren;
				}

				function buildEllipsis() {
					var binding = scope.ngBind || scope.ngBindHtml;
					var isTrustedHTML = false;
					if($sce.isEnabled() && angular.isObject(binding) && $sce.getTrustedHtml(binding)) {
						isTrustedHTML = true;
						binding = $sce.getTrustedHtml(binding);
					}
					if (binding) {
						var isHtml = (!(!!scope.ngBind) && !!(scope.ngBindHtml));
						var i = 0,
							ellipsisSymbol = (typeof(attributes.ellipsisSymbol) !== 'undefined') ? attributes.ellipsisSymbol : '…',
							ellipsisSeparator = (typeof(scope.ellipsisSeparator) !== 'undefined') ? attributes.ellipsisSeparator : ' ',
							ellipsisSeparatorReg = (typeof(scope.ellipsisSeparatorReg) !== 'undefined') ? scope.ellipsisSeparatorReg : false,
							appendString = (typeof(scope.ellipsisAppend) !== 'undefined' && scope.ellipsisAppend !== '') ? ellipsisSymbol + "" + scope.ellipsisAppend + '' : ellipsisSymbol,
							bindArray = ellipsisSeparatorReg ? binding.match(ellipsisSeparatorReg) : binding.split(ellipsisSeparator);

						attributes.isTruncated = false;
						if (isHtml) {
							element.html(binding);
						} else {
							element.text(binding);
						}

						// If text has overflow
						if (isOverflowed(element, scope.useParent)) {
							var bindArrayStartingLength = bindArray.length,
								initialMaxHeight = scope.useParent ? getParentHeight(element) : element[0].clientHeight;

							if (isHtml) {
								element.html(binding + appendString);
							} else {
								element.text(binding).html(element.html() + appendString);
							}
							//Set data-overflow on element for targeting
							element.attr('data-overflowed', 'true');

							// Set complete text and remove one word at a time, until there is no overflow
							for (; i < bindArrayStartingLength; i++) {
								bindArray.pop();

								if (isHtml) {
									element.html(bindArray.join(ellipsisSeparator) + appendString);
								} else {
									element.text(bindArray.join(ellipsisSeparator)).html(element.html() + appendString);
								}

								if ((scope.useParent ? element.parent()[0] : element[0]).scrollHeight < initialMaxHeight || isOverflowed(element, scope.useParent) === false) {
									attributes.isTruncated = true;
									break;
								}
							}

							// If append string was passed and append click function included
							if (ellipsisSymbol != appendString && typeof(scope.ellipsisAppendClick) !== 'undefined' && scope.ellipsisAppendClick !== '') {
								element.find('span.angular-ellipsis-append').bind("click", function(e) {
									scope.$apply(function() {
										scope.ellipsisAppendClick.call(scope, {
											event: e
										});
									});
								});
							}

							if(!isTrustedHTML && $sce.isEnabled())
							{
								$sce.trustAsHtml(binding);
							}
						}
						else{
							element.attr('data-overflowed', 'false');
						}
					}
				}

				/**
				 *	Test if element has overflow of text beyond height or max-height
				 *
				 *	@param element (DOM object)
				 *
				 *	@return bool
				 *
				 */
				function isOverflowed(thisElement, useParent) {
					thisElement = useParent ? thisElement.parent() : thisElement;
					return thisElement[0].scrollHeight > thisElement[0].clientHeight;
				}

				/**
				 *	Watchers
				 */

				/**
				 *	Execute ellipsis truncate on ngBind update
				 */
				scope.$watch('ngBind', function() {
					asyncDigestImmediate.add(buildEllipsis);
				});

				/**
				 *	Execute ellipsis truncate on ngBindHtml update
				 */
				scope.$watch('ngBindHtml', function() {
					asyncDigestImmediate.add(buildEllipsis);
				});

				/**
				 *	Execute ellipsis truncate on ngBind update
				 */
				scope.$watch('ellipsisAppend', function() {
					buildEllipsis();
				});

				/**
				*	Execute ellipsis truncate when element becomes visible
				*/
				scope.$watch(function() { return element[0].offsetWidth != 0 && element[0].offsetHeight != 0 }, function() {
					asyncDigestDebounced.add(buildEllipsis);
				});

				function checkWindowForRebuild() {
					if (attributes.lastWindowResizeWidth != window.innerWidth || attributes.lastWindowResizeHeight != window.innerHeight) {
						buildEllipsis();
					}

					attributes.lastWindowResizeWidth = window.innerWidth;
					attributes.lastWindowResizeHeight = window.innerHeight;
				}

				var unbindRefreshEllipsis = scope.$on('dibari:refresh-ellipsis', function() {
					asyncDigestImmediate.add(buildEllipsis);
				});
				/**
				 *	When window width or height changes - re-init truncation
				 */

				function onResize() {
					asyncDigestDebounced.add(checkWindowForRebuild);
				}

				var $win = angular.element($window);
				$win.bind('resize', onResize);

				/**
				 * Clean up after ourselves
				 */
				scope.$on('$destroy', function() {
					$win.unbind('resize', onResize);
					asyncDigestImmediate.remove(buildEllipsis);
					asyncDigestDebounced.remove(checkWindowForRebuild);
					if (unbindRefreshEllipsis) {
						unbindRefreshEllipsis();
						unbindRefreshEllipsis = null;
					}
				});

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


<commit_before>(function( angular ) {
  'use strict';

  angular.module('angular-humanize', []).
    filter('humanizeFilesize', function () {
      return function ( input ) {
        if ( isNaN(parseInt(input)) ) { return input; }
        return humanize.filesize(parseInt(input));
      };
    }).
    filter('humanizeOrdinal', function () {
      return function ( input ) {
        if ( parseInt(input) !== input ) { return input; }
        return humanize.ordinal(input);
      };
    }).
    filter('humanizeNaturalDay', function () {
      return function ( input ) {
        if ( parseInt(input) !== input ) { return input; }
        return humanize.naturalDay(input);
      };
    }).
    filter('humanizeRelativeTime', function () {
      return function ( input ) {
        if ( parseInt(input) !== input ) { return input; }
        return humanize.relativeTime(input);
      };
    });

}( angular ));
<commit_msg>Add decimals, decPoint and  thousandsSep params support in humanizeFilesize filter<commit_after>(function( angular ) {
  'use strict';

  angular.module('angular-humanize', []).
    filter('humanizeFilesize', function () {
      return function ( input, decimals, decPoint, thousandsSep ) {
        if ( isNaN(parseInt(input)) ) { return input; }
        return humanize.filesize(parseInt(input, decimals || 2, decPoint || '.', thousandsSep || ','));
      };
    }).
    filter('humanizeOrdinal', function () {
      return function ( input ) {
        if ( parseInt(input) !== input ) { return input; }
        return humanize.ordinal(input);
      };
    }).
    filter('humanizeNaturalDay', function () {
      return function ( input ) {
        if ( parseInt(input) !== input ) { return input; }
        return humanize.naturalDay(input);
      };
    }).
    filter('humanizeRelativeTime', function () {
      return function ( input ) {
        if ( parseInt(input) !== input ) { return input; }
        return humanize.relativeTime(input);
      };
    });

}( angular ));
<|endoftext|>


<commit_before>/*!
 * ${copyright}
 */

// Provides helper sap.ui.core.CustomStyleClassSupport
sap.ui.define(['jquery.sap.global', './Element'],
	function(jQuery, Element) {
	"use strict";

	/**
	 * Applies the support for custom style classes on the prototype of a sap.ui.core.Element.
	 *
	 * All controls (subclasses of sap.ui.core.Control) provide the support custom style classes. The control API provides functions
	 * to the application which allow it to add, remove or change style classes for the control.
	 * In general, this option is not available for elements because elements do not necessarily have a representation in the DOM.
	 *
	 * This function can be used by a control developer to explicitly enrich the API of his/her element implementation with the API functions
	 * for the custom style class support. It must be called on the prototype of the element.
	 *
	 * Usage Example:
	 *

	 * sap.ui.define(['sap/ui/core/Element', 'sap/ui/core/CustomStyleClassSupport'], function(Element, CustomStyleClassSupport) {
	 *    "use strict";
	 *    var MyElement = Element.extend("my.MyElement", {
	 *       metadata : {
	 *          //...
	 *       }
	 *       //...
	 *    });
	 *
	 *    CustomStyleClassSupport.apply(MyElement.prototype);
	 *
	 *    return MyElement;
	 * }, true);
	 *

	 *
	 * Furthermore, the function oRenderManager.writeClasses(oElement); ({@link sap.ui.core.RenderManager#writeClasses}) must be called within
	 * the renderer of the control to which the element belongs, when writing the root tag of the element. This ensures the classes are written to the HTML.
	 *
	 * This function adds the following functions to the elements prototype:
	 *

	 *
addStyleClass: {@link sap.ui.core.Control#addStyleClass}

	 *
removeStyleClass: {@link sap.ui.core.Control#removeStyleClass}

	 *
toggleStyleClass: {@link sap.ui.core.Control#toggleStyleClass}

	 *
hasStyleClass: {@link sap.ui.core.Control#hasStyleClass}

	 *

	 * In addition the clone function of the element is extended to ensure that the custom style classes are also available on the cloned element.
	 *
	 * Note: This function can only be used within control development. An application cannot add style class support on existing elements by calling this function.
	 *
	 * @public
	 * @alias sap.ui.core.CustomStyleClassSupport
	 * @function
	 */
	var CustomStyleClassSupport = function () {
		// "this" is the prototype now when called with apply()

		// Ensure only Elements are enhanced
		if (!(this instanceof Element)) {
			return;
		}

		// enrich original clone function
		var fOriginalClone = this.clone;
		this.clone = function() {
			// call original clone function
			var oClone = fOriginalClone.apply(this, arguments);

			// add the style classes of "this" to the clone
			if (this.aCustomStyleClasses) {
				oClone.aCustomStyleClasses = this.aCustomStyleClasses.slice();
			}
			return oClone;
		};

		this.addStyleClass = function(sStyleClass, bSuppressRerendering) { // bSuppressRerendering is experimental and hence undocumented
			jQuery.sap.assert(sStyleClass && typeof sStyleClass === "string", "sStyleClass must be a string");

			if (!this.aCustomStyleClasses) {
				this.aCustomStyleClasses = [];
			}
			if (sStyleClass) {
				// ensure the "class" attribute is not closed
				if (sStyleClass.indexOf("\"") > -1) {
					return this;
				}
				if (sStyleClass.indexOf("'") > -1) {
					return this;
				} // TODO: maybe check for quotes in different charsets or encodings

				// multiple calls should not add the class multiple times
				for (var i = this.aCustomStyleClasses.length - 1; i >= 0; i--) {
					if (this.aCustomStyleClasses[i] == sStyleClass) {
						return this;
					}
				}

				this.aCustomStyleClasses.push(sStyleClass);
				var oRoot = this.getDomRef();
				if (oRoot) { // non-rerendering shortcut
					jQuery(oRoot).addClass(sStyleClass);
				} else if (bSuppressRerendering === false) {
					this.invalidate();
				}
			}

			return this;
		};

		this.removeStyleClass = function(sStyleClass, bSuppressRerendering) { // bSuppressRerendering is experimental and hence undocumented
			jQuery.sap.assert(sStyleClass && typeof sStyleClass === "string", "sStyleClass must be a string");

			if (sStyleClass && this.aCustomStyleClasses) {
				for (var i = this.aCustomStyleClasses.length - 1; i >= 0; i--) {
					if (this.aCustomStyleClasses[i] == sStyleClass) {
						this.aCustomStyleClasses.splice(i, 1);
						var oRoot = this.getDomRef();
						if (oRoot) { // non-rerendering shortcut
							jQuery(oRoot).removeClass(sStyleClass);
						} else if (bSuppressRerendering === false) {
							this.invalidate();
						}
					}
				}
			}

			return this;
		};

		this.toggleStyleClass = function(sStyleClass, bAdd) {
			jQuery.sap.assert(sStyleClass && typeof sStyleClass === "string", "sStyleClass must be a string");

			if (sStyleClass && typeof sStyleClass === "string") {
				if (bAdd === true) {
					this.addStyleClass(sStyleClass);
				} else if (bAdd === false) {
					this.removeStyleClass(sStyleClass);
				} else if (bAdd === undefined) {
					this.hasStyleClass(sStyleClass) ? this.removeStyleClass(sStyleClass) : this.addStyleClass(sStyleClass);
				} else {
					jQuery.sap.log.warning(this.toString() + "- toggleStyleClass(): bAdd should be a boolean or undefined, but is '" + bAdd + "'");
				}
			}

			return this; // we could (depending on bAdd) return either this or the boolean result of removeStyleClass, but at least in the bAdd===undefined case the caller wouldn't even know which return type to expect...
		};

		this.hasStyleClass = function(sStyleClass) {
			jQuery.sap.assert(sStyleClass && typeof sStyleClass === "string", "sStyleClass must be a string");

			if (sStyleClass && this.aCustomStyleClasses) {
				for (var i = this.aCustomStyleClasses.length - 1; i >= 0; i--) {
					if (this.aCustomStyleClasses[i] == sStyleClass) {
						return true;
					}
				}
			}
			return false;
		};

		this.getMetadata().addPublicMethods(["addStyleClass", "removeStyleClass", "toggleStyleClass", "hasStyleClass"]);

	};

	// moved here to fix the cyclic dependency CustomStyleClassSupport, Element, Core, Control

	return CustomStyleClassSupport;

}, /* bExport= */ true);
<commit_msg>[FIX] CustomStyleClassSupport: throw assertions only for non-strings<commit_after>/*!
 * ${copyright}
 */

// Provides helper sap.ui.core.CustomStyleClassSupport
sap.ui.define(['jquery.sap.global', './Element'],
	function(jQuery, Element) {
	"use strict";

	/**
	 * Applies the support for custom style classes on the prototype of a sap.ui.core.Element.
	 *
	 * All controls (subclasses of sap.ui.core.Control) provide the support custom style classes. The control API provides functions
	 * to the application which allow it to add, remove or change style classes for the control.
	 * In general, this option is not available for elements because elements do not necessarily have a representation in the DOM.
	 *
	 * This function can be used by a control developer to explicitly enrich the API of his/her element implementation with the API functions
	 * for the custom style class support. It must be called on the prototype of the element.
	 *
	 * Usage Example:
	 *

	 * sap.ui.define(['sap/ui/core/Element', 'sap/ui/core/CustomStyleClassSupport'], function(Element, CustomStyleClassSupport) {
	 *    "use strict";
	 *    var MyElement = Element.extend("my.MyElement", {
	 *       metadata : {
	 *          //...
	 *       }
	 *       //...
	 *    });
	 *
	 *    CustomStyleClassSupport.apply(MyElement.prototype);
	 *
	 *    return MyElement;
	 * }, true);
	 *

	 *
	 * Furthermore, the function oRenderManager.writeClasses(oElement); ({@link sap.ui.core.RenderManager#writeClasses}) must be called within
	 * the renderer of the control to which the element belongs, when writing the root tag of the element. This ensures the classes are written to the HTML.
	 *
	 * This function adds the following functions to the elements prototype:
	 *

	 *
addStyleClass: {@link sap.ui.core.Control#addStyleClass}

	 *
removeStyleClass: {@link sap.ui.core.Control#removeStyleClass}

	 *
toggleStyleClass: {@link sap.ui.core.Control#toggleStyleClass}

	 *
hasStyleClass: {@link sap.ui.core.Control#hasStyleClass}

	 *

	 * In addition the clone function of the element is extended to ensure that the custom style classes are also available on the cloned element.
	 *
	 * Note: This function can only be used within control development. An application cannot add style class support on existing elements by calling this function.
	 *
	 * @public
	 * @alias sap.ui.core.CustomStyleClassSupport
	 * @function
	 */
	var CustomStyleClassSupport = function () {
		// "this" is the prototype now when called with apply()

		// Ensure only Elements are enhanced
		if (!(this instanceof Element)) {
			return;
		}

		// enrich original clone function
		var fOriginalClone = this.clone;
		this.clone = function() {
			// call original clone function
			var oClone = fOriginalClone.apply(this, arguments);

			// add the style classes of "this" to the clone
			if (this.aCustomStyleClasses) {
				oClone.aCustomStyleClasses = this.aCustomStyleClasses.slice();
			}
			return oClone;
		};

		this.addStyleClass = function(sStyleClass, bSuppressRerendering) { // bSuppressRerendering is experimental and hence undocumented
			jQuery.sap.assert(typeof sStyleClass === "string", "sStyleClass must be a string");

			if (!this.aCustomStyleClasses) {
				this.aCustomStyleClasses = [];
			}
			if (sStyleClass && typeof sStyleClass === "string") {
				// ensure the "class" attribute is not closed
				if (sStyleClass.indexOf("\"") > -1) {
					return this;
				}
				if (sStyleClass.indexOf("'") > -1) {
					return this;
				} // TODO: maybe check for quotes in different charsets or encodings

				// multiple calls should not add the class multiple times
				for (var i = this.aCustomStyleClasses.length - 1; i >= 0; i--) {
					if (this.aCustomStyleClasses[i] == sStyleClass) {
						return this;
					}
				}

				this.aCustomStyleClasses.push(sStyleClass);
				var oRoot = this.getDomRef();
				if (oRoot) { // non-rerendering shortcut
					jQuery(oRoot).addClass(sStyleClass);
				} else if (bSuppressRerendering === false) {
					this.invalidate();
				}
			}

			return this;
		};

		this.removeStyleClass = function(sStyleClass, bSuppressRerendering) { // bSuppressRerendering is experimental and hence undocumented
			jQuery.sap.assert(typeof sStyleClass === "string", "sStyleClass must be a string");

			if (sStyleClass && typeof sStyleClass === "string" && this.aCustomStyleClasses) {
				for (var i = this.aCustomStyleClasses.length - 1; i >= 0; i--) {
					if (this.aCustomStyleClasses[i] == sStyleClass) {
						this.aCustomStyleClasses.splice(i, 1);
						var oRoot = this.getDomRef();
						if (oRoot) { // non-rerendering shortcut
							jQuery(oRoot).removeClass(sStyleClass);
						} else if (bSuppressRerendering === false) {
							this.invalidate();
						}
					}
				}
			}

			return this;
		};

		this.toggleStyleClass = function(sStyleClass, bAdd) {
			jQuery.sap.assert(typeof sStyleClass === "string", "sStyleClass must be a string");

			if (sStyleClass && typeof sStyleClass === "string") {
				if (bAdd === true) {
					this.addStyleClass(sStyleClass);
				} else if (bAdd === false) {
					this.removeStyleClass(sStyleClass);
				} else if (bAdd === undefined) {
					this.hasStyleClass(sStyleClass) ? this.removeStyleClass(sStyleClass) : this.addStyleClass(sStyleClass);
				} else {
					jQuery.sap.log.warning(this.toString() + "- toggleStyleClass(): bAdd should be a boolean or undefined, but is '" + bAdd + "'");
				}
			}

			return this; // we could (depending on bAdd) return either this or the boolean result of removeStyleClass, but at least in the bAdd===undefined case the caller wouldn't even know which return type to expect...
		};

		this.hasStyleClass = function(sStyleClass) {
			jQuery.sap.assert(typeof sStyleClass === "string", "sStyleClass must be a string");

			if (sStyleClass && typeof sStyleClass === "string" && this.aCustomStyleClasses) {
				for (var i = this.aCustomStyleClasses.length - 1; i >= 0; i--) {
					if (this.aCustomStyleClasses[i] == sStyleClass) {
						return true;
					}
				}
			}
			return false;
		};

		this.getMetadata().addPublicMethods(["addStyleClass", "removeStyleClass", "toggleStyleClass", "hasStyleClass"]);

	};

	// moved here to fix the cyclic dependency CustomStyleClassSupport, Element, Core, Control

	return CustomStyleClassSupport;

}, /* bExport= */ true);
<|endoftext|>


<commit_before><commit_msg>Added dependencies<commit_after>const { webContents } = require('electron');
const { app, BrowserWindow } = require("electron");
window.$ = window.jQuery = require('jquery');

<|endoftext|>


<commit_before>H5.Bootstrapper = (function ($) {
    'use strict';

    var Bootstrapper = {
        build: buildApp,

        // controls - choose [0...n]
        keyBoard: addKeyBoard,
        gamePad: addGamePad,
        pointer: addPointer,
        wheel: addWheel,

        // system-services / device-events - choose [0...n]
        orientation: addScreenOrientation,
        visibility: addPageVisibility,
        fullScreen: addFullScreen,

        // rendering - choose [1]
        atlas: useAtlasRendering,
        fixedRezAtlas: useFixedRezAtlasRendering,
        image: useImageRendering,

        // screen (size) - choose [0...n]
        responsive: addResize,
        lowRez: addLowResolutionRendering,

        // font - choose [0|1]
        font: useFont,
        ejectaFont: useEjectaFont,

        // framework services - choose [0...n]
        analytics: addAnalytics,
        locales: useLocales,
        scenes: useH5Scenes,

        // audio - choose [0|1]
        webAudioSprite: useWebAudioSprite,
        htmlAudio: useHtmlAudio,
        htmlAudioSprite: useHtmlAudioSprite
    };

    // dependencies on screen, therefore flags because you need a screen first (build: screen -> features: with screen)
    var lowRezWidth;
    var lowRezHeight;
    var useLowRez = false;
    var useFullScreen = false;
    var usePointer = false;

    var events;
    var device;
    var removeKeyListener;
    var removeWheelListener;
    var noOneDidAnInit = true;
    var resourceLoadingQueue;

    function initBootstrap() {
        noOneDidAnInit = false;
        useLowRez = false;
        useFullScreen = false;
        usePointer = false;

        events = new $.EventBus();
        device = new $.Device($.userAgent, $.width, $.height, $.getDevicePixelRatio(), $.screenWidth, $.screenHeight);

        resourceLoadingQueue = [];
    }

    function buildApp(installMyScenes, optionalMyCustomResources, optionalCanvas) {
        if (noOneDidAnInit) {
            initBootstrap();
        }

        var screen = useLowRez ?
            $.installCanvas(events, device, optionalCanvas, $.width, $.height, $.getDevicePixelRatio(), lowRezWidth,
                lowRezHeight) :
            $.installCanvas(events, device, optionalCanvas, $.width, $.height, $.getDevicePixelRatio());

        if (useLowRez) {
            device.width = lowRezWidth;
            device.height = lowRezHeight;
            device.isLowRez = true;
        }

        if (useFullScreen) {
            var fs = $.installFullScreen(useLowRez ? screen.scaledScreen : screen.screen, events);
            device.requestFullScreen = fs.request.bind(fs);
            device.isFullScreen = fs.isFullScreen.bind(fs);
            device.isFullScreenSupported = fs.__isSupported.bind(fs);
            device.exitFullScreen = fs.exit.bind(device);
        }

        if (usePointer) {
            $.installPointer(events, device, useLowRez ? screen.scaledScreen : screen.screen);
        }

        var globalServices = {
            screen: screen.screen,
            events: events,
            device: device,
            scaledScreen: screen.scaledScreen
        };

        noOneDidAnInit = true;

        if (optionalMyCustomResources) {
            resourceLoadingQueue.push(optionalMyCustomResources);
        }

        return new $.App(globalServices, resourceLoadingQueue, installMyScenes, removeKeyListener, removeWheelListener);
    }

    function addLowResolutionRendering(width, height) {
        if (noOneDidAnInit) {
            initBootstrap();
        }

        lowRezWidth = width;
        lowRezHeight = height;
        useLowRez = true;
        return Bootstrapper;
    }

    function addScreenOrientation() {
        if (noOneDidAnInit) {
            initBootstrap();
        }

        $.installOrientation(events, device);
        device.lockOrientation = $.OrientationLock.lock;
        device.unlockOrientation = $.OrientationLock.unlock;
        return Bootstrapper;
    }

    function addPageVisibility() {
        if (noOneDidAnInit) {
            initBootstrap();
        }

        $.installVisibility(events, device);
        return Bootstrapper;
    }

    function addFullScreen() {
        if (noOneDidAnInit) {
            initBootstrap();
        }

        useFullScreen = true;
        return Bootstrapper;
    }

    /**
     * @callback mapResize
     * @param {Event} event
     * @returns {Promise} has to be called with adapted data
     */

    /**
     * @param {mapResize} [mapCanvasDimensions] resize callback function
     * @return {Bootstrapper} return this to chain calls
     */
    function addResize(mapCanvasDimensions) {
        if (!mapCanvasDimensions) {
            throw new $.Error('no resize callback function provided');
        }
        if (noOneDidAnInit) {
            initBootstrap();
        }

        $.installResize(events, device, mapCanvasDimensions);
        return Bootstrapper;
    }

    function addKeyBoard() {
        if (noOneDidAnInit) {
            initBootstrap();
        }

        removeKeyListener = $.installKeyBoard(events);
        return Bootstrapper;
    }

    function addWheel() {
        if (noOneDidAnInit) {
            initBootstrap();
        }

        removeWheelListener = $.installWheel(events);
        return Bootstrapper;
    }

    function addGamePad() {
        if (noOneDidAnInit) {
            initBootstrap();
        }

        $.installGamePad(events);
        return Bootstrapper;
    }

    function addPointer() {
        if (noOneDidAnInit) {
            initBootstrap();
        }

        usePointer = true;
        return Bootstrapper;
    }

    function addAnalytics(url, tenantCode, appKeyCode) {
        if (noOneDidAnInit) {
            initBootstrap();
        }

        $.installAnalytics(url, tenantCode, appKeyCode, events);
        return Bootstrapper;
    }

    function useAtlasRendering(registerPaths) {
        if (noOneDidAnInit) {
            initBootstrap();
        }
        $.AtlasLoader.register(registerPaths);
        resourceLoadingQueue.push($.AtlasLoader);
        return Bootstrapper;
    }

    function useEjectaFont(path, name) {
        if (noOneDidAnInit) {
            initBootstrap();
        }
        $.EjectaFontLoader.register(path, name);
        resourceLoadingQueue.push($.EjectaFontLoader);
        return Bootstrapper;
    }

    function useFixedRezAtlasRendering(width, height, optionalBaseName, optionalGfxPath, optionalDataPath,
        optionalGfxExtension, optionalDataExtension) {
        if (noOneDidAnInit) {
            initBootstrap();
        }
        $.FixedRezAtlasLoader.register(width, height, optionalBaseName, optionalGfxPath, optionalDataPath,
            optionalGfxExtension, optionalDataExtension);
        resourceLoadingQueue.push($.FixedRezAtlasLoader);
        return Bootstrapper;
    }

    function useFont(path, name) {
        if (noOneDidAnInit) {
            initBootstrap();
        }
        $.FontLoader.register(path, name);
        resourceLoadingQueue.push($.FontLoader);
        return Bootstrapper;
    }

    function useHtmlAudio(soundNamesToPathsDict, optionalPath, optionalExtension) {
        if (noOneDidAnInit) {
            initBootstrap();
        }
        $.HtmlAudioLoader.register(soundNamesToPathsDict, optionalPath, optionalExtension);
        resourceLoadingQueue.push($.HtmlAudioLoader);
        return Bootstrapper;
    }

    function useHtmlAudioSprite(musicInfoPath, musicPath, sfxInfoPath, sfxPath, sfxTrackCount) {
        if (noOneDidAnInit) {
            initBootstrap();
        }
        $.HtmlAudioSpriteLoader.register(musicInfoPath, musicPath, sfxInfoPath, sfxPath, sfxTrackCount);
        resourceLoadingQueue.push($.HtmlAudioSpriteLoader);
        return Bootstrapper;
    }

    function useImageRendering(notImplementedYet) {
        if (noOneDidAnInit) {
            initBootstrap();
        }
        $.ImageLoader.register(notImplementedYet);
        resourceLoadingQueue.push($.ImageLoader);
        return Bootstrapper;
    }

    function useLocales(path) {
        if (noOneDidAnInit) {
            initBootstrap();
        }
        $.LocalesLoader.register(path);
        resourceLoadingQueue.push($.LocalesLoader);
        return Bootstrapper;
    }

    function useH5Scenes(path) {
        if (noOneDidAnInit) {
            initBootstrap();
        }
        $.SceneLoader.register(path);
        resourceLoadingQueue.push($.SceneLoader);
        return Bootstrapper;
    }

    function useWebAudioSprite(musicInfoPath, musicPath, sfxInfoPath, sfxPath) {
        if (noOneDidAnInit) {
            initBootstrap();
        }
        $.WebAudioSpriteLoader.register(musicInfoPath, musicPath, sfxInfoPath, sfxPath);
        resourceLoadingQueue.push($.WebAudioSpriteLoader);
        return Bootstrapper;
    }

    return Bootstrapper;
})({
    installCanvas: H5.installCanvas,
    installResize: H5.installResize,
    installKeyBoard: H5.installKeyBoard,
    installWheel: H5.installWheel,
    installGamePad: H5.installGamePad,
    installOrientation: H5.installOrientation,
    installFullScreen: H5.installFullScreen,
    installPointer: H5.installPointer,
    installVisibility: H5.installVisibility,
    installAnalytics: H5.installHolmes,
    App: H5.App,
    EventBus: H5.EventBus,
    Device: H5.Device,
    width: window.innerWidth,
    height: window.innerHeight,
    screenWidth: window.screen.availWidth,
    screenHeight: window.screen.availHeight,
    getDevicePixelRatio: H5.getDevicePixelRatio,
    OrientationLock: H5.OrientationLock,
    userAgent: window.navigator.userAgent,
    AtlasLoader: H5.AtlasLoader,
    EjectaFontLoader: H5.EjectaFontLoader,
    FixedRezAtlasLoader: H5.FixedRezAtlasLoader,
    FontLoader: H5.FontLoader,
    HtmlAudioLoader: H5.HtmlAudioLoader,
    HtmlAudioSpriteLoader: H5.HtmlAudioSpriteLoader,
    ImageLoader: H5.ImageLoader,
    LocalesLoader: H5.LocalesLoader,
    SceneLoader: H5.SceneLoader,
    WebAudioSpriteLoader: H5.WebAudioSpriteLoader,
    Error: Error
});
<commit_msg>remove check for param, because main use case is to provide no param at all<commit_after>H5.Bootstrapper = (function ($) {
    'use strict';

    var Bootstrapper = {
        build: buildApp,

        // controls - choose [0...n]
        keyBoard: addKeyBoard,
        gamePad: addGamePad,
        pointer: addPointer,
        wheel: addWheel,

        // system-services / device-events - choose [0...n]
        orientation: addScreenOrientation,
        visibility: addPageVisibility,
        fullScreen: addFullScreen,

        // rendering - choose [1]
        atlas: useAtlasRendering,
        fixedRezAtlas: useFixedRezAtlasRendering,
        image: useImageRendering,

        // screen (size) - choose [0...n]
        responsive: addResize,
        lowRez: addLowResolutionRendering,

        // font - choose [0|1]
        font: useFont,
        ejectaFont: useEjectaFont,

        // framework services - choose [0...n]
        analytics: addAnalytics,
        locales: useLocales,
        scenes: useH5Scenes,

        // audio - choose [0|1]
        webAudioSprite: useWebAudioSprite,
        htmlAudio: useHtmlAudio,
        htmlAudioSprite: useHtmlAudioSprite
    };

    // dependencies on screen, therefore flags because you need a screen first (build: screen -> features: with screen)
    var lowRezWidth;
    var lowRezHeight;
    var useLowRez = false;
    var useFullScreen = false;
    var usePointer = false;

    var events;
    var device;
    var removeKeyListener;
    var removeWheelListener;
    var noOneDidAnInit = true;
    var resourceLoadingQueue;

    function initBootstrap() {
        noOneDidAnInit = false;
        useLowRez = false;
        useFullScreen = false;
        usePointer = false;

        events = new $.EventBus();
        device = new $.Device($.userAgent, $.width, $.height, $.getDevicePixelRatio(), $.screenWidth, $.screenHeight);

        resourceLoadingQueue = [];
    }

    function buildApp(installMyScenes, optionalMyCustomResources, optionalCanvas) {
        if (noOneDidAnInit) {
            initBootstrap();
        }

        var screen = useLowRez ?
            $.installCanvas(events, device, optionalCanvas, $.width, $.height, $.getDevicePixelRatio(), lowRezWidth,
                lowRezHeight) :
            $.installCanvas(events, device, optionalCanvas, $.width, $.height, $.getDevicePixelRatio());

        if (useLowRez) {
            device.width = lowRezWidth;
            device.height = lowRezHeight;
            device.isLowRez = true;
        }

        if (useFullScreen) {
            var fs = $.installFullScreen(useLowRez ? screen.scaledScreen : screen.screen, events);
            device.requestFullScreen = fs.request.bind(fs);
            device.isFullScreen = fs.isFullScreen.bind(fs);
            device.isFullScreenSupported = fs.__isSupported.bind(fs);
            device.exitFullScreen = fs.exit.bind(device);
        }

        if (usePointer) {
            $.installPointer(events, device, useLowRez ? screen.scaledScreen : screen.screen);
        }

        var globalServices = {
            screen: screen.screen,
            events: events,
            device: device,
            scaledScreen: screen.scaledScreen
        };

        noOneDidAnInit = true;

        if (optionalMyCustomResources) {
            resourceLoadingQueue.push(optionalMyCustomResources);
        }

        return new $.App(globalServices, resourceLoadingQueue, installMyScenes, removeKeyListener, removeWheelListener);
    }

    function addLowResolutionRendering(width, height) {
        if (noOneDidAnInit) {
            initBootstrap();
        }

        lowRezWidth = width;
        lowRezHeight = height;
        useLowRez = true;
        return Bootstrapper;
    }

    function addScreenOrientation() {
        if (noOneDidAnInit) {
            initBootstrap();
        }

        $.installOrientation(events, device);
        device.lockOrientation = $.OrientationLock.lock;
        device.unlockOrientation = $.OrientationLock.unlock;
        return Bootstrapper;
    }

    function addPageVisibility() {
        if (noOneDidAnInit) {
            initBootstrap();
        }

        $.installVisibility(events, device);
        return Bootstrapper;
    }

    function addFullScreen() {
        if (noOneDidAnInit) {
            initBootstrap();
        }

        useFullScreen = true;
        return Bootstrapper;
    }

    /**
     * @callback mapResize
     * @param {Event} event
     * @returns {Promise} has to be called with adapted data
     */

    /**
     * @param {mapResize} [mapCanvasDimensions] resize callback function
     * @return {Bootstrapper} return this to chain calls
     */
    function addResize(mapCanvasDimensions) {
        if (noOneDidAnInit) {
            initBootstrap();
        }

        $.installResize(events, device, mapCanvasDimensions);
        return Bootstrapper;
    }

    function addKeyBoard() {
        if (noOneDidAnInit) {
            initBootstrap();
        }

        removeKeyListener = $.installKeyBoard(events);
        return Bootstrapper;
    }

    function addWheel() {
        if (noOneDidAnInit) {
            initBootstrap();
        }

        removeWheelListener = $.installWheel(events);
        return Bootstrapper;
    }

    function addGamePad() {
        if (noOneDidAnInit) {
            initBootstrap();
        }

        $.installGamePad(events);
        return Bootstrapper;
    }

    function addPointer() {
        if (noOneDidAnInit) {
            initBootstrap();
        }

        usePointer = true;
        return Bootstrapper;
    }

    function addAnalytics(url, tenantCode, appKeyCode) {
        if (noOneDidAnInit) {
            initBootstrap();
        }

        $.installAnalytics(url, tenantCode, appKeyCode, events);
        return Bootstrapper;
    }

    function useAtlasRendering(registerPaths) {
        if (noOneDidAnInit) {
            initBootstrap();
        }
        $.AtlasLoader.register(registerPaths);
        resourceLoadingQueue.push($.AtlasLoader);
        return Bootstrapper;
    }

    function useEjectaFont(path, name) {
        if (noOneDidAnInit) {
            initBootstrap();
        }
        $.EjectaFontLoader.register(path, name);
        resourceLoadingQueue.push($.EjectaFontLoader);
        return Bootstrapper;
    }

    function useFixedRezAtlasRendering(width, height, optionalBaseName, optionalGfxPath, optionalDataPath,
        optionalGfxExtension, optionalDataExtension) {
        if (noOneDidAnInit) {
            initBootstrap();
        }
        $.FixedRezAtlasLoader.register(width, height, optionalBaseName, optionalGfxPath, optionalDataPath,
            optionalGfxExtension, optionalDataExtension);
        resourceLoadingQueue.push($.FixedRezAtlasLoader);
        return Bootstrapper;
    }

    function useFont(path, name) {
        if (noOneDidAnInit) {
            initBootstrap();
        }
        $.FontLoader.register(path, name);
        resourceLoadingQueue.push($.FontLoader);
        return Bootstrapper;
    }

    function useHtmlAudio(soundNamesToPathsDict, optionalPath, optionalExtension) {
        if (noOneDidAnInit) {
            initBootstrap();
        }
        $.HtmlAudioLoader.register(soundNamesToPathsDict, optionalPath, optionalExtension);
        resourceLoadingQueue.push($.HtmlAudioLoader);
        return Bootstrapper;
    }

    function useHtmlAudioSprite(musicInfoPath, musicPath, sfxInfoPath, sfxPath, sfxTrackCount) {
        if (noOneDidAnInit) {
            initBootstrap();
        }
        $.HtmlAudioSpriteLoader.register(musicInfoPath, musicPath, sfxInfoPath, sfxPath, sfxTrackCount);
        resourceLoadingQueue.push($.HtmlAudioSpriteLoader);
        return Bootstrapper;
    }

    function useImageRendering(notImplementedYet) {
        if (noOneDidAnInit) {
            initBootstrap();
        }
        $.ImageLoader.register(notImplementedYet);
        resourceLoadingQueue.push($.ImageLoader);
        return Bootstrapper;
    }

    function useLocales(path) {
        if (noOneDidAnInit) {
            initBootstrap();
        }
        $.LocalesLoader.register(path);
        resourceLoadingQueue.push($.LocalesLoader);
        return Bootstrapper;
    }

    function useH5Scenes(path) {
        if (noOneDidAnInit) {
            initBootstrap();
        }
        $.SceneLoader.register(path);
        resourceLoadingQueue.push($.SceneLoader);
        return Bootstrapper;
    }

    function useWebAudioSprite(musicInfoPath, musicPath, sfxInfoPath, sfxPath) {
        if (noOneDidAnInit) {
            initBootstrap();
        }
        $.WebAudioSpriteLoader.register(musicInfoPath, musicPath, sfxInfoPath, sfxPath);
        resourceLoadingQueue.push($.WebAudioSpriteLoader);
        return Bootstrapper;
    }

    return Bootstrapper;
})({
    installCanvas: H5.installCanvas,
    installResize: H5.installResize,
    installKeyBoard: H5.installKeyBoard,
    installWheel: H5.installWheel,
    installGamePad: H5.installGamePad,
    installOrientation: H5.installOrientation,
    installFullScreen: H5.installFullScreen,
    installPointer: H5.installPointer,
    installVisibility: H5.installVisibility,
    installAnalytics: H5.installHolmes,
    App: H5.App,
    EventBus: H5.EventBus,
    Device: H5.Device,
    width: window.innerWidth,
    height: window.innerHeight,
    screenWidth: window.screen.availWidth,
    screenHeight: window.screen.availHeight,
    getDevicePixelRatio: H5.getDevicePixelRatio,
    OrientationLock: H5.OrientationLock,
    userAgent: window.navigator.userAgent,
    AtlasLoader: H5.AtlasLoader,
    EjectaFontLoader: H5.EjectaFontLoader,
    FixedRezAtlasLoader: H5.FixedRezAtlasLoader,
    FontLoader: H5.FontLoader,
    HtmlAudioLoader: H5.HtmlAudioLoader,
    HtmlAudioSpriteLoader: H5.HtmlAudioSpriteLoader,
    ImageLoader: H5.ImageLoader,
    LocalesLoader: H5.LocalesLoader,
    SceneLoader: H5.SceneLoader,
    WebAudioSpriteLoader: H5.WebAudioSpriteLoader,
    Error: Error
});
<|endoftext|>


<commit_before>define([
    'dijit/_TemplatedMixin',
    'dijit/_WidgetBase',
    'dijit/_WidgetsInTemplateMixin',

    'dojo/_base/array',
    'dojo/_base/declare',
    'dojo/text!app/templates/ResultsPanel.html',

    'dojox/charting/Chart',
    'dojox/charting/plot2d/Pie',
    'dojox/charting/themes/PlotKit/green',
    'xstyle/css!app/resources/ResultsPanel.css'
], function(
    _TemplatedMixin,
    _WidgetBase,
    _WidgetsInTemplateMixin,

    array,
    declare,
    template,

    Chart,
    Pie,
    green
) {
    return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
        // description:
        //      The panel to show graphs charts results from the query

        templateString: template,
        baseClass: 'results-panel',
        widgetsInTemplate: true,

        // Properties to be sent into constructor

        postCreate: function() {
            // summary:
            //      Overrides method of same name in dijit._Widget.
            // tags:
            //      private
            console.log('app.ResultsPanel::postCreate', arguments);

            this.setupConnections();

            this.charts = [
                this.buildChart(this.report1Node),
                this.buildChart(this.report2Node),
                this.buildChart(this.report3Node)
            ];

            this.inherited(arguments);
        },
        setupConnections: function() {
            // summary:
            //      wire events, and such
            //
            console.log('app.ResultsPanel::setupConnections', arguments);
        },
        showCharts: function() {
            // summary:
            //      description
            // params
            console.log('app.ResultsPanel::showCharts', arguments);
        },
        buildChart: function(node) {
            // summary:
            //      builds a chart around a node
            // node
            console.log('app.ResulstPanel::buildChart', arguments);

            // Create the chart within it's 'holding' node

            var chartData = [{
                x: 1,
                y: 19021
            }, {
                x: 1,
                y: 12837
            }, {
                x: 1,
                y: 12378
            }, {
                x: 1,
                y: 21882
            }, {
                x: 1,
                y: 17654
            }, {
                x: 1,
                y: 15833
            }, {
                x: 1,
                y: 16122
            }];

            var pieChart = new Chart(node);

            // Set the theme
            green.chart.fill = green.plotarea.fill = '#fff';
            pieChart.setTheme(green);

            // Add the only/default plot
            pieChart.addPlot('default', {
                type: Pie, // our plot2d/Pie module reference as type value
                radius: 200,
                fontColor: 'black',
                labelOffset: -20
            });

            // Add the series of data
            pieChart.addSeries('January', chartData);

            this.own(pieChart);

            return pieChart;
        },
        startup: function() {
            // summary:
            //      startup for rendering
            //
            console.log('app.ResultsPanel::startup', arguments);

            array.forEach(this.charts, function(chart){
                chart.render();
            }, this);
        }
    });
});<commit_msg>fix test page<commit_after>define([
    'dijit/_TemplatedMixin',
    'dijit/_WidgetBase',

    'dojo/_base/array',
    'dojo/_base/declare',
    'dojo/text!app/templates/ResultsPanel.html',

    'dojox/charting/Chart',
    'dojox/charting/plot2d/Pie',
    'dojox/charting/themes/PlotKit/green',

    'xstyle/css!app/resources/ResultsPanel.css'
], function(
    _TemplatedMixin,
    _WidgetBase,

    array,
    declare,
    template,

    Chart,
    Pie,
    green
) {
    return declare([_WidgetBase, _TemplatedMixin], {
        // description:
        //      The panel to show graphs charts results from the query

        templateString: template,
        baseClass: 'results-panel',

        // Properties to be sent into constructor

        postCreate: function() {
            // summary:
            //      Overrides method of same name in dijit._Widget.
            // tags:
            //      private
            console.log('app.ResultsPanel::postCreate', arguments);

            this.setupConnections();

            this.charts = [
                this.buildChart(this.report1Node),
                this.buildChart(this.report2Node),
                this.buildChart(this.report3Node)
            ];

            this.inherited(arguments);
        },
        setupConnections: function() {
            // summary:
            //      wire events, and such
            //
            console.log('app.ResultsPanel::setupConnections', arguments);
        },
        showCharts: function() {
            // summary:
            //      description
            // params
            console.log('app.ResultsPanel::showCharts', arguments);
        },
        buildChart: function(node) {
            // summary:
            //      builds a chart around a node
            // node
            console.log('app.ResulstPanel::buildChart', arguments);

            // Create the chart within it's 'holding' node

            var chartData = [{
                x: 1,
                y: 19021
            }, {
                x: 1,
                y: 12837
            }, {
                x: 1,
                y: 12378
            }, {
                x: 1,
                y: 21882
            }, {
                x: 1,
                y: 17654
            }, {
                x: 1,
                y: 15833
            }, {
                x: 1,
                y: 16122
            }];

            var pieChart = new Chart(node);

            // Set the theme
            green.chart.fill = green.plotarea.fill = '#fff';
            pieChart.setTheme(green);

            // Add the only/default plot
            pieChart.addPlot('default', {
                type: Pie, // our plot2d/Pie module reference as type value
                radius: 200,
                fontColor: 'black',
                labelOffset: -20
            });

            // Add the series of data
            pieChart.addSeries('January', chartData);

            this.own(pieChart);

            return pieChart;
        },
        startup: function() {
            // summary:
            //      startup for rendering
            //
            console.log('app.ResultsPanel::startup', arguments);

            array.forEach(this.charts, function(chart){
                chart.render();
            }, this);
        }
    });
});<|endoftext|>


<commit_before>(function() {
  // TODO(sissel): Write something that will use history.pushState and fall back
  // to document.location.hash madness.

  var logstash = {
    params: {
      offset: 0,
      count: 50,
    },

    search: function(query, options) {
      if (query == undefined || query == "") {
        return;
      }

      /* Default options */
      if (typeof(options) == 'undefined') {
        options = { graph: true };
      }

      var display_query = query.replace("<", "<").replace(">", ">")
      $("#querystatus, #results h1").html("Loading query '" + display_query + "' (offset:" + logstash.params.offset + ", count:" + logstash.params.count + ") ")
      //console.log(logstash.params)
      logstash.params.q = query;
      document.location.hash = escape(JSON.stringify(logstash.params));

      /* Load the search results */
      $("#results").load("/api/search?format=html", logstash.params);

      if (options.graph != false) {
        /* Load the default histogram graph */
        jQuery.getJSON("/api/histogram", logstash.params, function(histogram, text, jqxhr) {
          /* Load the data into the graph */
          flot_data = [];
          // histogram is an array of { "key": ..., "count": ... }
          for (var i in histogram) {
            flot_data.push([parseInt(histogram[i]["key"]), histogram[i]["count"]])
          }

          logstash.plot(flot_data);
        });
      } /* if options.graph != false */
      $("#query").val(logstash.params.q);
    }, /* search */

    parse_params: function(href) {
      var query = href.replace(/^[^?]*\?/, "");
      if (query == href) {
        //console.log("No query params in link " + href);
        /* No query params */
        return {};
      }

      //console.log({ "query": query });
      var param_list = query.split("&");
      params = {};
      //console.log({ "Parsed params": params });
      for (var p in param_list) {
        var a = param_list[p].split("=");
        var key = a[0];
        var value = a[1];
        params[key] = unescape(value);
      }
      return params;
    },

    appendquery: function(query) {
      var newquery = $("#query").val();
      newquery += " " + query;
      logstash.search(newquery.trim());
    }, /* appendquery */

    plot: function(data) {
      var target = $("#visual");
      target.css("display", "block");
      var plot = $.plot(target,
        [ {  /* data */
            data: data,
            bars: {
              show: true,
              barWidth: 3600000,
            }
        } ],
        { /* options */
          xaxis: { mode: "time" },
          grid: { hoverable: true, clickable: true },
        }
      );

      target.bind("plotclick", function(e, pos, item) {
        if (item) {
          start = logstash.ms_to_iso8601(item.datapoint[0]);
          end = logstash.ms_to_iso8601(item.datapoint[0] + 3600000);

          logstash.appendquery("@timestamp:[" + start + " TO " + end + "]");
        }
      });
    }, /* plot */

    ms_to_iso8601: function(milliseconds) {
      /* From:
       * https://developer.mozilla.org/en/JavaScript/Reference/global_objects/date#Example.3a_ISO_8601_formatted_dates
       */
      var d = new Date(milliseconds);
      function pad(n){return n<10 ? '0'+n : n}
      return d.getUTCFullYear()+'-'
        + pad(d.getUTCMonth()+1)+'-'
        + pad(d.getUTCDate())+'T'
        + pad(d.getUTCHours())+':'
        + pad(d.getUTCMinutes())+':'
        + pad(d.getUTCSeconds())+'Z'
    },
  }; /* logstash */

  window.logstash = logstash;

  $().ready(function() {
    if (location.hash.length > 1) {
      try {
        logstash.params = JSON.parse(unescape(location.hash.substring(1)));
      } catch (e) {
        // Do nothing
      }
      logstash.search(logstash.params.q);
    } else {
      /* No hash. See if there's a query param. */
      var params = logstash.parse_params(location.href);
      //console.log(params)
      for (var p in params) {
        logstash.params[p] = params[p];
      }
      logstash.search(logstash.params.q)
    }

    $(window).hashchange(function() {
      logstash.params = JSON.parse(unescape(location.hash.substring(1)));
      query = logstash.params.q
      if (query != $("#query").val()) {
        scroll(0, 0);
        logstash.search(query);
      }
    });

    $("a.pager, a.querychanger").live("click", function() {
      /* TODO(sissel): Allow 'control click' and 'middle click' to act normally */
      var href = $(this).attr("href");
      var params = logstash.parse_params(href);
      for (var p in params) {
        logstash.params[p] = params[p];
      }
      logstash.search(logstash.params.q, { graph: false })
      return false;
    });

    var result_row_selector = "table.results tr.event";
    $(result_row_selector).live("click", function() {
      var data = $("td.message", this).data("full");
      if (typeof(data) == "string") {
        data = JSON.parse(data);
      }

      /* Apply template to the dialog */
      var query = $("#query").val().replace(/^\s+|\s+$/g, "")
      var sanitize = function(str) {
        if (!/^".*"$/.test(str)) {
          str = '"' + str + '"';
        }
        return escape(str);
      };

      var template = $.template("inspector",
        "
" +
          "(${type}) ${field}:" +
          "{{each(idx, val) value}}" +
            "" +
              "${val}" +
            ", " +
          "{{/each}}" +
        "
");

      /* TODO(sissel): recurse through the data */
      var fields = new Array();
      for (var i in data["@fields"]) {
        var value = data["@fields"][i]
        if (/^[, ]*$/.test(value)) {
          continue; /* Skip empty data fields */
        }
        if (!(value instanceof Array)) {
          value = [value];
        }
        fields.push( { type: "field", field: i, value: value })
      }

      for (var i in data) {
        if (i == "@fields") continue;
        var value = data[i]
        if (!(value instanceof Array)) {
          value = [value];
        }

        if (i.charAt(0) == "@") { /* metadata */
          fields.push( { type: "metadata", field: i, value: value });
        } else { /* data */
          if (/^[, ]*$/.test(value)) {
            continue; /* Skip empty data fields */
          }
          fields.push( { type: "field", field: i, value: value })
        }
      }

      for (var i in data) {
        if (i == "_source") {
          continue; /* already processed this one */
        }
        value = data[i]
        if (!(value instanceof Array)) {
          value = [value];
        }
        fields.push( { type: "metadata", field: i, value: value })
      }

      fields.sort(function(a, b) {
        if (a.type+a.field  b.type+b.field) { return 1; }
        return 0;
      });

      $(result_row_selector).removeClass("selected")
      $(this).addClass("selected");
      var entry = this;
      $("#inspector li").remove()
      $("#inspector")
        .append($.tmpl("inspector", fields, { "sanitize": sanitize }))
        .dialog({
          width: 400,
          title: "Fields for this log" ,
          closeOnEscape: true,
          position: ["right", "top"],
        });
    });

    $("#inspector li a").live("click", function(ev) {
      var field = $(this).data("field");
      var value = $(this).data("value");
      var query = $("#query");
      var newcondition = unescape(field) + ":" + unescape(value);

      var newquery = query.val();
      if (ev.shiftKey) {
        // Shift-click will make a "and not" condition
        query.val(newquery + " -" + newcondition)
      } else {
        query.val(newquery + " " + newcondition)
      }
      logstash.search(query.val())
      return false;
    });

    $("#searchbutton").bind("click submit", function(ev) {
      var query = $("#query").val().replace(/^\s+|\s+$/g, "")
      /* Search now, we pressed the submit button */
      logstash.search(query)
      return false;
    });
  }); /* $().ready */
})(); /* function scoping */
<commit_msg>- Reset search offset when drilling into the histogram<commit_after>(function() {
  // TODO(sissel): Write something that will use history.pushState and fall back
  // to document.location.hash madness.

  var logstash = {
    params: {
      offset: 0,
      count: 50,
    },

    search: function(query, options) {
      if (query == undefined || query == "") {
        return;
      }

      /* Default options */
      if (typeof(options) == 'undefined') {
        options = { graph: true };
      }

      var display_query = query.replace("<", "<").replace(">", ">")
      $("#querystatus, #results h1").html("Loading query '" + display_query + "' (offset:" + logstash.params.offset + ", count:" + logstash.params.count + ") ")
      //console.log(logstash.params)
      logstash.params.q = query;
      document.location.hash = escape(JSON.stringify(logstash.params));

      /* Load the search results */
      $("#results").load("/api/search?format=html", logstash.params);

      if (options.graph != false) {
        /* Load the default histogram graph */
        jQuery.getJSON("/api/histogram", logstash.params, function(histogram, text, jqxhr) {
          /* Load the data into the graph */
          flot_data = [];
          // histogram is an array of { "key": ..., "count": ... }
          for (var i in histogram) {
            flot_data.push([parseInt(histogram[i]["key"]), histogram[i]["count"]])
          }

          logstash.plot(flot_data);
        });
      } /* if options.graph != false */
      $("#query").val(logstash.params.q);
    }, /* search */

    parse_params: function(href) {
      var query = href.replace(/^[^?]*\?/, "");
      if (query == href) {
        //console.log("No query params in link " + href);
        /* No query params */
        return {};
      }

      //console.log({ "query": query });
      var param_list = query.split("&");
      params = {};
      //console.log({ "Parsed params": params });
      for (var p in param_list) {
        var a = param_list[p].split("=");
        var key = a[0];
        var value = a[1];
        params[key] = unescape(value);
      }
      return params;
    },

    appendquery: function(query) {
      var newquery = $("#query").val();
      newquery += " " + query;
      logstash.search(newquery.trim());
    }, /* appendquery */

    plot: function(data) {
      var target = $("#visual");
      target.css("display", "block");
      var plot = $.plot(target,
        [ {  /* data */
            data: data,
            bars: {
              show: true,
              barWidth: 3600000,
            }
        } ],
        { /* options */
          xaxis: { mode: "time" },
          grid: { hoverable: true, clickable: true },
        }
      );

      target.bind("plotclick", function(e, pos, item) {
        if (item) {
          start = logstash.ms_to_iso8601(item.datapoint[0]);
          end = logstash.ms_to_iso8601(item.datapoint[0] + 3600000);

          /* Clicking on the graph means a new search, means
           * we probably don't want to keep the old offset since
           * the search results will change. */
          logstash.params.offset = 0;
          logstash.appendquery("@timestamp:[" + start + " TO " + end + "]");
        }
      });
    }, /* plot */

    ms_to_iso8601: function(milliseconds) {
      /* From:
       * https://developer.mozilla.org/en/JavaScript/Reference/global_objects/date#Example.3a_ISO_8601_formatted_dates
       */
      var d = new Date(milliseconds);
      function pad(n){return n<10 ? '0'+n : n}
      return d.getUTCFullYear()+'-'
        + pad(d.getUTCMonth()+1)+'-'
        + pad(d.getUTCDate())+'T'
        + pad(d.getUTCHours())+':'
        + pad(d.getUTCMinutes())+':'
        + pad(d.getUTCSeconds())+'Z'
    },
  }; /* logstash */

  window.logstash = logstash;

  $().ready(function() {
    if (location.hash.length > 1) {
      try {
        logstash.params = JSON.parse(unescape(location.hash.substring(1)));
      } catch (e) {
        // Do nothing
      }
      logstash.search(logstash.params.q);
    } else {
      /* No hash. See if there's a query param. */
      var params = logstash.parse_params(location.href);
      //console.log(params)
      for (var p in params) {
        logstash.params[p] = params[p];
      }
      logstash.search(logstash.params.q)
    }

    $(window).hashchange(function() {
      logstash.params = JSON.parse(unescape(location.hash.substring(1)));
      query = logstash.params.q
      if (query != $("#query").val()) {
        scroll(0, 0);
        logstash.search(query);
      }
    });

    $("a.pager, a.querychanger").live("click", function() {
      /* TODO(sissel): Allow 'control click' and 'middle click' to act normally */
      var href = $(this).attr("href");
      var params = logstash.parse_params(href);
      for (var p in params) {
        logstash.params[p] = params[p];
      }
      logstash.search(logstash.params.q, { graph: false })
      return false;
    });

    var result_row_selector = "table.results tr.event";
    $(result_row_selector).live("click", function() {
      var data = $("td.message", this).data("full");
      if (typeof(data) == "string") {
        data = JSON.parse(data);
      }

      /* Apply template to the dialog */
      var query = $("#query").val().replace(/^\s+|\s+$/g, "")
      var sanitize = function(str) {
        if (!/^".*"$/.test(str)) {
          str = '"' + str + '"';
        }
        return escape(str);
      };

      var template = $.template("inspector",
        "
" +
          "(${type}) ${field}:" +
          "{{each(idx, val) value}}" +
            "" +
              "${val}" +
            ", " +
          "{{/each}}" +
        "
");

      /* TODO(sissel): recurse through the data */
      var fields = new Array();
      for (var i in data["@fields"]) {
        var value = data["@fields"][i]
        if (/^[, ]*$/.test(value)) {
          continue; /* Skip empty data fields */
        }
        if (!(value instanceof Array)) {
          value = [value];
        }
        fields.push( { type: "field", field: i, value: value })
      }

      for (var i in data) {
        if (i == "@fields") continue;
        var value = data[i]
        if (!(value instanceof Array)) {
          value = [value];
        }

        if (i.charAt(0) == "@") { /* metadata */
          fields.push( { type: "metadata", field: i, value: value });
        } else { /* data */
          if (/^[, ]*$/.test(value)) {
            continue; /* Skip empty data fields */
          }
          fields.push( { type: "field", field: i, value: value })
        }
      }

      for (var i in data) {
        if (i == "_source") {
          continue; /* already processed this one */
        }
        value = data[i]
        if (!(value instanceof Array)) {
          value = [value];
        }
        fields.push( { type: "metadata", field: i, value: value })
      }

      fields.sort(function(a, b) {
        if (a.type+a.field  b.type+b.field) { return 1; }
        return 0;
      });

      $(result_row_selector).removeClass("selected")
      $(this).addClass("selected");
      var entry = this;
      $("#inspector li").remove()
      $("#inspector")
        .append($.tmpl("inspector", fields, { "sanitize": sanitize }))
        .dialog({
          width: 400,
          title: "Fields for this log" ,
          closeOnEscape: true,
          position: ["right", "top"],
        });
    });

    $("#inspector li a").live("click", function(ev) {
      var field = $(this).data("field");
      var value = $(this).data("value");
      var query = $("#query");
      var newcondition = unescape(field) + ":" + unescape(value);

      var newquery = query.val();
      if (ev.shiftKey) {
        // Shift-click will make a "and not" condition
        query.val(newquery + " -" + newcondition)
      } else {
        query.val(newquery + " " + newcondition)
      }
      logstash.search(query.val())
      return false;
    });

    $("#searchbutton").bind("click submit", function(ev) {
      var query = $("#query").val().replace(/^\s+|\s+$/g, "")
      /* Search now, we pressed the submit button */
      logstash.search(query)
      return false;
    });
  }); /* $().ready */
})(); /* function scoping */
<|endoftext|>