<commit_before>define([
	"intern!object",
	"intern/chai!assert",
	"dojo/Deferred",
	"deliteful/list/List"
], function (registerSuite, assert, Deferred, List) {

	var list = null;

	registerSuite({
		name: "list/List",
		beforeEach: function () {
			if (list) {
				list.destroy();
			}
			list = new List();
			document.body.appendChild(list);
			list.startup();
			list.store.add({label: "item 1"});
			list.store.add({label: "item 2"});
			list.store.add({label: "item 3"});
			list.deliver();
		},
		"baseClass update" : function () {
			assert.strictEqual(list.className, "d-list");
			list.baseClass = "d-round-rect-list";
			assert.strictEqual(list.className, "d-round-rect-list");
			list.baseClass = "d-list";
			assert.strictEqual(list.className, "d-list");
		},
		"scrollDirection horizontal not supported": function () {
			try {
				list.scrollDirection = "horizontal";
			} catch (error) {
				assert.isNotNull(error);
				console.log(error);
				assert.strictEqual(
						"'horizontal' not supported for scrollDirection, keeping the previous value of 'vertical'",
						error.message,
						"error message");
				assert.strictEqual(list.scrollDirection, "vertical");
			}
		},
		"scrollDirection foo not supported": function () {
			try {
				list.scrollDirection = "foo";
			} catch (error) {
				assert.isNotNull(error);
				console.log(error);
				assert.strictEqual("'foo' not supported for scrollDirection, keeping the previous value of 'vertical'",
						error.message,
						"error message");
				assert.strictEqual(list.scrollDirection, "vertical");
			}
		},
		"default scroll direction is vertical": function () {
			list.scrollDirection = "vertical";
			list.deliver();
			assert.strictEqual(list.scrollableNode.className, "d-list-container d-scrollable d-scrollable-v");
		},
		"scroll direction none": function () {
			list.scrollDirection = "none";
			list.deliver();
			list.scrollDirection = "none";
			assert.strictEqual(list.className, "d-list");
		},
		"getRendererByItemId": function () {
			var children = list.getChildren();
			assert.strictEqual(list.getRendererByItemId(list.store.data[0].id), children[0], "first renderer");
			assert.strictEqual(list.getRendererByItemId(list.store.data[1].id), children[1], "second renderer");
			assert.strictEqual(list.getRendererByItemId(list.store.data[2].id), children[2], "third renderer");
			assert.isNull(list.getRendererByItemId("I'm not an existing id"), "non list item");
		},
		"getItemRendererIndex": function () {
			var children = list.getChildren();
			assert.strictEqual(0, list.getItemRendererIndex(children[0]), "first renderer");
			assert.strictEqual(1, list.getItemRendererIndex(children[1]), "second renderer");
			assert.strictEqual(2, list.getItemRendererIndex(children[2]), "second renderer");
			assert.strictEqual(-1, list.getItemRendererIndex(list), "non list renderer");
		},
		"getEnclosingRenderer": function () {
			var children = list.getChildren();
			assert.strictEqual(list.getEnclosingRenderer(children[0]), children[0], "first");
			assert.strictEqual(list.getEnclosingRenderer(children[0].getChildren()[0]), children[0], "second");
			assert.isNull(list.getEnclosingRenderer(list), "third");
		},
		"_renderNewItems": function () {
			list._renderNewItems([{label: "item a"}, {label: "item b"}, {label: "item c"}], true);
			var children = list.getChildren();
			assert.strictEqual(children.length, 6, "nb of items");
			assert.strictEqual(children[0].item.label, "item a", "first added 1");
			assert.strictEqual(children[1].item.label, "item b", "first added 2");
			assert.strictEqual(children[2].item.label, "item c", "firstd added 3");
			list._renderNewItems([{label: "item d"}, {label: "item e"}, {label: "item f"}], false);
			children = list.getChildren();
			assert.strictEqual(children.length, 9, "nb of items 2");
			assert.strictEqual(children[6].item.label, "item d", "last added 1");
			assert.strictEqual(children[7].item.label, "item e", "last added 2");
			assert.strictEqual(children[8].item.label, "item f", "last added 3");
		},
		"_getFirst": function () {
			var children = list.getChildren();
			assert.strictEqual(list._getFirst(), children[0].renderNode);
			list.categoryAttr = "label";
			list.deliver();
			children = list.getChildren();
			assert.strictEqual(children[0].className, "d-list-category", "first is category");
			assert.strictEqual(list._getFirst(), children[0].renderNode, "first renderer is category");
		},
		"_getLast": function () {
			var children = list.getChildren();
			assert.strictEqual(list._getLast(), children[2].renderNode);
		},
		"update item label": function () {
			list.store.put({label: "item a"}, {id: list.store.data[0].id});
			list.deliver();
			var renderer = list.getChildren()[0];
			assert.strictEqual(renderer.item.label, "item a");
			assert.strictEqual(renderer.firstChild.children[1].innerHTML, "item a");
		},
		"update item: add, update and remove icon" : function () {
			// add
			list.store.put({label: "item a", iconclass: "my-icon"}, {id: list.store.data[0].id});
			list.deliver();
			var renderer = list.getChildren()[0];
			assert.strictEqual(renderer.item.label, "item a");
			assert.strictEqual(renderer.firstChild.getAttribute("role"), "gridcell");
			assert.strictEqual(renderer.firstChild.firstChild.className, "d-list-item-icon my-icon");
			assert.strictEqual(renderer.firstChild.children[1].className, "d-list-item-label");
			assert.strictEqual(renderer.firstChild.children[1].innerHTML, "item a");
			// update
			list.store.put({label: "item a", iconclass: "my-other-icon"}, {id: list.store.data[0].id});
			list.deliver();
			renderer = list.getChildren()[0];
			assert.strictEqual(renderer.item.label, "item a");
			assert.strictEqual(renderer.firstChild.getAttribute("role"), "gridcell");
			assert.strictEqual(renderer.firstChild.firstChild.className, "d-list-item-icon my-other-icon");
			assert.strictEqual(renderer.firstChild.children[1].className, "d-list-item-label");
			assert.strictEqual(renderer.firstChild.children[1].innerHTML, "item a");
			// remove
			list.store.put({label: "item a"}, {id: list.store.data[0].id});
			list.deliver();
			renderer = list.getChildren()[0];
			assert.strictEqual(renderer.item.label, "item a");
			assert.strictEqual(renderer.firstChild.getAttribute("role"), "gridcell");
			assert.strictEqual(renderer.firstChild.children[1].className, "d-list-item-label");
			assert.strictEqual(renderer.firstChild.children[1].innerHTML, "item a");
		},
		"item category attribute is not undefined by StoreMap": function () {
			list.destroy();
			list = new List();
			list.startup();
			list.store.add({label: "item 1", category: "category 1"});
			assert.strictEqual(list.getChildren()[0].item.category, "category 1");
		},
		"query-error event": function () {
			var def = this.async(1000);
			try {
				var queryErrorEvt = null;
				var store = {
					filter: function () {
						var result = new Deferred();
						result.map = function () { return this; };
						result.reject("Query Error X");
						return result;
					}
				};
				list.destroy();
				list = new List({store: store});
				list.on("query-error", function (evt) {
					queryErrorEvt = evt;
				});
				list.startup();
				setTimeout(def.callback(function () {
					assert.isNotNull(queryErrorEvt);
					assert.strictEqual("Query Error X", queryErrorEvt.error, "error message");
					assert(!list.hasAttribute("aria-busy"));
				}), 10);
			} catch (e) {
				def.reject(e);
			}
			return def;
		},
		"first focus apply to the first visible child": function () {
			var def = this.async(1000);
			try {
				list.style.height = "200px";
				var itemHeightInPixel = 43;
				for (var i = 0; i < 50; i++) {
					list.store.add({label: "item " + (i + 4)});
				}
				list.focus();
				setTimeout(def.rejectOnError(function () {
					try {
						var focusedElement = document.activeElement;
						assert.isNotNull(focusedElement, "active element");
						assert.isDefined(focusedElement, "active element");
						assert.strictEqual("item 1", focusedElement.parentNode.item.label, "focused element label");
						list.scrollableNode.scrollTop = itemHeightInPixel * 2.5;
						setTimeout(def.rejectOnError(function () {
							list.focus();
							setTimeout(def.callback(function () {
								try {
									var focusedElement = document.activeElement;
									assert.isNotNull(focusedElement, "active element");
									assert.isDefined(focusedElement, "active element");
									assert.strictEqual("item 4", focusedElement.parentNode.item.label,
										"focused element label");
									def.resolve();
								} catch (error) {
									def.reject(error);
								}
							}), 10);
						}), 500);
					} catch (error) {
						def.reject(error);
					}
				}), 10);
			} catch (error) {
				def.reject(error);
			}
			return def;
		},
		teardown : function () {
			list.destroy();
			list = null;
		}
	});
});
<commit_msg>Fix unit test related to baseClass update.<commit_after>define([
	"intern!object",
	"intern/chai!assert",
	"dojo/Deferred",
	"deliteful/list/List"
], function (registerSuite, assert, Deferred, List) {

	var list = null;

	registerSuite({
		name: "list/List",
		beforeEach: function () {
			if (list) {
				list.destroy();
			}
			list = new List();
			document.body.appendChild(list);
			list.startup();
			list.store.add({label: "item 1"});
			list.store.add({label: "item 2"});
			list.store.add({label: "item 3"});
			list.deliver();
		},
		"baseClass update" : function () {
			assert.strictEqual(list.className, "d-list");
			list.baseClass = "d-round-rect-list";
			list.deliver();
			assert.strictEqual(list.className, "d-round-rect-list");
			list.baseClass = "d-list";
			list.deliver();
			assert.strictEqual(list.className, "d-list");
		},
		"scrollDirection horizontal not supported": function () {
			try {
				list.scrollDirection = "horizontal";
			} catch (error) {
				assert.isNotNull(error);
				console.log(error);
				assert.strictEqual(
						"'horizontal' not supported for scrollDirection, keeping the previous value of 'vertical'",
						error.message,
						"error message");
				assert.strictEqual(list.scrollDirection, "vertical");
			}
		},
		"scrollDirection foo not supported": function () {
			try {
				list.scrollDirection = "foo";
			} catch (error) {
				assert.isNotNull(error);
				console.log(error);
				assert.strictEqual("'foo' not supported for scrollDirection, keeping the previous value of 'vertical'",
						error.message,
						"error message");
				assert.strictEqual(list.scrollDirection, "vertical");
			}
		},
		"default scroll direction is vertical": function () {
			list.scrollDirection = "vertical";
			list.deliver();
			assert.strictEqual(list.scrollableNode.className, "d-list-container d-scrollable d-scrollable-v");
		},
		"scroll direction none": function () {
			list.scrollDirection = "none";
			list.deliver();
			list.scrollDirection = "none";
			assert.strictEqual(list.className, "d-list");
		},
		"getRendererByItemId": function () {
			var children = list.getChildren();
			assert.strictEqual(list.getRendererByItemId(list.store.data[0].id), children[0], "first renderer");
			assert.strictEqual(list.getRendererByItemId(list.store.data[1].id), children[1], "second renderer");
			assert.strictEqual(list.getRendererByItemId(list.store.data[2].id), children[2], "third renderer");
			assert.isNull(list.getRendererByItemId("I'm not an existing id"), "non list item");
		},
		"getItemRendererIndex": function () {
			var children = list.getChildren();
			assert.strictEqual(0, list.getItemRendererIndex(children[0]), "first renderer");
			assert.strictEqual(1, list.getItemRendererIndex(children[1]), "second renderer");
			assert.strictEqual(2, list.getItemRendererIndex(children[2]), "second renderer");
			assert.strictEqual(-1, list.getItemRendererIndex(list), "non list renderer");
		},
		"getEnclosingRenderer": function () {
			var children = list.getChildren();
			assert.strictEqual(list.getEnclosingRenderer(children[0]), children[0], "first");
			assert.strictEqual(list.getEnclosingRenderer(children[0].getChildren()[0]), children[0], "second");
			assert.isNull(list.getEnclosingRenderer(list), "third");
		},
		"_renderNewItems": function () {
			list._renderNewItems([{label: "item a"}, {label: "item b"}, {label: "item c"}], true);
			var children = list.getChildren();
			assert.strictEqual(children.length, 6, "nb of items");
			assert.strictEqual(children[0].item.label, "item a", "first added 1");
			assert.strictEqual(children[1].item.label, "item b", "first added 2");
			assert.strictEqual(children[2].item.label, "item c", "firstd added 3");
			list._renderNewItems([{label: "item d"}, {label: "item e"}, {label: "item f"}], false);
			children = list.getChildren();
			assert.strictEqual(children.length, 9, "nb of items 2");
			assert.strictEqual(children[6].item.label, "item d", "last added 1");
			assert.strictEqual(children[7].item.label, "item e", "last added 2");
			assert.strictEqual(children[8].item.label, "item f", "last added 3");
		},
		"_getFirst": function () {
			var children = list.getChildren();
			assert.strictEqual(list._getFirst(), children[0].renderNode);
			list.categoryAttr = "label";
			list.deliver();
			children = list.getChildren();
			assert.strictEqual(children[0].className, "d-list-category", "first is category");
			assert.strictEqual(list._getFirst(), children[0].renderNode, "first renderer is category");
		},
		"_getLast": function () {
			var children = list.getChildren();
			assert.strictEqual(list._getLast(), children[2].renderNode);
		},
		"update item label": function () {
			list.store.put({label: "item a"}, {id: list.store.data[0].id});
			list.deliver();
			var renderer = list.getChildren()[0];
			assert.strictEqual(renderer.item.label, "item a");
			assert.strictEqual(renderer.firstChild.children[1].innerHTML, "item a");
		},
		"update item: add, update and remove icon" : function () {
			// add
			list.store.put({label: "item a", iconclass: "my-icon"}, {id: list.store.data[0].id});
			list.deliver();
			var renderer = list.getChildren()[0];
			assert.strictEqual(renderer.item.label, "item a");
			assert.strictEqual(renderer.firstChild.getAttribute("role"), "gridcell");
			assert.strictEqual(renderer.firstChild.firstChild.className, "d-list-item-icon my-icon");
			assert.strictEqual(renderer.firstChild.children[1].className, "d-list-item-label");
			assert.strictEqual(renderer.firstChild.children[1].innerHTML, "item a");
			// update
			list.store.put({label: "item a", iconclass: "my-other-icon"}, {id: list.store.data[0].id});
			list.deliver();
			renderer = list.getChildren()[0];
			assert.strictEqual(renderer.item.label, "item a");
			assert.strictEqual(renderer.firstChild.getAttribute("role"), "gridcell");
			assert.strictEqual(renderer.firstChild.firstChild.className, "d-list-item-icon my-other-icon");
			assert.strictEqual(renderer.firstChild.children[1].className, "d-list-item-label");
			assert.strictEqual(renderer.firstChild.children[1].innerHTML, "item a");
			// remove
			list.store.put({label: "item a"}, {id: list.store.data[0].id});
			list.deliver();
			renderer = list.getChildren()[0];
			assert.strictEqual(renderer.item.label, "item a");
			assert.strictEqual(renderer.firstChild.getAttribute("role"), "gridcell");
			assert.strictEqual(renderer.firstChild.children[1].className, "d-list-item-label");
			assert.strictEqual(renderer.firstChild.children[1].innerHTML, "item a");
		},
		"item category attribute is not undefined by StoreMap": function () {
			list.destroy();
			list = new List();
			list.startup();
			list.store.add({label: "item 1", category: "category 1"});
			assert.strictEqual(list.getChildren()[0].item.category, "category 1");
		},
		"query-error event": function () {
			var def = this.async(1000);
			try {
				var queryErrorEvt = null;
				var store = {
					filter: function () {
						var result = new Deferred();
						result.map = function () { return this; };
						result.reject("Query Error X");
						return result;
					}
				};
				list.destroy();
				list = new List({store: store});
				list.on("query-error", function (evt) {
					queryErrorEvt = evt;
				});
				list.startup();
				setTimeout(def.callback(function () {
					assert.isNotNull(queryErrorEvt);
					assert.strictEqual("Query Error X", queryErrorEvt.error, "error message");
					assert(!list.hasAttribute("aria-busy"));
				}), 10);
			} catch (e) {
				def.reject(e);
			}
			return def;
		},
		"first focus apply to the first visible child": function () {
			var def = this.async(1000);
			try {
				list.style.height = "200px";
				var itemHeightInPixel = 43;
				for (var i = 0; i < 50; i++) {
					list.store.add({label: "item " + (i + 4)});
				}
				list.focus();
				setTimeout(def.rejectOnError(function () {
					try {
						var focusedElement = document.activeElement;
						assert.isNotNull(focusedElement, "active element");
						assert.isDefined(focusedElement, "active element");
						assert.strictEqual("item 1", focusedElement.parentNode.item.label, "focused element label");
						list.scrollableNode.scrollTop = itemHeightInPixel * 2.5;
						setTimeout(def.rejectOnError(function () {
							list.focus();
							setTimeout(def.callback(function () {
								try {
									var focusedElement = document.activeElement;
									assert.isNotNull(focusedElement, "active element");
									assert.isDefined(focusedElement, "active element");
									assert.strictEqual("item 4", focusedElement.parentNode.item.label,
										"focused element label");
									def.resolve();
								} catch (error) {
									def.reject(error);
								}
							}), 10);
						}), 500);
					} catch (error) {
						def.reject(error);
					}
				}), 10);
			} catch (error) {
				def.reject(error);
			}
			return def;
		},
		teardown : function () {
			list.destroy();
			list = null;
		}
	});
});
<|endoftext|>


<commit_before>/*
 * OutlineLabel.js
 */

tm.display = tm.display || {};

(function() {

    /**
     * @class tm.display.OutlineLabel
     * システムフォントを描画するクラス（アウトライン付き）
     * @extends tm.display.CanvasElement
     */
    tm.display.OutlineLabel = tm.createClass({
        superClass: tm.display.CanvasElement,

        //縁取り分を含めたラベル配列
        labels: null,

        //アウトラインの幅
        _outlineWidth: 1,

        /**
         * @constructor
         */
        init: function(text, size) {
            this.superInit();

            this.outlineColor = "black";

            //アウトライン作成
            this.labels = [];
            var n = 0;
            for (var i = -1; i < 2; i++) {
                for (var j = -1; j < 2; j++) {
                    this.labels[n] = tm.display.Label(text, size);
                    this.labels[n].setPosition(i * this.outlineWidth, j * this.outlineWidth);
                    if (i == 0 && j == 0){
                        this.labels[n].fillStyle = 'white';
                    } else {
                        this.labels[n].fillStyle = 'black';
                        this.labels[n].addChildTo(this);
                    }
                    n++;
                }
            }
            //真ん中は一番後に追加
            this.labels[4].addChildTo(this);
        },

        setAlign: function(align) {
            this.align = align;
            return this;
        },

        setBaseline: function(baseline) {
            this.baseline = baseline;
            return this;
        },

        setFontSize: function(size) {
            this.fontSize = size;
            return this;
        },

        setFontFamily: function(family) {
            this.fontFamily = family;
            return this;
        },

        setFontWeight: function(weight) {
            this.fontWeight = weight;
            return this;
        },

        setBlendMode: function(blendMode) {
            this.blendMode = blendMode;
            return this;
        },

        setFillStyle: function(fillStyle) {
            this.fillStyle = fillStyle;
            return this;
        },

        setFillStyleOutline: function(fillStyle) {
            this.fillStyleOutline = fillStyle;
            return this;
        },

        setOutlineWidth: function(width) {
            this.outlineWidth = width;
            return this;
        },

        //パラメータ一括セット
        setParam: function(param) {
            this.fontFamily       = param.fontFamily       || this.fontFamily;
            this.align            = param.align            || this.align;
            this.baseline         = param.baseline         || this.baseline;
            this.fontSize         = param.fontSize         || this.fontSize
            this.fontWeight       = param.fontWeight       || this.fontWeight;
            this.fillStyle        = param.fillStyle        || this.fillStyle;
            this.fillStyleOutline = param.fillStyleOutline || this.fillStyleOutline;
            this.outlineWidth     = param.outlineWidth     || this.outlineWidth;
            return this;
        },
    });

    /**
     * @property    text
     * 文字
     */
    tm.display.OutlineLabel.prototype.accessor("text", {
        "get": function() { return this.labels[0].text; },
        "set": function(v){
            if (v == null || v == undefined) {
                for (var i = 0; i < 9; i++)this.labels[i].text = "";
            } else {
                for (var i = 0; i < 9; i++)this.labels[i].text = v;
            }
        }
    });

    /**
     * @property    fontSize
     * フォントサイズ
     */
    tm.display.OutlineLabel.prototype.accessor("fontSize", {
        "get": function() { return this.labels[0].fontSize; },
        "set": function(v) {
            for (var i = 0; i < 9; i++)this.labels[i].fontSize = v;
        }
    });

    /**
     * @property    fontFamily
     * フォント
     */
    tm.display.OutlineLabel.prototype.accessor("fontFamily", {
        "get": function() { return this.labels[0].fontFamily; },
        "set": function(v){
            for (var i = 0; i < 9; i++)this.labels[i].fontFamily = v;
        }
    });

    /**
     * @property    fontWeight
     */
    tm.display.OutlineLabel.prototype.accessor("fontWeight", {
        "get": function() { return this.labels[0].fontWeight; },
        "set": function(v) {
            for (var i = 0; i < 9; i++)this.labels[i].fontWeight = v;
        },
    });

    /**
     * @property lineHeight
     */
    tm.display.OutlineLabel.prototype.accessor("lineHeight", {
        "get": function() { return this.labels[0].lineHeight; },
        "set": function(v) {
            for (var i = 0; i < 9; i++)this.labels[i].lineHeight = v;
        },
    });

    /**
     * @property fillStyle
     */
    tm.display.OutlineLabel.prototype.accessor("fillStyle", {
        "get": function() { return this.labels[4].fillStyle; },
        "set": function(fillStyle) {
            this.labels[4].fillStyle = fillStyle;
        },
    });

    /**
     * @property fillStyleOutline
     */
    tm.display.OutlineLabel.prototype.accessor("fillStyleOutline", {
        "get": function() { return this.labels[0].fillStyle; },
        "set": function(fillStyle) {
            for (var i = 0; i < 9; i++) {
                if (i != 4)this.labels[i].fillStyle = fillStyle;
            }
        },
    });

    /**
     * @property    align
     */
    tm.display.OutlineLabel.prototype.accessor("align", {
        "get": function() { return this.labels[0].align; },
        "set": function(align) {
            for (var i = 0; i < 9; i++)this.labels[i].align = align;
        }
    });

    /**
     * @property    baseline
     */
    tm.display.OutlineLabel.prototype.accessor("baseline", {
        "get": function() { return this.labels[0].baseline; },
        "set": function(baseline) {
            for (var i = 0; i < 9; i++)this.labels[i].baseline = baseline;
        }
    });

    /**
     * @property    blendMode
     */
    tm.display.OutlineLabel.prototype.accessor("blendMode", {
        "get": function() { return this.labels[4].blendMode; },
        "set": function(blendMode) {
            for (var i = 0; i < 9; i++)this.labels[i].blendMode = blendMode;
        }
    });

    /**
     * @property    alpha
     */
    tm.display.OutlineLabel.prototype.accessor("alpha", {
        "get": function() { return this.labels[4].alpha; },
        "set": function(alpha) {
            for (var i = 0; i < 9; i++)this.labels[i].alpha = alpha;
        }
    });

    /**
     * @property    visible
     */
    tm.display.OutlineLabel.prototype.accessor("visible", {
        "get": function() { return this.labels[0].visible; },
        "set": function(visible) {
            for (var i = 0; i < 9; i++)this.labels[i].visible = visible;
        }
    });

    /**
     * @property    outlineWidth
     *              縁取り幅
     */
    tm.display.OutlineLabel.prototype.accessor("outlineWidth", {
        "get": function() { return this._outlineWidth; },
        "set": function(width) {
            this._outlineWidth = width;
            var n = 0;
            for (var i = -1; i < 2; i++) {
                for (var j = -1; j < 2; j++) {
                    this.labels[n].setPosition(i * this._outlineWidth, j * this._outlineWidth);
                    n++;
                }
            }
        }
    });

    /**
     * @property    shadowBlur
     */
    tm.display.OutlineLabel.prototype.accessor("shadowBlur", {
        "get": function() { return this.labels[4].shadowBlur; },
        "set": function(shadowBlur) {
           for (var i = 0; i < 9; i++)this.labels[i].shadowBlur = shadowBlur;
//           this.labels[4].shadowBlur = shadowBlur;
        }
    });

    /**
     * @property    shadowColoe
     */
    tm.display.OutlineLabel.prototype.accessor("shadowColor", {
        "get": function() { return this.labels[4].shadowColor; },
        "set": function(shadowColor) {
            for (var i = 0; i < 9; i++)this.labels[i].shadowColor = shadowColor;
//            this.labels[4].shadowColor = shadowColor;
        }
    });

})();
<commit_msg>OutlineLabel更新<commit_after>/*
 * OutlineLabel.js
 */

tm.display = tm.display || {};

(function() {

    /**
     * @class tm.display.OutlineLabel
     * システムフォントを描画するクラス（アウトライン付き）
     * @extends tm.display.CanvasElement
     */
    tm.display.OutlineLabel = tm.createClass({
        superClass: tm.display.CanvasElement,

        //縁取り分を含めたラベル配列
        labels: null,

        //アウトラインの幅
        _outlineWidth: 1,

        /**
         * @constructor
         */
        init: function(text, size) {
            this.superInit();

            this.outlineColor = "black";

            //アウトライン作成
            this.labels = [];
            var n = 0;
            for (var i = -1; i < 2; i++) {
                for (var j = -1; j < 2; j++) {
                    this.labels[n] = tm.display.Label(text, size);
                    this.labels[n].setPosition(i * this.outlineWidth, j * this.outlineWidth);
                    if (i == 0 && j == 0){
                        this.labels[n].fillStyle = 'white';
                    } else {
                        this.labels[n].fillStyle = 'black';
                        this.labels[n].addChildTo(this);
                    }
                    n++;
                }
            }
            //真ん中は一番後に追加
            this.labels[4].addChildTo(this);
        },

        setAlign: function(align) {
            this.align = align;
            return this;
        },

        setBaseline: function(baseline) {
            this.baseline = baseline;
            return this;
        },

        setFontSize: function(size) {
            this.fontSize = size;
            return this;
        },

        setFontFamily: function(family) {
            this.fontFamily = family;
            return this;
        },

        setFontWeight: function(weight) {
            this.fontWeight = weight;
            return this;
        },

        setBlendMode: function(blendMode) {
            this.blendMode = blendMode;
            return this;
        },

        setFillStyle: function(fillStyle) {
            this.fillStyle = fillStyle;
            return this;
        },

        setFillStyleOutline: function(fillStyle) {
            this.fillStyleOutline = fillStyle;
            return this;
        },

        setOutlineWidth: function(width) {
            this.outlineWidth = width;
            return this;
        },

        //パラメータ一括セット
        setParam: function(param) {
            this.fontFamily       = param.fontFamily       || this.fontFamily;
            this.align            = param.align            || this.align;
            this.baseline         = param.baseline         || this.baseline;
            this.fontSize         = param.fontSize         || this.fontSize
            this.fontWeight       = param.fontWeight       || this.fontWeight;
            this.fillStyle        = param.fillStyle        || this.fillStyle;
            this.fillStyleOutline = param.fillStyleOutline || this.fillStyleOutline;
            this.outlineWidth     = param.outlineWidth     || this.outlineWidth;
            return this;
        },
    });

    /**
     * @property    text
     * 文字
     */
    tm.display.OutlineLabel.prototype.accessor("text", {
        "get": function() { return this.labels[0].text; },
        "set": function(v){
            if (v == null || v == undefined) {
                for (var i = 0; i < 9; i++)this.labels[i].text = "";
            } else {
                for (var i = 0; i < 9; i++)this.labels[i].text = v;
            }
        }
    });

    /**
     * @property    fontSize
     * フォントサイズ
     */
    tm.display.OutlineLabel.prototype.accessor("fontSize", {
        "get": function() { return this.labels[0].fontSize; },
        "set": function(v) {
            for (var i = 0; i < 9; i++)this.labels[i].fontSize = v;
        }
    });

    /**
     * @property    fontFamily
     * フォント
     */
    tm.display.OutlineLabel.prototype.accessor("fontFamily", {
        "get": function() { return this.labels[0].fontFamily; },
        "set": function(v){
            for (var i = 0; i < 9; i++)this.labels[i].fontFamily = v;
        }
    });

    /**
     * @property    fontWeight
     */
    tm.display.OutlineLabel.prototype.accessor("fontWeight", {
        "get": function() { return this.labels[0].fontWeight; },
        "set": function(v) {
            for (var i = 0; i < 9; i++)this.labels[i].fontWeight = v;
        },
    });

    /**
     * @property lineHeight
     */
    tm.display.OutlineLabel.prototype.accessor("lineHeight", {
        "get": function() { return this.labels[0].lineHeight; },
        "set": function(v) {
            for (var i = 0; i < 9; i++)this.labels[i].lineHeight = v;
        },
    });

    /**
     * @property fillStyle
     */
    tm.display.OutlineLabel.prototype.accessor("fillStyle", {
        "get": function() { return this.labels[4].fillStyle; },
        "set": function(fillStyle) {
            this.labels[4].fillStyle = fillStyle;
        },
    });

    /**
     * @property fillStyleOutline
     */
    tm.display.OutlineLabel.prototype.accessor("fillStyleOutline", {
        "get": function() { return this.labels[0].fillStyle; },
        "set": function(fillStyle) {
            for (var i = 0; i < 9; i++) {
                if (i != 4)this.labels[i].fillStyle = fillStyle;
            }
        },
    });

    /**
     * @property    align
     */
    tm.display.OutlineLabel.prototype.accessor("align", {
        "get": function() { return this.labels[0].align; },
        "set": function(align) {
            for (var i = 0; i < 9; i++)this.labels[i].align = align;
        }
    });

    /**
     * @property    baseline
     */
    tm.display.OutlineLabel.prototype.accessor("baseline", {
        "get": function() { return this.labels[0].baseline; },
        "set": function(baseline) {
            for (var i = 0; i < 9; i++)this.labels[i].baseline = baseline;
        }
    });

    /**
     * @property    blendMode
     */
    tm.display.OutlineLabel.prototype.accessor("blendMode", {
        "get": function() { return this.labels[4].blendMode; },
        "set": function(blendMode) {
            for (var i = 0; i < 9; i++)this.labels[i].blendMode = blendMode;
        }
    });

    /**
     * @property    alpha
     */
    tm.display.OutlineLabel.prototype.accessor("alpha", {
        "get": function() { return this.labels[4].alpha; },
        "set": function(alpha) {
            for (var i = 0; i < 9; i++)this.labels[i].alpha = alpha;
        }
    });

    /**
     * @property    visible
     */
    tm.display.OutlineLabel.prototype.accessor("visible", {
        "get": function() { return this.labels[0].visible; },
        "set": function(visible) {
            for (var i = 0; i < 9; i++)this.labels[i].visible = visible;
        }
    });

    /**
     * @property    outlineWidth
     *              縁取り幅
     */
    tm.display.OutlineLabel.prototype.accessor("outlineWidth", {
        "get": function() { return this._outlineWidth; },
        "set": function(width) {
            this._outlineWidth = width;
            var n = 0;
            for (var i = -1; i < 2; i++) {
                for (var j = -1; j < 2; j++) {
                    this.labels[n].setPosition(i * this._outlineWidth, j * this._outlineWidth);
                    n++;
                }
            }
        }
    });

    /**
     * @property    shadowBlur
     */
    tm.display.OutlineLabel.prototype.accessor("shadowBlur", {
        "get": function() { return this.labels[4].shadowBlur; },
        "set": function(shadowBlur) {
           for (var i = 0; i < 9; i++)this.labels[i].shadowBlur = shadowBlur;
//           this.labels[4].shadowBlur = shadowBlur;
        }
    });

    /**
     * @property    shadowColoe
     */
    tm.display.OutlineLabel.prototype.accessor("shadowColor", {
        "get": function() { return this.labels[4].shadowColor; },
        "set": function(shadowColor) {
            for (var i = 0; i < 9; i++)this.labels[i].shadowColor = shadowColor;
//            this.labels[4].shadowColor = shadowColor;
        }
    });

    //tm.display.Label拡張
    //パラメータ一括セット
    tm.display.Label.prototype.setParam =  function(param) {
            this.fontFamily       = param.fontFamily       || this.fontFamily;
            this.align            = param.align            || this.align;
            this.baseline         = param.baseline         || this.baseline;
            this.fontSize         = param.fontSize         || this.fontSize
            this.fontWeight       = param.fontWeight       || this.fontWeight;
            this.fillStyle        = param.fillStyle        || this.fillStyle;
            this.fillStyleOutline = param.fillStyleOutline || this.fillStyleOutline;
            this.outlineWidth     = param.outlineWidth     || this.outlineWidth;
            return this;
    }

})();
<|endoftext|>


<commit_before>/* eslint-disable object-property-newline */
/* eslint-disable no-var */

(function testDriver() {
    "use strict";
    var tests = [
        {"exec": false, "path": "test0.html"},
        {"exec": true, "path": "test1.html"},
        {"exec": true, "path": "test2.html"},
        {"exec": true, "path": "test3.html"},
        {"exec": true, "path": "test4.html"},
        {"exec": true, "path": "test5.html"},
        {"exec": true, "path": "test6.html"},
        {"exec": true, "path": "test7.html"},
        {"exec": true, "path": "test8.html"},
        {"exec": true, "path": "test9.html"},
        {"exec": true, "path": "test10.html"},
        {"exec": true, "path": "test11.html"},
        {"exec": true, "path": "test12.html"},
        {"exec": true, "path": "test13.html"},
        {"exec": true, "path": "test14.html"},
        {"exec": true, "path": "test15.html"},
        {"exec": true, "path": "test16.html"},
        {"exec": true, "path": "test17.html"},
        {"exec": true, "path": "test18.html"},
        {"exec": true, "path": "test19.html"},
        {"exec": true, "path": "test20.html"},
        {"exec": true, "path": "test21.html"},
        {"exec": true, "path": "test22.html"},
        {"exec": true, "path": "test23.html"},
        {"exec": true, "path": "test24.html"},
        {"exec": true, "path": "test25.html"},
        {"exec": true, "path": "test26.html"},
        {"exec": true, "path": "test27.html"},
        {"exec": true, "path": "test28.html"},
        {"exec": true, "path": "test29.html"},
        {"exec": true, "path": "test30.html"},
        {"exec": true, "path": "test31.html"},
        {"exec": true, "path": "test32.html"},
        {"exec": true, "path": "test33.html"},
        {"exec": true, "path": "test34.html"},
        {"exec": true, "path": "test35.html"},
        {"exec": true, "path": "test36.html"},
        {"exec": true, "path": "test37.html"},
        {"exec": true, "path": "test38.html"}
    ];
    var testframe = document.getElementById("testframe");
    var currentTest = 1;
    var total = "passed";

    /**
     * Add test result to the DOM
     * @param {string} name – Filename
     * @param {string} desc - Test description
     * @param {string} result - Result (failed or passed)
     */
    function addTestResult(name, desc, result) {
        var dl = document.getElementById("testresults");
        var template = document.getElementById("template").innerHTML;
        template = template.replace(/@file@/g, name);
        template = template.replace(/@desc@/, desc);
        template = template.replace(/@result@/g, result);
        dl.innerHTML += template;
        window.scrollBy(0, 20);
    }

    /**
     * Runs tests
     * @param {number} index - Index of the test
     */
    function run(index) {
        /* eslint-disable security/detect-object-injection */
        if (tests[index]) {
            currentTest = index;
            if (tests[index].exec) {
                window.setTimeout(function defer() {
                    testframe.src = tests[index].path;
                }, 0);
            } else {
                addTestResult(tests[index].path, "omitted", "omitted");
                run(index + 1);
            }
        } else {
            addTestResult("", navigator.userAgent, total);
        }
        /* eslint-enable security/detect-object-injection */
    }

    window.addEventListener("message", function onMessage(e) {
        var msg = JSON.parse(e.data);
        addTestResult(tests[msg.index].path, msg.desc, msg.result);
        if (msg.result === "failed") {
            total = "failed";
        }
        run(msg.index + 1);
    }, false);

    run(currentTest);
}());
<commit_msg>security: no innerHTML<commit_after>/* eslint-disable object-property-newline */
/* eslint-disable no-var */

(function testDriver() {
    "use strict";
    var tests = [
        {"exec": false, "path": "test0.html"},
        {"exec": true, "path": "test1.html"},
        {"exec": true, "path": "test2.html"},
        {"exec": true, "path": "test3.html"},
        {"exec": true, "path": "test4.html"},
        {"exec": true, "path": "test5.html"},
        {"exec": true, "path": "test6.html"},
        {"exec": true, "path": "test7.html"},
        {"exec": true, "path": "test8.html"},
        {"exec": true, "path": "test9.html"},
        {"exec": true, "path": "test10.html"},
        {"exec": true, "path": "test11.html"},
        {"exec": true, "path": "test12.html"},
        {"exec": true, "path": "test13.html"},
        {"exec": true, "path": "test14.html"},
        {"exec": true, "path": "test15.html"},
        {"exec": true, "path": "test16.html"},
        {"exec": true, "path": "test17.html"},
        {"exec": true, "path": "test18.html"},
        {"exec": true, "path": "test19.html"},
        {"exec": true, "path": "test20.html"},
        {"exec": true, "path": "test21.html"},
        {"exec": true, "path": "test22.html"},
        {"exec": true, "path": "test23.html"},
        {"exec": true, "path": "test24.html"},
        {"exec": true, "path": "test25.html"},
        {"exec": true, "path": "test26.html"},
        {"exec": true, "path": "test27.html"},
        {"exec": true, "path": "test28.html"},
        {"exec": true, "path": "test29.html"},
        {"exec": true, "path": "test30.html"},
        {"exec": true, "path": "test31.html"},
        {"exec": true, "path": "test32.html"},
        {"exec": true, "path": "test33.html"},
        {"exec": true, "path": "test34.html"},
        {"exec": true, "path": "test35.html"},
        {"exec": true, "path": "test36.html"},
        {"exec": true, "path": "test37.html"},
        {"exec": true, "path": "test38.html"}
    ];
    var testframe = document.getElementById("testframe");
    var currentTest = 1;
    var total = "passed";

    /**
     * Add test result to the DOM
     * @param {string} name – Filename
     * @param {string} desc - Test description
     * @param {string} result - Result (failed or passed)
     */
    function addTestResult(name, desc, result) {
        var dl = document.getElementById("testresults");
        var li = document.createElement("li");
        var linkSpan = document.createElement("span");
        var filelink = document.createElement("a");
        var resultSpan = document.createElement("span");
        var descSpan = document.createElement("span");

        linkSpan.setAttribute("class", "testname");
        filelink.setAttribute("href", name);
        filelink.appendChild(document.createTextNode(name));
        linkSpan.appendChild(filelink);
        li.appendChild(linkSpan);

        resultSpan.setAttribute("class", "result " + result);
        resultSpan.appendChild(document.createTextNode("[" + result + "]"));
        li.appendChild(resultSpan);

        descSpan.setAttribute("class", "desc");
        descSpan.appendChild(document.createTextNode(desc));
        li.appendChild(descSpan);

        dl.appendChild(li);
    }

    /**
     * Runs tests
     * @param {number} index - Index of the test
     */
    function run(index) {
        /* eslint-disable security/detect-object-injection */
        if (tests[index]) {
            currentTest = index;
            if (tests[index].exec) {
                window.setTimeout(function defer() {
                    testframe.src = tests[index].path;
                }, 0);
            } else {
                addTestResult(tests[index].path, "omitted", "omitted");
                run(index + 1);
            }
        } else {
            addTestResult("", navigator.userAgent, total);
        }
        /* eslint-enable security/detect-object-injection */
    }

    window.addEventListener("message", function onMessage(e) {
        var msg = JSON.parse(e.data);
        addTestResult(tests[msg.index].path, msg.desc, msg.result);
        if (msg.result === "failed") {
            total = "failed";
        }
        run(msg.index + 1);
    }, false);

    run(currentTest);
}());
<|endoftext|>


<commit_before>/**
 * Core widget library, every widget has to be derived from the widget.
 *
 * @octdoc      ui/widget
 * @copyright   copyright (c) 2010-2012 by Harald Lapp
 * @author      Harald Lapp <harald@octris.org>
 */
/**/

;(function() {
    if ('widget' in oui) return;

    var registry = {};      // Global widget registry.

    /**
     * Constructor.
     *
     * @octdoc      widget/
     * @public
     * @param       string      name            Name to set for widget.
     * @param       object      options         Optional options for widget.
     * @return      oui.widget                  Widget instance.
     */
    oui.widget = function(name, options)
    /**/
    {
        /**
         * Main DOM node of widget.
         *
         * @octdoc      widget/node
         * @private
         * @var         DOMElement
         */
        var node = null;
        /**/

        /**
         * Name of widget.
         *
         * @octdoc      widget/name
         * @private
         * @var         string
         */
        var name = name || '';
        /**/

        /**
         * Options of widget.
         *
         * @octdoc      widget/options
         * @private
         * @var         object
         */
        var options = options || {};
        /**/

        /**
         * Whether the widget is disabled.
         *
         * @octdoc      widget/disabled
         * @private
         * @var         bool
         */
        var disabled = false;
        /**/

        /**
         * Child widgets.
         *
         * @octdoc      widget/children
         * @private
         * @var         array
         */
        var children = [];
        /**/

        /**
         * Return name of the widget.
         *
         * @octdoc      widget/getName
         * @public
         * @return      string                  The name of the widget.
         */
        this.getName = function()
        /**/
        {
            return name;
        }

        /**
         * Return main DOM node of the widget.
         *
         * @octdoc      widget/getNode
         * @public
         * @return      DOMElement
         */
        this.getNode = function()
        /**/
        {
            return node;
        }

        /**
         * Return value of a widget.
         *
         * @octdoc      widget/getValue
         * @public
         * @return      null|mixed
         */
        this.getValue = function()
        /**/
        {
            return null;
        }

        /**
         * Set value for a widget.
         *
         * @octdoc      widget/setValue
         * @public
         * @param       mixed           value               Value to set.
         */
        this.setValue = function(value)
        /**/
        {
        }

        /**
         * Enable or disable the widget and all it's child widgets.
         *
         * @octdoc      widget/setEnabled
         * @public
         * @param       bool            enabled             True enables the widget, false disables it.
         */
        this.setEnabled = function(enabled)
        /**/
        {
            if (disabled = !enabled) {
                return;
            }

            if ((disabled = !enabled)) {
                this.onDisable();
            } else {
                this.onEnable();
            }

            for (var i = 0, cnt = children.length; i < cnt; ++i) {
                children[i].setEnabled(enabled);
            }
        }

        /**
         * Initiate building of child widgets.
         *
         * @octdoc  widget/processChildren
         * @param   array           def                 Widget definition.
         * @param   callback        processor           Callback method for processing
         *                                              child widgets.
         * @param   parent          object              Optional parent DOM node.
         */
        this.processChildren = function(def, processor, parent)
        /**/
        {
            var me = this;

            (function process(parent, def) {
                if (!('children' in def)) return;

                var type, child, widget, instance;

                for (var i = 0, cnt = def['children'].length; i < cnt; ++i) {
                    child = null;

                    for (type in def['children'][i]) {
                        child = def['children'][i][type];
                        break;
                    }

                    if (child == null) {
                        // no child element
                        continue;
                    }

                    widget   = registry[type];
                    name     = ('name' in child ? child['name'] : '');
                    instance = me.addChild(new widget.widget(name, widget.options));

                    processor(parent, instance, child);
                }
            })(parent || node, def);
        }

        /**
         * Add child widget
         *
         * @octdoc      widget/addChild
         * @public
         * @param       oui.widget      instance            Instance of a widget.
         * @return      oui.widget                          The widget instance specified as parameter.
         */
        this.addChild = function(instance)
        /**/
        {
            if (!(instance instanceof oui.widget)) {
                throw 'The parameter specified is not an instance of \'oui.widget\'!';
            }

            // TODO: check, if instance is allowed to add (eg.: by checking options [eg.: container must not be
            //       a child of tile])

            var me = this;

            instance.getDialog = function() {
                return me.getDialog();
            }

            children.push(instance);

            return instance;
        }

        /**
         * Create widget. This method is normally called from within the attach method to create
         * the widget container.
         *
         * @octdoc      widget/create
         * @public
         * @param       DOMElement      parent              Parent node to create widget in.
         * @param       object          def                 Widget definition.
         * @return      DOMElement                          Node of new created widget.
         */
        this.create = function(parent, def)
        /**/
        {
            node = oui.$(document.createElement(this.container));
            node.addClass(
                this.cssclass + ('class' in def
                                 ? ' ' + def['class']
                                 : '')
            );

            parent.append(node);

            return node;
        }
    }

    /**
     * Default container type of a widget.
     *
     * @octdoc      widget/container
     * @public
     * @var         string
     */
    oui.widget.prototype.container = 'DIV';
    /**/

    /**
     * Default css class of a widget.
     *
     * @octdoc      widget/cssclass
     * @public
     * @var         string
     */
    oui.widget.prototype.cssclass = 'oui_widget';
    /**/

    /**
     * Return dialog, the widget is assigned to. Returns false, if the widget is not assigned
     * to any dialog.
     *
     * @octdoc      widget/getDialog
     * @public
     * @var         bool|oui.dialog
     */
    oui.widget.prototype.getDialog = function()
    /**/
    {
        return false;
    }

    /**
     * Build a widget and attach it to a parent node.
     *
     * @octdoc      widget/attach
     * @public
     * @param       DOMElement      parent          Parent node to attach widget to.
     * @param       object          def             Widget definitions.
     */
    oui.widget.prototype.attach = function(parent, def)
    /**/
    {
        this.create(parent, def);

        this.processChildren(def, function(parent, instance, def) {
            instance.attach(parent, def);
        });
    }

    /**
     * Assimilate a part of a page and try to wrap OUI functionality around page elements.
     *
     * @octdoc      widget/assimilate
     * @public
     * @param       DOMElement      node            Node to assimilate.
     */
    oui.widget.prototype.assimilate = function(node)
    /**/
    {
        var me = this;

        (function _assimilate(node) {
            // TODO: implementation
        })(node);
    }

    /**
     * Add a widget object to the registry.
     *
     * @octdoc      widget/register
     * @static
     * @param       string          name            Name of widget to register.
     * @param       object          widget          Widget object.
     * @param       object          options         Optional options for widget creation.
     */
    oui.widget.register = function(name, widget, options)
    /**/
    {
        if (name in registry) {
            throw 'Widget was registered before!';
        } else if (name == 'widget') {
            throw 'A widget cannot have the name \'widget\'!';
        } else {
            registry[name] = {
                'widget':  widget,
                'options': options || {}
            }
        }
    }

    /*
     * event handlers to be overwritten by children
     */

    /**
     * Event handler get's called, when widget get's enabled
     *
     * @octdoc      widget/onEnable
     * @public
     */
    oui.widget.prototype.onEnable = function()
    /**/
    {
    }

    /**
     * Event handler get's called, when widget get's disabled.
     *
     * @octdoc      widget/onDisable
     * @public
     */
    oui.widget.prototype.onDisable = function()
    /**/
    {
    }

    /**
     * Event handler get's called, after widget was populated with data.
     *
     * @octdoc      widget/onPopulate
     * @public
     */
    oui.widget.prototype.onPopulate = function()
    /**/
    {
    }

    /**
     * Event handler get's called, after widget's value get's updated/changed.
     *
     * @octdoc      widget/onChange
     * @public
     */
    oui.widget.prototype.onChange = function()
    /**/
    {
    }

    /**
     * Event handler get's called, when widget is clicked on.
     *
     * @octdoc      widget/onClick
     * @public
     */
    oui.widget.prototype.onClick = function()
    /**/
    {
    }

    /*
     * static methods
     */

    /**
     * Tests if something is registered with a specified widget name.
     *
     * @octdoc      widget/isRegistered
     * @static
     * @param       string          name            Name of widget to test if it's registered.
     */
    oui.widget.isRegistered = function(name)
    /**/
    {
        return (name in registry);
    }
})();
<commit_msg>added method to retrieve parent widget<commit_after>/**
 * Core widget library, every widget has to be derived from the widget.
 *
 * @octdoc      ui/widget
 * @copyright   copyright (c) 2010-2012 by Harald Lapp
 * @author      Harald Lapp <harald@octris.org>
 */
/**/

;(function() {
    if ('widget' in oui) return;

    var registry = {};      // Global widget registry.

    /**
     * Constructor.
     *
     * @octdoc      widget/
     * @public
     * @param       string      name            Name to set for widget.
     * @param       object      options         Optional options for widget.
     * @return      oui.widget                  Widget instance.
     */
    oui.widget = function(name, options)
    /**/
    {
        /**
         * Main DOM node of widget.
         *
         * @octdoc      widget/node
         * @private
         * @var         DOMElement
         */
        var node = null;
        /**/

        /**
         * Name of widget.
         *
         * @octdoc      widget/name
         * @private
         * @var         string
         */
        var name = name || '';
        /**/

        /**
         * Options of widget.
         *
         * @octdoc      widget/options
         * @private
         * @var         object
         */
        var options = options || {};
        /**/

        /**
         * Whether the widget is disabled.
         *
         * @octdoc      widget/disabled
         * @private
         * @var         bool
         */
        var disabled = false;
        /**/

        /**
         * Child widgets.
         *
         * @octdoc      widget/children
         * @private
         * @var         array
         */
        var children = [];
        /**/

        /**
         * Return name of the widget.
         *
         * @octdoc      widget/getName
         * @public
         * @return      string                  The name of the widget.
         */
        this.getName = function()
        /**/
        {
            return name;
        }

        /**
         * Return main DOM node of the widget.
         *
         * @octdoc      widget/getNode
         * @public
         * @return      DOMElement
         */
        this.getNode = function()
        /**/
        {
            return node;
        }

        /**
         * Return value of a widget.
         *
         * @octdoc      widget/getValue
         * @public
         * @return      null|mixed
         */
        this.getValue = function()
        /**/
        {
            return null;
        }

        /**
         * Set value for a widget.
         *
         * @octdoc      widget/setValue
         * @public
         * @param       mixed           value               Value to set.
         */
        this.setValue = function(value)
        /**/
        {
        }

        /**
         * Enable or disable the widget and all it's child widgets.
         *
         * @octdoc      widget/setEnabled
         * @public
         * @param       bool            enabled             True enables the widget, false disables it.
         */
        this.setEnabled = function(enabled)
        /**/
        {
            if (disabled = !enabled) {
                return;
            }

            if ((disabled = !enabled)) {
                this.onDisable();
            } else {
                this.onEnable();
            }

            for (var i = 0, cnt = children.length; i < cnt; ++i) {
                children[i].setEnabled(enabled);
            }
        }

        /**
         * Initiate building of child widgets.
         *
         * @octdoc  widget/processChildren
         * @param   array           def                 Widget definition.
         * @param   callback        processor           Callback method for processing
         *                                              child widgets.
         * @param   parent          object              Optional parent DOM node.
         */
        this.processChildren = function(def, processor, parent)
        /**/
        {
            var me = this;

            (function process(parent, def) {
                if (!('children' in def)) return;

                var type, child, widget, instance;

                for (var i = 0, cnt = def['children'].length; i < cnt; ++i) {
                    child = null;

                    for (type in def['children'][i]) {
                        child = def['children'][i][type];
                        break;
                    }

                    if (child == null) {
                        // no child element
                        continue;
                    }

                    widget   = registry[type];
                    name     = ('name' in child ? child['name'] : '');
                    instance = me.addChild(new widget.widget(name, widget.options));

                    processor(parent, instance, child);
                }
            })(parent || node, def);
        }

        /**
         * Add child widget
         *
         * @octdoc      widget/addChild
         * @public
         * @param       oui.widget      instance            Instance of a widget.
         * @return      oui.widget                          The widget instance specified as parameter.
         */
        this.addChild = function(instance)
        /**/
        {
            if (!(instance instanceof oui.widget)) {
                throw 'The parameter specified is not an instance of \'oui.widget\'!';
            }

            // TODO: check, if instance is allowed to add (eg.: by checking options [eg.: container must not be
            //       a child of tile])

            var me = this;

            instance.getDialog = function() {
                return me.getDialog();
            }

            instance.getParent = function() {
                return me;
            }

            children.push(instance);

            return instance;
        }

        /**
         * Create widget. This method is normally called from within the attach method to create
         * the widget container.
         *
         * @octdoc      widget/create
         * @public
         * @param       DOMElement      parent              Parent node to create widget in.
         * @param       object          def                 Widget definition.
         * @return      DOMElement                          Node of new created widget.
         */
        this.create = function(parent, def)
        /**/
        {
            node = oui.$(document.createElement(this.container));
            node.addClass(
                this.cssclass + ('class' in def
                                 ? ' ' + def['class']
                                 : '')
            );

            parent.append(node);

            return node;
        }
    }

    /**
     * Default container type of a widget.
     *
     * @octdoc      widget/container
     * @public
     * @var         string
     */
    oui.widget.prototype.container = 'DIV';
    /**/

    /**
     * Default css class of a widget.
     *
     * @octdoc      widget/cssclass
     * @public
     * @var         string
     */
    oui.widget.prototype.cssclass = 'oui_widget';
    /**/

    /**
     * Return dialog, the widget is assigned to. Returns false, if the widget is not assigned
     * to any dialog.
     *
     * @octdoc      widget/getDialog
     * @public
     * @var         bool|oui.dialog
     */
    oui.widget.prototype.getDialog = function()
    /**/
    {
        return false;
    }

    /**
     * Return parent widget.
     *
     * @octdoc      widget/getParent
     * @public
     * @var         bool|oui.widget
     */
    oui.widget.prototype.getParent = function()
    /**/
    {
        return false;
    }

    /**
     * Build a widget and attach it to a parent node.
     *
     * @octdoc      widget/attach
     * @public
     * @param       DOMElement      parent          Parent node to attach widget to.
     * @param       object          def             Widget definitions.
     */
    oui.widget.prototype.attach = function(parent, def)
    /**/
    {
        this.create(parent, def);

        this.processChildren(def, function(parent, instance, def) {
            instance.attach(parent, def);
        });
    }

    /**
     * Assimilate a part of a page and try to wrap OUI functionality around page elements.
     *
     * @octdoc      widget/assimilate
     * @public
     * @param       DOMElement      node            Node to assimilate.
     */
    oui.widget.prototype.assimilate = function(node)
    /**/
    {
        var me = this;

        (function _assimilate(node) {
            // TODO: implementation
        })(node);
    }

    /**
     * Add a widget object to the registry.
     *
     * @octdoc      widget/register
     * @static
     * @param       string          name            Name of widget to register.
     * @param       object          widget          Widget object.
     * @param       object          options         Optional options for widget creation.
     */
    oui.widget.register = function(name, widget, options)
    /**/
    {
        if (name in registry) {
            throw 'Widget was registered before!';
        } else if (name == 'widget') {
            throw 'A widget cannot have the name \'widget\'!';
        } else {
            registry[name] = {
                'widget':  widget,
                'options': options || {}
            }
        }
    }

    /*
     * event handlers to be overwritten by children
     */

    /**
     * Event handler get's called, when widget get's enabled
     *
     * @octdoc      widget/onEnable
     * @public
     */
    oui.widget.prototype.onEnable = function()
    /**/
    {
    }

    /**
     * Event handler get's called, when widget get's disabled.
     *
     * @octdoc      widget/onDisable
     * @public
     */
    oui.widget.prototype.onDisable = function()
    /**/
    {
    }

    /**
     * Event handler get's called, after widget was populated with data.
     *
     * @octdoc      widget/onPopulate
     * @public
     */
    oui.widget.prototype.onPopulate = function()
    /**/
    {
    }

    /**
     * Event handler get's called, after widget's value get's updated/changed.
     *
     * @octdoc      widget/onChange
     * @public
     */
    oui.widget.prototype.onChange = function()
    /**/
    {
    }

    /**
     * Event handler get's called, when widget is clicked on.
     *
     * @octdoc      widget/onClick
     * @public
     */
    oui.widget.prototype.onClick = function()
    /**/
    {
    }

    /*
     * static methods
     */

    /**
     * Tests if something is registered with a specified widget name.
     *
     * @octdoc      widget/isRegistered
     * @static
     * @param       string          name            Name of widget to test if it's registered.
     */
    oui.widget.isRegistered = function(name)
    /**/
    {
        return (name in registry);
    }
})();
<|endoftext|>


<commit_before>if (!('webkitSpeechRecognition' in window)) {
    var os = getMobileOperatingSystem();
    if (os == 'iOS') {
        $('#os').text(os);
        $('#start').text('請使用 Chrome 語音輸入法');
    } else if (os == 'Android') {
        $('#os').text(os);
        $('#start').text('請使用 Siri 語音輸入法');
    } else {
        swal(
            'Oops...',
            'Something went wrong!',
            'error'
        );
    }
} else {
    $('#os').text('Chrome');
    var recognition = new webkitSpeechRecognition();
    recognition.lang = 'en-US';
    recognition.continuous = false;
    recognition.interimResults = true;

    recognizing = false;

    var final_rst = [];
    var inter_rst = [];

    recognition.onstart = function() {
        recognizing = true;
        update_start_btn();
        console.log('recognition start');
        $('#status').text('正在辨識');
    };

    recognition.onend = function() {
        recognizing = false;
        update_start_btn();
        console.log('recognition end');
    };

    recognition.onresult = function(event) {
        console.log('recognition result');
        update_start_btn();
        $('#status').text('辨識完成');
        console.log(event);
        for (var i = event.resultIndex; i < event.results.length; i++) {
            if (event.results[i].isFinal) {
                final_rst.push(event.results[i][0].transcript);
                $('#result').val(event.results[i][0].transcript);
                $('#final_rst_panel').text(event.results[i][0].transcript);
            } else {
                inter_rst.push(event.results[i][0].transcript);
                $('#inter_rst_panel').text($('#inter_rst_panel').text() + ', ' + event.results[i][0].transcript);
            }
        }

    };

    function reset_recognition() {
        final_rst = [];
        inter_rst = [];
        $('#inter_rst_panel').text('');
        $('#final_rst_panel').text('');
        $('#result').val('');
        update_start_btn();
    }

    function update_start_btn() {
        if (recognizing == true) {
            $('#start').removeClass('btn-primary').addClass('btn-danger');
            $('#start').text('停止辨識');
        } else {
            $('#start').removeClass('btn-danger').addClass('btn-primary');
            $('#start').text('開始辨識');
        }
    }
}

function voice_only_textarea(obj) {
    obj.on('keypress', function(event) {
        console.log('keypress');
        event.preventDefault();
        return false;
    });
    obj.on('paste', function(event) {
        console.log('paste');
        event.preventDefault();
        return false;
    });
}

function getMobileOperatingSystem() {
    var userAgent = navigator.userAgent || navigator.vendor || window.opera;
    if (userAgent.match(/iPad/i) ||
        userAgent.match(/iPhone/i) ||
        userAgent.match(/iPod/i)) {
        return 'iOS';
    } else if (userAgent.match(/Android/i)) {
        return 'Android';
    } else {
        return 'unknown';
    }
}

$(document).ready(function() {
    $('#start').click(function() {
        console.log('click');
        if (recognizing == false) {
            reset_recognition();
            recognition.start();
        } else {
            recognition.stop();
        }
    });
    voice_only_textarea($('#result'));
});
<commit_msg>update<commit_after>if (!('webkitSpeechRecognition' in window)) {
    var os = getMobileOperatingSystem();
    if (os == 'iOS') {
        $('#os').text(os);
        $('#status').text('請使用 Siri 語音輸入法');
        $('#start').hide();
    } else if (os == 'Android') {
        $('#os').text(os);
        $('#status').text('請使用 Chrome 語音輸入法');
        $('#start').hide();
    } else {
        swal(
            'Oops...',
            'Something went wrong!',
            'error'
        );
    }
} else {
    $('#os').text('Chrome');
    var recognition = new webkitSpeechRecognition();
    recognition.lang = 'en-US';
    recognition.continuous = false;
    recognition.interimResults = true;

    recognizing = false;

    var final_rst = [];
    var inter_rst = [];

    recognition.onstart = function() {
        recognizing = true;
        update_start_btn();
        console.log('recognition start');
        $('#status').text('正在辨識');
    };

    recognition.onend = function() {
        recognizing = false;
        update_start_btn();
        console.log('recognition end');
    };

    recognition.onresult = function(event) {
        console.log('recognition result');
        update_start_btn();
        $('#status').text('辨識完成');
        console.log(event);
        for (var i = event.resultIndex; i < event.results.length; i++) {
            if (event.results[i].isFinal) {
                final_rst.push(event.results[i][0].transcript);
                $('#result').val(event.results[i][0].transcript);
                $('#final_rst_panel').text(event.results[i][0].transcript);
            } else {
                inter_rst.push(event.results[i][0].transcript);
                $('#inter_rst_panel').text($('#inter_rst_panel').text() + ', ' + event.results[i][0].transcript);
            }
        }

    };

    function reset_recognition() {
        final_rst = [];
        inter_rst = [];
        $('#inter_rst_panel').text('');
        $('#final_rst_panel').text('');
        $('#result').val('');
        update_start_btn();
    }

    function update_start_btn() {
        if (recognizing == true) {
            $('#start').removeClass('btn-primary').addClass('btn-danger');
            $('#start').text('停止辨識');
        } else {
            $('#start').removeClass('btn-danger').addClass('btn-primary');
            $('#start').text('開始辨識');
        }
    }
}

function voice_only_textarea(obj) {
    obj.on('keypress', function(event) {
        console.log('keypress');
        event.preventDefault();
        return false;
    });
    obj.on('paste', function(event) {
        console.log('paste');
        event.preventDefault();
        return false;
    });
}

function getMobileOperatingSystem() {
    var userAgent = navigator.userAgent || navigator.vendor || window.opera;
    if (userAgent.match(/iPad/i) ||
        userAgent.match(/iPhone/i) ||
        userAgent.match(/iPod/i)) {
        return 'iOS';
    } else if (userAgent.match(/Android/i)) {
        return 'Android';
    } else {
        return 'unknown';
    }
}

$(document).ready(function() {
    $('#start').click(function() {
        console.log('click');
        if (recognizing == false) {
            reset_recognition();
            recognition.start();
        } else {
            recognition.stop();
        }
    });
    voice_only_textarea($('#result'));
});
<|endoftext|>


<commit_before>angular.module("ui.timepicker", ["angularMoment"])
    .directive("uiTimepicker", ["moment", function (moment) {
        return {
            restrict: "EA",

            require: 'ngModel',

            scope: {
                datetime: '=ngModel'
            },

            replace: true,

            template: '

',

            link: function (scope, element, attrs) {
                var _selection = d3.select(element[0]);

                var _arc = d3.svg.arc().startAngle(0 * (Math.PI / 180)).endAngle(360 * (Math.PI / 180));

                var _w = 200;
                var _h = _w;
                var _diameter = _w;
                var _margin = { top:10, right:10, bottom:10, left:10 };
                var _fontSize = 10;

                var _width;
                var _height;
                var _x0;
                var _y0;

                var _minValue = 1;
                var _maxValue = 720;
                var _value = 1;

                _selection.each(function (data) {
                    measure();

                    var svg = d3.select(this).selectAll("svg").data([data]);

                    var enter = svg.enter().append("svg")
                        .attr("class", "x1-timepicker-svg").append("g")
                        .attr("transform", "translate(" + _margin.left + "," + _margin.top + ")");

                    svg.attr("width", _w).attr("height", _h);

                    var background = enter.append("g")
                        .attr("class", "x1-timepicker-component");

                    var body = background.append("circle")
                        .attr("class", "x1-timepicker-inner")
                        .attr("transform", "translate(" + _x0 + "," + _y0 + ")")
                        .attr("cx", 0)
                        .attr("cy", 0)
                        .attr("r", _width / 2);

                    var slider = background.append("path")
                        .attr("transform", "translate(" + _x0 + "," + _y0 + ")")
                        .attr("d", _arc);

                    var arcContainer = enter.append("g")
                        .attr("class", "x1-timepicker-arcs");

                    var selectedArc = arcContainer.append("path")
                        .attr("class", "arc")
                        .attr("transform", "translate(" + _x0 + "," + _y0 + ")")
                        .attr("d", _arc);

                    // ---------- labels for the picker ------------------------------------------
                    var labels = enter.append("g")
                        .attr("class", "x1-timepicker-labels");

                    var labelSendAt = labels.append("text")
                        .attr("class", "title")
                        .attr("x", _x0)
                        .attr("y", _width / 4.2 + _fontSize / 3)
                        .attr("width", _width)
                        .text("Time")
                        .style("font-size", (_fontSize * 0.4) + "px");

                    var labelTime = labels.append("text")
                        .attr("class", "time")
                        .attr("x", _x0)
                        .attr("y", _y0 + _fontSize / 3)
                        .attr("width", _width)
                        .style("font-size", (_fontSize * 1.4) + "px");

                    var labelAMPM = labels.append("text")
                        .attr("class", "ampm")
                        .attr("cursor", "pointer")
                        .attr("x", _x0)
                        .attr("y", _width / 1.4 + _fontSize / 3)
                        .attr("width", _width)
                        .style("font-size", (_fontSize * 0.6) + "px")
                        .on("click", function () {
                            if (isAM(scope.datetime)) {
                                d3.select(this).text("PM");
                                scope.datetime = moment(scope.datetime).add(+12, 'hour').toDate();
                            } else {
                                d3.select(this).text("AM");
                                scope.datetime = moment(scope.datetime).add(-12, 'hour').toDate();
                            }
                            scope.$apply();
                        });

                    // ---------- slider handler ------------------------------------------
                    var drag = d3.behavior.drag().on("drag", function () {
                        var eventX = d3.event.x;
                        var eventY = d3.event.y;

                        // --------------------------
                        var _C = Math.PI * _width;

                        var ox = 0;
                        var oy = 0;

                        var ax = 0;
                        var ay = _height / 2;

                        var bx = eventX - _width / 2;
                        var by = _height / 2 - eventY;

                        var k = (by - oy)/(bx - ox);

                        var angel = Math.abs(Math.atan(k) / (Math.PI / 180));
                        var targetAngel = 0;

                        if (bx > 0 && by >= 0) {
                            targetAngel = 90 - angel;
                        } else if (bx >= 0 && by < 0) {
                            targetAngel = 90 + angel;
                        } else if (bx < 0 && by <= 0) {
                            targetAngel = 270 - angel;
                        } else if (bx <= 0 && by > 0) {
                            targetAngel = 270 + angel;
                        }

                        _value = _maxValue * (targetAngel / 360);

                        // update scope.datetime
                        var hours = Math.floor(_value / 60);
                        var minutes = _value % 60;

                        scope.datetime = moment(scope.datetime)
                            .set('hour', (isAM(scope.datetime) ? hours : (hours + 12)))
                            .set('minute', minutes)
                            .set('second', 0)
                            .toDate();

                        scope.$apply(function(){
                            setCurrent(selectedArc, handler, labelTime, labelAMPM);
                        });
                    });

                    var handler = enter.append("g").append("circle")
                        .attr("class", "x1-timepicker-handler")
                        .attr("cursor", "pointer")
                        .attr("transform", "translate(" + _x0 + "," + _y0 + ")")
                        .attr("cx", 0)
                        .attr("cy", 0)
                        .attr("r", 10)
                        .attr("fill", "#FFFFFF")
                        .call(drag);

                    // ---------- set the init value from ng-model ----------------------------------------------
                    var hours = moment(scope.datetime).hours();
                    var hours12 = hours >= 12 ? hours - 12 : hours;
                    var minutes = moment(scope.datetime).minutes();

                    _value = (hours12 * 60 + minutes);

                    setCurrent(selectedArc, handler, labelTime, labelAMPM);
                });

                function isAM (date) {
                    return moment(date).format("A") === "AM";
                }

                function measure () {
                    _width = _height = _diameter - _margin.right - _margin.left - _margin.top - _margin.bottom;
                    _x0 = _y0 = _width / 2;
                    _fontSize = _width * .2;
                    _arc.outerRadius(_width / 2);
                    _arc.innerRadius(_width / 2 * .85);
                }

                function setCurrent (selectedArc, handler, labelTime, labelAMPM) {
                    // set the selected arc
                    var ratio = Math.min((_value - _minValue) / (_maxValue - _minValue), 1);
                    var endAng = Math.min(360 * ratio, 360) * Math.PI / 180;
                    _arc.endAngle(endAng);
                    selectedArc.attr("d", _arc);

                    // set the handler position
                    var oAngel = 360 * _value / _maxValue;
                    var r = _width / 2 - 5;
                    var x = r * Math.cos((oAngel - 90) * Math.PI / 180);
                    var y = r * Math.sin((oAngel - 90) * Math.PI / 180);
                    handler.attr('cx', x).attr('cy', y);

                    // update time label
                    var hours = moment(scope.datetime).hours();
                    var hours12 = hours >= 12 ? hours - 12 : hours;
                    var minutes = moment(scope.datetime).minutes();

                    var lbTime = "" + hours12 + ":";
                    if (minutes < 10) {
                        lbTime += "0";
                    }
                    lbTime += minutes;

                    labelTime.text(lbTime);
                    labelAMPM.text(moment(scope.datetime).format("A"));
                }

            }
        };
    }]);
<commit_msg>fix bug<commit_after>angular.module("ui.timepicker", ["angularMoment"])
    .directive("uiTimepicker", ["moment", function (moment) {
        return {
            restrict: "EA",

            require: 'ngModel',

            scope: {
                datetime: '=ngModel'
            },

            replace: true,

            template: '

',

            link: function (scope, element, attrs) {
                var _selection = d3.select(element[0]);

                var _arc = d3.svg.arc().startAngle(0 * (Math.PI / 180)).endAngle(360 * (Math.PI / 180));

                var _w = 200;
                var _h = _w;
                var _diameter = _w;
                var _margin = { top:10, right:10, bottom:10, left:10 };
                var _fontSize = 10;

                var _width;
                var _height;
                var _x0;
                var _y0;

                var _minValue = 1;
                var _maxValue = 720;
                var _value = 1;

                _selection.each(function (data) {
                    measure();

                    var svg = d3.select(this).selectAll("svg").data([data]);

                    var enter = svg.enter().append("svg")
                        .attr("class", "x1-timepicker-svg").append("g")
                        .attr("transform", "translate(" + _margin.left + "," + _margin.top + ")");

                    svg.attr("width", _w).attr("height", _h);

                    var background = enter.append("g")
                        .attr("class", "x1-timepicker-component");

                    var body = background.append("circle")
                        .attr("class", "x1-timepicker-inner")
                        .attr("transform", "translate(" + _x0 + "," + _y0 + ")")
                        .attr("cx", 0)
                        .attr("cy", 0)
                        .attr("r", _width / 2);

                    var slider = background.append("path")
                        .attr("transform", "translate(" + _x0 + "," + _y0 + ")")
                        .attr("d", _arc);

                    var arcContainer = enter.append("g")
                        .attr("class", "x1-timepicker-arcs");

                    var selectedArc = arcContainer.append("path")
                        .attr("class", "arc")
                        .attr("transform", "translate(" + _x0 + "," + _y0 + ")")
                        .attr("d", _arc);

                    // ---------- labels for the picker ------------------------------------------
                    var labels = enter.append("g")
                        .attr("class", "x1-timepicker-labels");

                    var labelSendAt = labels.append("text")
                        .attr("class", "title")
                        .attr("x", _x0)
                        .attr("y", _width / 4.2 + _fontSize / 3)
                        .attr("width", _width)
                        .text("Time")
                        .style("font-size", (_fontSize * 0.4) + "px");

                    var labelTime = labels.append("text")
                        .attr("class", "time")
                        .attr("x", _x0)
                        .attr("y", _y0 + _fontSize / 3)
                        .attr("width", _width)
                        .style("font-size", (_fontSize * 1.4) + "px");

                    var labelAMPM = labels.append("text")
                        .attr("class", "ampm")
                        .attr("cursor", "pointer")
                        .attr("x", _x0)
                        .attr("y", _width / 1.4 + _fontSize / 3)
                        .attr("width", _width)
                        .style("font-size", (_fontSize * 0.6) + "px")
                        .on("click", function () {
                            var offset = isAM(scope.datetime) ? 12 : -12;
                            scope.datetime = moment(scope.datetime).add(offset, 'hour').toDate();
                            d3.select(this).text(moment(scope.datetime).format("A"));
                            scope.$apply();
                        });

                    // ---------- slider handler ------------------------------------------
                    var drag = d3.behavior.drag().on("drag", function () {
                        var eventX = d3.event.x;
                        var eventY = d3.event.y;

                        // --------------------------
                        var _C = Math.PI * _width;

                        var ox = 0;
                        var oy = 0;

                        var ax = 0;
                        var ay = _height / 2;

                        var bx = eventX - _width / 2;
                        var by = _height / 2 - eventY;

                        var k = (by - oy)/(bx - ox);

                        var angel = Math.abs(Math.atan(k) / (Math.PI / 180));
                        var targetAngel = 0;

                        if (bx > 0 && by >= 0) {
                            targetAngel = 90 - angel;
                        } else if (bx >= 0 && by < 0) {
                            targetAngel = 90 + angel;
                        } else if (bx < 0 && by <= 0) {
                            targetAngel = 270 - angel;
                        } else if (bx <= 0 && by > 0) {
                            targetAngel = 270 + angel;
                        }

                        _value = _maxValue * (targetAngel / 360);

                        // update scope.datetime
                        var hours = Math.floor(_value / 60);
                        var minutes = _value % 60;

                        scope.datetime = moment(scope.datetime)
                            .set('hour', (isAM(scope.datetime) ? hours : (hours + 12)))
                            .set('minute', minutes)
                            .set('second', 0)
                            .toDate();

                        scope.$apply(function(){
                            setCurrent(selectedArc, handler, labelTime, labelAMPM);
                        });
                    });

                    var handler = enter.append("g").append("circle")
                        .attr("class", "x1-timepicker-handler")
                        .attr("cursor", "pointer")
                        .attr("transform", "translate(" + _x0 + "," + _y0 + ")")
                        .attr("cx", 0)
                        .attr("cy", 0)
                        .attr("r", 10)
                        .attr("fill", "#FFFFFF")
                        .call(drag);

                    // ---------- set the init value from ng-model ----------------------------------------------
                    var updateValue = function (v) {
                        var hours = moment(v).hours();
                        var hours12 = hours >= 12 ? hours - 12 : hours;
                        var minutes = moment(v).minutes();
                        _value = (hours12 * 60 + minutes);
                        setCurrent(selectedArc, handler, labelTime, labelAMPM);
                    };

                    updateValue(scope.datetime);

                    scope.$watch("datetime", function (newVal, oldVal) {
                        updateValue(newVal);
                    });
                });

                function isAM (date) {
                    return moment(date).format("A") === "AM";
                }

                function measure () {
                    _width = _height = _diameter - _margin.right - _margin.left - _margin.top - _margin.bottom;
                    _x0 = _y0 = _width / 2;
                    _fontSize = _width * .2;
                    _arc.outerRadius(_width / 2);
                    _arc.innerRadius(_width / 2 * .85);
                }

                function setCurrent (selectedArc, handler, labelTime, labelAMPM) {
                    // set the selected arc
                    var ratio = Math.min((_value - _minValue) / (_maxValue - _minValue), 1);
                    var endAng = Math.min(360 * ratio, 360) * Math.PI / 180;
                    _arc.endAngle(endAng);
                    selectedArc.attr("d", _arc);

                    // set the handler position
                    var oAngel = 360 * _value / _maxValue;
                    var r = _width / 2 - 5;
                    var x = r * Math.cos((oAngel - 90) * Math.PI / 180);
                    var y = r * Math.sin((oAngel - 90) * Math.PI / 180);
                    handler.attr('cx', x).attr('cy', y);

                    // update time label
                    var hours = moment(scope.datetime).hours();
                    var hours12 = hours >= 12 ? hours - 12 : hours;
                    var minutes = moment(scope.datetime).minutes();

                    var lbTime = "" + hours12 + ":";
                    if (minutes < 10) {
                        lbTime += "0";
                    }
                    lbTime += minutes;

                    labelTime.text(lbTime);
                    labelAMPM.text(moment(scope.datetime).format("A"));
                }

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


<commit_before>function AI() {

	this.moves = [0,1,2,3];
	this.brain = new deepqlearn.Brain(19,4, {
		epsilon_test_time: 0.1,
		epsilon_min: 0.1,
		experience_size: 300000
	});
	this.previousMove = 0;
	this.previousMoved = false;
}

AI.prototype.getMaxVal = function() {
	var max = 0;
	this.grid.cells.forEach(function(row){
		row.forEach( function( curVal ){
			if( curVal && curVal.value > max )
				max = curVal.value;
		});
	});

	if( StateManager.maxVal < max ){
		StateManager.maxVal = max;
		document.getElementById('max-value').innerHTML = 'Max Value is: ' + max;
	}

	return max;
}

AI.prototype.getEmptyCount = function() {

	var count = 0;
	this.grid.cells.forEach(function(row) {
		row.forEach( function( curVal ) {
			if( curVal )
				return;

			count++;
		});
	});

	return count;

}

AI.prototype.buildInputs = function(score, moved, timesMoved, pMove) {

	var inputs = [];

	var max = this.getMaxVal();

	this.grid.cells.forEach(function(row, index) {
		row.forEach( function( curVal ) {

			if( curVal ){
				inputs.push( ( 1 + ( -1 / curVal.value ) ) );
			}else{
				inputs.push(0);
			}
		});
	});

	inputs.push( ( this.previousMove > 0 ) ? this.previousMove / 4      : 0 );
	inputs.push( ( score > 0 )             ? ( 1 + ( -1 / score ) )     : 0 );
	inputs.push( ( moved )                 ? 1                          : 0 );
	inputs.push( ( this.getEmptyCount() > 0 ) ? this.getEmptyCount()    : 0 );

//	console.log('Inputs: ', inputs);
	return inputs;

}

AI.prototype.getBest = function(grid, meta) {
	this.grid = grid;
	var inputs = this.buildInputs( meta.score, meta.moved );
	var action = this.brain.forward( inputs );

	var move = {
		move: this.moves[action]
	};

	this.previousMove = move.move;

	return move;

}

AI.prototype.setMoved = function(moved){
	this.previousMoved = moved;
}

AI.prototype.reward = function(meta) {

	var max = this.getMaxVal();
	if( meta.over && meta.won ){

		reward = 1;

	}else if( meta.score != meta.previous ) {

		reward  = ( 1 + (-1 / ( meta.score - meta.previous ) ) );
		reward += ( ( meta.empty > 0 ) ? ( meta.empty / 16 ) : 0 );
		reward /= 4;

	}else{

		reward = -(0.5);

	}

	if( meta.over && !meta.won ){
//		console.log('Inverting Reward due to Loss');
		reward *= -1;
	}
//	console.log('Reward: ', reward );
	this.brain.backward( reward );
	this.brain.visSelf(document.getElementById('brainInfo'));

}

AI.prototype.rewardMultiple = function(meta){

	var max = this.getMaxVal();
	var scoreReward = ( 1 + (-1 / (meta.score - meta.previous ) ) );
	var maxReward = ( 1 + ( ( -1 * max ) / meta.score ) );
	var movesReward = ( ( meta.timesMoved > 0 ) ? ( 1 + (-1 / meta.timesMoved ) ) : 0);
	var emptyReward = ( ( meta.empty > 0 ) ? ( 1 + (-1 / meta.empty ) ) : 0 );

	this.brain.backward( scoreReward );
	this.brain.backward( maxReward );
	this.brain.backward( movesReward );
	this.brain.backward( emptyReward );
	this.brain.visSelf(document.getElementById('brainInfo'));

}
<commit_msg>Cut reward down to points<commit_after>function AI() {

	this.moves = [0,1,2,3];
	this.brain = new deepqlearn.Brain(19,4, {
		epsilon_test_time: 0.1,
		epsilon_min: 0.1,
		experience_size: 300000
	});
	this.previousMove = 0;
	this.previousMoved = false;
}

AI.prototype.getMaxVal = function() {
	var max = 0;
	this.grid.cells.forEach(function(row){
		row.forEach( function( curVal ){
			if( curVal && curVal.value > max )
				max = curVal.value;
		});
	});

	if( StateManager.maxVal < max ){
		StateManager.maxVal = max;
		document.getElementById('max-value').innerHTML = 'Max Value is: ' + max;
	}

	return max;
}

AI.prototype.getEmptyCount = function() {

	var count = 0;
	this.grid.cells.forEach(function(row) {
		row.forEach( function( curVal ) {
			if( curVal )
				return;

			count++;
		});
	});

	return count;

}

AI.prototype.buildInputs = function(score, moved, timesMoved, pMove) {

	var inputs = [];

	var max = this.getMaxVal();

	this.grid.cells.forEach(function(row, index) {
		row.forEach( function( curVal ) {

			if( curVal ){
				inputs.push( ( 1 + ( -1 / curVal.value ) ) );
			}else{
				inputs.push(0);
			}
		});
	});

	inputs.push( ( this.previousMove > 0 ) ? this.previousMove / 4      : 0 );
	inputs.push( ( score > 0 )             ? ( 1 + ( -1 / score ) )     : 0 );
	inputs.push( ( moved )                 ? 1                          : 0 );
	inputs.push( ( this.getEmptyCount() > 0 ) ? this.getEmptyCount()    : 0 );

//	console.log('Inputs: ', inputs);
	return inputs;

}

AI.prototype.getBest = function(grid, meta) {
	this.grid = grid;
	var inputs = this.buildInputs( meta.score, meta.moved );
	var action = this.brain.forward( inputs );

	var move = {
		move: this.moves[action]
	};

	this.previousMove = move.move;

	return move;

}

AI.prototype.setMoved = function(moved){
	this.previousMoved = moved;
}

AI.prototype.reward = function(meta) {

	var max = this.getMaxVal();
	if( meta.over && meta.won ){

		reward = 1;

	}else if( meta.score != meta.previous ) {

		reward  = ( 1 + (-1 / ( meta.score - meta.previous ) ) );
	//	reward += ( ( meta.empty > 0 ) ? ( meta.empty / 16 ) : 0 );
	//	reward /= 4;

	}else{

		reward = -(0.5);

	}

	if( meta.over && !meta.won ){
//		console.log('Inverting Reward due to Loss');
		reward *= -1;
	}
//	console.log('Reward: ', reward );
	this.brain.backward( reward );
	this.brain.visSelf(document.getElementById('brainInfo'));

}

AI.prototype.rewardMultiple = function(meta){

	var max = this.getMaxVal();
	var scoreReward = ( 1 + (-1 / (meta.score - meta.previous ) ) );
	var maxReward = ( 1 + ( ( -1 * max ) / meta.score ) );
	var movesReward = ( ( meta.timesMoved > 0 ) ? ( 1 + (-1 / meta.timesMoved ) ) : 0);
	var emptyReward = ( ( meta.empty > 0 ) ? ( 1 + (-1 / meta.empty ) ) : 0 );

	this.brain.backward( scoreReward );
	this.brain.backward( maxReward );
	this.brain.backward( movesReward );
	this.brain.backward( emptyReward );
	this.brain.visSelf(document.getElementById('brainInfo'));

}
<|endoftext|>


<commit_before>$(document).ready(function(){
  $('.content article').each(function(){
   var thisA=$(this),
    articlePos=this.offset.top;
      $(window).scroll(function(){
        var wTop=$(this).scrollTop();
        if(wTop>articlePos){
          this.addClass('active');
        }
      });
  });
});
<commit_msg>Update js.js<commit_after>$(document).ready(function(){
  $('.content article').each(function(){
   var thisA=$(this),
    articlePos=thisA.offset.top;
      $(window).scroll(function(){
        var wTop=$(this).scrollTop();
        if(wTop>articlePos){
          thisA.addClass('active');
        }
      });
  });
});
<|endoftext|>