<commit_before>function loadCustomerAddressInfo( customerNumberFieldName ) {
	var customerNumber = DWRUtil.getValue( customerNumberFieldName );

	if (customerNumber == '') {
		clearAddressFields();
		return;
	}
	else {
		customerNumber = customerNumber.toUpperCase();
	}

	var dwrReply = {
		callback:function(data) {
			if ( data != null && typeof data == 'object' ) {
				setAddressFields(data);
			}
			else {
				clearAddressFields();
			}
		},
		errorHandler:function( errorMessage ) {

		}
	};
	CustomerAddressService.getPrimaryAddress( customerNumber, dwrReply );
}

function setAddressFields( data ) {
	setRecipientValueIgnoreNull( "document.customerBillToAddressIdentifier",          data.customerAddressIdentifier );
    setRecipientValueIgnoreNull( "document.billingCityName",                          data.customerCityName );
	setRecipientValueIgnoreNull( "document.billingAddressTypeCode",                   data.customerAddressTypeCode );
	setRecipientValueIgnoreNull( "document.billingStateCode",                         data.customerStateCode );
	setRecipientValueIgnoreNull( "document.billingAddressName",                       data.customerAddressName );
	setRecipientValueIgnoreNull( "document.billingZipCode",                           data.customerZipCode );
	setRecipientValueIgnoreNull( "document.billingLine1StreetAddress",                data.customerLine1StreetAddress );
	setRecipientValueIgnoreNull( "document.billingAddressInternationalProvinceName",  data.customerAddressInternationalProvinceName );
	setRecipientValueIgnoreNull( "document.billingLine2StreetAddress",                data.customerLine2StreetAddress );
	setRecipientValueIgnoreNull( "document.billingInternationalMailCode",             data.customerInternationalMailCode );
	setRecipientValueIgnoreNull( "document.billingEmailAddress",                      data.customerEmailAddress );
	setRecipientValueIgnoreNull( "document.billingCountryCode",                       data.customerCountryCode );

    setRecipientValueIgnoreNull( "document.customerShipToAddressIdentifier",          data.customerAddressIdentifier );
    setRecipientValueIgnoreNull( "document.shippingCityName",                          data.customerCityName );
	setRecipientValueIgnoreNull( "document.shippingAddressTypeCode",                   data.customerAddressTypeCode );
	setRecipientValueIgnoreNull( "document.shippingStateCode",                         data.customerStateCode );
	setRecipientValueIgnoreNull( "document.shippingAddressName",                       data.customerAddressName );
	setRecipientValueIgnoreNull( "document.shippingZipCode",                           data.customerZipCode );
	setRecipientValueIgnoreNull( "document.shippingLine1StreetAddress",                data.customerLine1StreetAddress );
	setRecipientValueIgnoreNull( "document.shippingAddressInternationalProvinceName",  data.customerAddressInternationalProvinceName );
	setRecipientValueIgnoreNull( "document.shippingLine2StreetAddress",                data.customerLine2StreetAddress );
	setRecipientValueIgnoreNull( "document.shippingInternationalMailCode",             data.customerInternationalMailCode );
	setRecipientValueIgnoreNull( "document.shippingEmailAddress",                      data.customerEmailAddress );
	setRecipientValueIgnoreNull( "document.shippingCountryCode",                       data.customerCountryCode );
}

function clearAddressFields() {
	setRecipientValueIgnoreNull( "document.customerBillToAddressIdentifier", "" );
	setRecipientValueIgnoreNull( "document.billingCityName", "" );
	setRecipientValueIgnoreNull( "document.billingAddressTypeCode", "" );
	setRecipientValueIgnoreNull( "document.billingStateCode", "" );
	setRecipientValueIgnoreNull( "document.billingAddressName", "" );
	setRecipientValueIgnoreNull( "document.billingZipCode", "" );
	setRecipientValueIgnoreNull( "document.billingLine1StreetAddress", "" );
	setRecipientValueIgnoreNull( "document.billingAddressInternationalProvinceName", "" );
	setRecipientValueIgnoreNull( "document.billingLine2StreetAddress", "" );
	setRecipientValueIgnoreNull( "document.billingInternationalMailCode", "" );
	setRecipientValueIgnoreNull( "document.billingEmailAddress", "" );
	setRecipientValueIgnoreNull( "document.billingCountryCode", "" );

    setRecipientValueIgnoreNull( "document.customerShipToAddressIdentifier", "" );
    setRecipientValueIgnoreNull( "document.shippingCityName", "" );
	setRecipientValueIgnoreNull( "document.shippingAddressTypeCode", "" );
	setRecipientValueIgnoreNull( "document.shippingStateCode", "" );
	setRecipientValueIgnoreNull( "document.shippingAddressName", "" );
	setRecipientValueIgnoreNull( "document.shippingZipCode", "" );
	setRecipientValueIgnoreNull( "document.shippingLine1StreetAddress", "" );
	setRecipientValueIgnoreNull( "document.shippingAddressInternationalProvinceName", "" );
	setRecipientValueIgnoreNull( "document.shippingLine2StreetAddress", "" );
	setRecipientValueIgnoreNull( "document.shippingInternationalMailCode", "" );
	setRecipientValueIgnoreNull( "document.shippingEmailAddress", "" );
	setRecipientValueIgnoreNull( "document.shippingCountryCode", "" );
}

//	this is here instead of using setRecipientValue in dhtml.js because that other
// one chokes and pukes when value == null.
function setRecipientValueIgnoreNull(recipientBase, value, isError ) {

    if (value) {
    	value = value.toString().trim();
    }
    else {
    	value = '';
    }

    var containerHidden = document.getElementById(recipientBase);
    if ( !containerHidden ) {
	    containerHidden = kualiElements[recipientBase];
    }
    var containerDiv = document.getElementById(recipientBase + divSuffix);
    if (containerDiv) {
		if (value == '') {
			DWRUtil.setValue( containerDiv.id, " " );
		} else {
			DWRUtil.setValue( containerDiv.id, value, isError?null:{escapeHtml:true} );
		}
	}
    if (containerHidden) {
    	// get rid of HTML in the value
    	value = value.replace(/(<([^>]+)>)/ig,"");
		DWRUtil.setValue( recipientBase, value );
	}
}

<commit_msg>KULAR-578<commit_after>function loadCustomerAddressInfo( customerNumberFieldName ) {
	var customerNumber = DWRUtil.getValue( customerNumberFieldName );

	if (customerNumber == '') {
		clearAddressFields();
		return;
	}
	else {
		customerNumber = customerNumber.toUpperCase();
	}

	var dwrReply = {
		callback:function(data) {
			if ( data != null && typeof data == 'object' ) {
				setAddressFields(data);
			}
			else {
				clearAddressFields();
			}
		},
		errorHandler:function( errorMessage ) {

		}
	};
	CustomerAddressService.getPrimaryAddress( customerNumber, dwrReply );
}

function setAddressFields( data ) {
	setRecipientValueIgnoreNull( "document.customerBillToAddressIdentifier",          data.customerAddressIdentifier );
    setRecipientValueIgnoreNull( "document.billingCityName",                          data.customerCityName );
	setRecipientValueIgnoreNull( "document.billingAddressTypeCode",                   data.customerAddressTypeCode );
	setRecipientValueIgnoreNull( "document.billingStateCode",                         data.customerStateCode );
	setRecipientValueIgnoreNull( "document.billingAddressName",                       data.customerAddressName );
	setRecipientValueIgnoreNull( "document.billingZipCode",                           data.customerZipCode );
	setRecipientValueIgnoreNull( "document.billingLine1StreetAddress",                data.customerLine1StreetAddress );
	setRecipientValueIgnoreNull( "document.billingAddressInternationalProvinceName",  data.customerAddressInternationalProvinceName );
	setRecipientValueIgnoreNull( "document.billingLine2StreetAddress",                data.customerLine2StreetAddress );
	setRecipientValueIgnoreNull( "document.billingInternationalMailCode",             data.customerInternationalMailCode );
	setRecipientValueIgnoreNull( "document.billingEmailAddress",                      data.customerEmailAddress );
	setRecipientValueIgnoreNull( "document.billingCountryCode",                       data.customerCountryCode );
}

function clearAddressFields() {
	setRecipientValueIgnoreNull( "document.customerBillToAddressIdentifier", "" );
	setRecipientValueIgnoreNull( "document.billingCityName", "" );
	setRecipientValueIgnoreNull( "document.billingAddressTypeCode", "" );
	setRecipientValueIgnoreNull( "document.billingStateCode", "" );
	setRecipientValueIgnoreNull( "document.billingAddressName", "" );
	setRecipientValueIgnoreNull( "document.billingZipCode", "" );
	setRecipientValueIgnoreNull( "document.billingLine1StreetAddress", "" );
	setRecipientValueIgnoreNull( "document.billingAddressInternationalProvinceName", "" );
	setRecipientValueIgnoreNull( "document.billingLine2StreetAddress", "" );
	setRecipientValueIgnoreNull( "document.billingInternationalMailCode", "" );
	setRecipientValueIgnoreNull( "document.billingEmailAddress", "" );
	setRecipientValueIgnoreNull( "document.billingCountryCode", "" );

    setRecipientValueIgnoreNull( "document.customerShipToAddressIdentifier", "" );
    setRecipientValueIgnoreNull( "document.shippingCityName", "" );
	setRecipientValueIgnoreNull( "document.shippingAddressTypeCode", "" );
	setRecipientValueIgnoreNull( "document.shippingStateCode", "" );
	setRecipientValueIgnoreNull( "document.shippingAddressName", "" );
	setRecipientValueIgnoreNull( "document.shippingZipCode", "" );
	setRecipientValueIgnoreNull( "document.shippingLine1StreetAddress", "" );
	setRecipientValueIgnoreNull( "document.shippingAddressInternationalProvinceName", "" );
	setRecipientValueIgnoreNull( "document.shippingLine2StreetAddress", "" );
	setRecipientValueIgnoreNull( "document.shippingInternationalMailCode", "" );
	setRecipientValueIgnoreNull( "document.shippingEmailAddress", "" );
	setRecipientValueIgnoreNull( "document.shippingCountryCode", "" );
}

//	this is here instead of using setRecipientValue in dhtml.js because that other
// one chokes and pukes when value == null.
function setRecipientValueIgnoreNull(recipientBase, value, isError ) {

    if (value) {
    	value = value.toString().trim();
    }
    else {
    	value = '';
    }

    var containerHidden = document.getElementById(recipientBase);
    if ( !containerHidden ) {
	    containerHidden = kualiElements[recipientBase];
    }
    var containerDiv = document.getElementById(recipientBase + divSuffix);
    if (containerDiv) {
		if (value == '') {
			DWRUtil.setValue( containerDiv.id, " " );
		} else {
			DWRUtil.setValue( containerDiv.id, value, isError?null:{escapeHtml:true} );
		}
	}
    if (containerHidden) {
    	// get rid of HTML in the value
    	value = value.replace(/(<([^>]+)>)/ig,"");
		DWRUtil.setValue( recipientBase, value );
	}
}

<|endoftext|>


<commit_before>define([
	"intern!object",
	"intern/chai!assert",
	"dojo/on",
	"delite/handlebars",
	"delite/register",
	"delite/Widget",
	"delite/handlebars!./templates/SimpleHandleBarsButton.html",
	"delite/handlebars!./templates/HandlebarsButton.html",
	"delite/handlebars!./templates/SvgWidget.html"
], function (registerSuite, assert,  on, handlebars,register, Widget, simpleHBTmpl, buttonHBTmpl, svgTmpl) {
	var container, myButton;
	registerSuite({
		name: "handlebars",
		setup: function () {
			container = document.createElement("div");
			document.body.appendChild(container);
		},
		"load" : function () {
			// Test that function returned from delite/handlebars! creates the template correctly
			var TestButton = register("test-button", [HTMLButtonElement, Widget], {
				iconClass: "originalClass",
				label: "original label",
				buildRendering: simpleHBTmpl
			});
			myButton = new TestButton();
			assert.strictEqual(myButton.tagName.toLowerCase(), "button", "root node exists");
			assert.strictEqual(myButton.firstChild.tagName.toLowerCase(), "span", "icon node exists too");
			assert.strictEqual(myButton.firstChild.className, "duiReset originalClass", "icon class set");
			assert.strictEqual(myButton.textContent.trim(), "original label", "label set");
		},
		"update" : function () {
			myButton.label = "new label";
			assert.strictEqual(myButton.textContent.trim(), "new label", "label updated");

			myButton.iconClass = "newClass";
			assert.strictEqual(myButton.firstChild.className, "duiReset newClass", "icon class set");

		},
		"branching" : function () {
			var NoLabelButton = register("no-label-button", [HTMLButtonElement, Widget], {
				iconClass: "originalClass",
				showLabel: false,
				label: "original label",
				buildRendering: buttonHBTmpl
			});
			myButton = new NoLabelButton();
			assert.strictEqual(myButton.tagName.toLowerCase(), "button", "root node exists");
			assert.strictEqual(myButton.firstChild.tagName.toLowerCase(), "span", "icon node exists too");
			assert.strictEqual(myButton.firstChild.className, "duiReset originalClass", "icon class set");
			assert.strictEqual(myButton.textContent.trim(), "", "no label");
			myButton.label = "new label";
			assert.strictEqual(myButton.textContent.trim(), "", "still no label");

			// Test true if condition
			var LabelButton = register("label-button", [HTMLButtonElement, Widget], {
				iconClass: "originalClass",
				showLabel: true,
				label: "original label",
				buildRendering: buttonHBTmpl
			});
			myButton = new LabelButton();
			assert.strictEqual(myButton.tagName.toLowerCase(), "button", "root node exists");
			assert.strictEqual(myButton.firstChild.tagName.toLowerCase(), "span", "icon node exists too");
			assert.strictEqual(myButton.firstChild.className, "duiReset originalClass", "icon class set");
			assert.strictEqual(myButton.textContent.trim(), "original label", "label");

			// Make sure that changes still work
			myButton.label = "new label";
			assert.strictEqual(myButton.textContent.trim(), "new label", "label updated");

		},
		"Special props" : function () {
			var SpecialPropsWidget = register("special-props", [HTMLElement, Widget], {
				inputClass: "originalClass",	// attribute called "class" but property called "className"
				inputValue: "original value",	// must be set as property
				role: "originalRole",			// must be set as attribute
				buildRendering: handlebars.compile(
					'<special-props><input class="{{inputClass}}" value="{{inputValue}}" role="{{role}}"/></special-props>'
				)
			});
			var mySpecialPropsWidget = new SpecialPropsWidget();
			var input = mySpecialPropsWidget.children[0];

			assert.strictEqual(input.value, "original value", "value set as property");
			assert.strictEqual(input.className, "originalClass",
				"class set even though property is called className, not class");
			assert.strictEqual(input.getAttribute("role"), "originalRole", "role set as attribute");

			mySpecialPropsWidget.mix({
				inputClass: "newClass",
				inputValue: "new value",
				role: "newRole"
			});
			assert.strictEqual(input.value, "new value", "value changed");
			assert.strictEqual(input.className, "newClass", "class changed");
			assert.strictEqual(input.getAttribute("role"), "newRole", "role changed");

			// TODO: implement and then test reverse binding, from input.value --> widget.value?
		},
		"special characters" : function () {
			// Test that special characters are escaped.  This is actually testing template.js.
			var TestList = register("test-ul", [ HTMLUListElement, Widget], {
				label: "bill'\\",
				buildRendering: handlebars.compile(
					"

\"\\{{label}}\n\twas \n\there'

")
			});
			myList = new TestList();
			assert.strictEqual(myList.tagName.toLowerCase(), "ul", "root node exists");
			assert.strictEqual(myList.firstChild.tagName.toLowerCase(), "li", "child exists");
			assert.strictEqual(myList.firstChild.getAttribute("foo"), "a.b('c,d')", "single quotes prop");
			assert.strictEqual(myList.firstChild.getAttribute("bar"), "\\\"hello\"", "double quotes, backslash prop");
			assert.strictEqual(myList.firstChild.textContent, "\"\\bill'\\ was here'", "node text");
		},
		events : function () {
			// Test that listeners like onclick work.
			global = 1;
			var TestClick = register("test-events", [ HTMLElement, Widget], {
				buildRendering: handlebars.compile(
					"click me")
			});
			var myClick = new TestClick();
			myClick.placeAt(container);
			on.emit(myClick.firstChild, "click", {});
			assert.strictEqual(global, 2, "click handler fired");
		},
		"Widgets in Template" : function () {
			register("simple-heading", [HTMLElement, Widget], {
				text: "",
				buildRendering: handlebars.compile("<simple-heading>{{text}}</simple-heading>")
			});

			// This widget uses sub-widgets test-button (defined in first test) and also simple-heading.
			var ComplexWidget = register("widgets-in-template", [HTMLElement, Widget], {
				heading: "original heading",
				content: "original content",
				buttonLabel: "original button label",
				buildRendering: handlebars.compile(
					'<widgets-in-template>' +
						'<simple-heading text="{{heading}}"></simple-heading>' +
						'{{content}}' +
						'<button is="test-button" label="{{buttonLabel}}"></button>' +
						'</widgets-in-template>'
				)
			});

			var myComplexWidget = new ComplexWidget(),
				headingWidget = myComplexWidget.getElementsByTagName("simple-heading")[0],
				buttonWidget = myComplexWidget.getElementsByTagName("button")[0];
			assert.ok(headingWidget.buildRendering, "heading widget was instantiated");
			assert.strictEqual(headingWidget.textContent, "original heading",
				"heading widget got title from main widget");
			assert.ok(buttonWidget.buildRendering, "button widget was instantiated");
			assert.strictEqual(buttonWidget.textContent.trim(), "original button label",
				"button widget got label from main widget");

			myComplexWidget.mix({
				heading: "new heading",
				buttonLabel: "new button label"
			});
			assert.strictEqual(headingWidget.textContent, "new heading", "heading changed");
			assert.strictEqual(buttonWidget.textContent.trim(), "new button label", "button changed");
		},

		html: function () {
			// Testing that parsing still works if ending tags are missing

			var TestHtml = register("test-html", [HTMLUListElement, Widget], {
				buildRendering: handlebars.compile("

1

<input>
")
			});

			var node = new TestHtml();
			assert.strictEqual(node.tagName.toLowerCase(), "ul", "root node exists");

			node = node.firstChild;
			assert.strictEqual(node.tagName.toLowerCase(), "li", "first li exists");
			assert.strictEqual(node.textContent, "1", "first li value");

			node = node.nextSibling;
			assert.strictEqual(node.tagName.toLowerCase(), "li", "second li exists");

			node = node.firstChild;
			assert.strictEqual(node.tagName.toLowerCase(), "input", "input exists");
		},

		svg: function () {
			// Testing template with embedded SVG, for:
			//		1. xmlns attribute recognized, calls createElementNS() not createElement()
			//		2. class attribute still works
			//		3. tags of SVG nodes are lowercase
			//		4. attribute names are case sensitive

			var TestSvg = register("test-svg", [HTMLElement, Widget], {
				buildRendering: svgTmpl
			});

			var node = new TestSvg();
			assert.strictEqual(node.tagName.toLowerCase(), "test-svg", "root node exists");

			node = node.firstChild;
			assert.strictEqual(node.tagName, "svg", "svg node exists");
			assert.strictEqual(node.getAttribute("class"), "svg-root-class", "svg node class attribute");
			assert.strictEqual(node.getAttribute("viewBox"), "0 0 30 30", "viewBox");
			assert.strictEqual(node.namespaceURI, "http://www.w3.org/2000/svg", "svg.namespaceURI");

			node = node.firstChild;
			assert.strictEqual(node.tagName, "rect", "rect node exists");
			assert.strictEqual(node.namespaceURI, "http://www.w3.org/2000/svg", "rect.namespaceURI");
		},

		teardown : function () {
			container.parentNode.removeChild(container);
		}
	});
});
<commit_msg>jshint for handlebars test<commit_after>define([
	"intern!object",
	"intern/chai!assert",
	"dojo/on",
	"delite/handlebars",
	"delite/register",
	"delite/Widget",
	"delite/handlebars!./templates/SimpleHandleBarsButton.html",
	"delite/handlebars!./templates/HandlebarsButton.html",
	"delite/handlebars!./templates/SvgWidget.html"
], function (registerSuite, assert,  on, handlebars, register, Widget, simpleHBTmpl, buttonHBTmpl, svgTmpl) {
	var container, myButton;
	registerSuite({
		name: "handlebars",
		setup: function () {
			container = document.createElement("div");
			document.body.appendChild(container);
		},
		load: function () {
			// Test that function returned from delite/handlebars! creates the template correctly
			var TestButton = register("test-button", [HTMLButtonElement, Widget], {
				iconClass: "originalClass",
				label: "original label",
				buildRendering: simpleHBTmpl
			});
			myButton = new TestButton();
			assert.strictEqual(myButton.tagName.toLowerCase(), "button", "root node exists");
			assert.strictEqual(myButton.firstChild.tagName.toLowerCase(), "span", "icon node exists too");
			assert.strictEqual(myButton.firstChild.className, "duiReset originalClass", "icon class set");
			assert.strictEqual(myButton.textContent.trim(), "original label", "label set");
		},
		update: function () {
			myButton.label = "new label";
			assert.strictEqual(myButton.textContent.trim(), "new label", "label updated");

			myButton.iconClass = "newClass";
			assert.strictEqual(myButton.firstChild.className, "duiReset newClass", "icon class set");

		},
		branching: function () {
			var NoLabelButton = register("no-label-button", [HTMLButtonElement, Widget], {
				iconClass: "originalClass",
				showLabel: false,
				label: "original label",
				buildRendering: buttonHBTmpl
			});
			myButton = new NoLabelButton();
			assert.strictEqual(myButton.tagName.toLowerCase(), "button", "root node exists");
			assert.strictEqual(myButton.firstChild.tagName.toLowerCase(), "span", "icon node exists too");
			assert.strictEqual(myButton.firstChild.className, "duiReset originalClass", "icon class set");
			assert.strictEqual(myButton.textContent.trim(), "", "no label");
			myButton.label = "new label";
			assert.strictEqual(myButton.textContent.trim(), "", "still no label");

			// Test true if condition
			var LabelButton = register("label-button", [HTMLButtonElement, Widget], {
				iconClass: "originalClass",
				showLabel: true,
				label: "original label",
				buildRendering: buttonHBTmpl
			});
			myButton = new LabelButton();
			assert.strictEqual(myButton.tagName.toLowerCase(), "button", "root node exists");
			assert.strictEqual(myButton.firstChild.tagName.toLowerCase(), "span", "icon node exists too");
			assert.strictEqual(myButton.firstChild.className, "duiReset originalClass", "icon class set");
			assert.strictEqual(myButton.textContent.trim(), "original label", "label");

			// Make sure that changes still work
			myButton.label = "new label";
			assert.strictEqual(myButton.textContent.trim(), "new label", "label updated");

		},
		"special props": function () {
			var SpecialPropsWidget = register("special-props", [HTMLElement, Widget], {
				inputClass: "originalClass",	// attribute called "class" but property called "className"
				inputValue: "original value",	// must be set as property
				role: "originalRole",			// must be set as attribute
				buildRendering: handlebars.compile(
					"<special-props><input class='{{inputClass}}' value='{{inputValue}}' " +
						"role='{{role}}'/></special-props>"
				)
			});
			var mySpecialPropsWidget = new SpecialPropsWidget();
			var input = mySpecialPropsWidget.children[0];

			assert.strictEqual(input.value, "original value", "value set as property");
			assert.strictEqual(input.className, "originalClass",
				"class set even though property is called className, not class");
			assert.strictEqual(input.getAttribute("role"), "originalRole", "role set as attribute");

			mySpecialPropsWidget.mix({
				inputClass: "newClass",
				inputValue: "new value",
				role: "newRole"
			});
			assert.strictEqual(input.value, "new value", "value changed");
			assert.strictEqual(input.className, "newClass", "class changed");
			assert.strictEqual(input.getAttribute("role"), "newRole", "role changed");

			// TODO: implement and then test reverse binding, from input.value --> widget.value?
		},
		"special characters": function () {
			// Test that special characters are escaped.  This is actually testing template.js.
			var TestList = register("test-ul", [ HTMLUListElement, Widget], {
				label: "bill'\\",
				buildRendering: handlebars.compile(
					"

\"\\{{label}}\n\twas \n\there'

")
			});
			var myList = new TestList();
			assert.strictEqual(myList.tagName.toLowerCase(), "ul", "root node exists");
			assert.strictEqual(myList.firstChild.tagName.toLowerCase(), "li", "child exists");
			assert.strictEqual(myList.firstChild.getAttribute("foo"), "a.b('c,d')", "single quotes prop");
			assert.strictEqual(myList.firstChild.getAttribute("bar"), "\\\"hello\"", "double quotes, backslash prop");
			assert.strictEqual(myList.firstChild.textContent, "\"\\bill'\\ was here'", "node text");
		},
		events: function () {
			// Test that listeners like onclick work.
			/* global g:true */
			g = 1;
			var TestClick = register("test-events", [ HTMLElement, Widget], {
				buildRendering: handlebars.compile(
					"click me")
			});
			var myClick = new TestClick();
			myClick.placeAt(container);
			on.emit(myClick.firstChild, "click", {});
			assert.strictEqual(g, 2, "click handler fired");
		},
		"widgets in templates": function () {
			register("simple-heading", [HTMLElement, Widget], {
				text: "",
				buildRendering: handlebars.compile("<simple-heading>{{text}}</simple-heading>")
			});

			// This widget uses sub-widgets test-button (defined in first test) and also simple-heading.
			var ComplexWidget = register("widgets-in-template", [HTMLElement, Widget], {
				heading: "original heading",
				content: "original content",
				buttonLabel: "original button label",
				buildRendering: handlebars.compile(
					"<widgets-in-template>" +
						"<simple-heading text='{{heading}}'></simple-heading>" +
						"{{content}}" +
						"<button is='test-button' label='{{buttonLabel}}'></button>" +
						"</widgets-in-template>"
				)
			});

			var myComplexWidget = new ComplexWidget(),
				headingWidget = myComplexWidget.getElementsByTagName("simple-heading")[0],
				buttonWidget = myComplexWidget.getElementsByTagName("button")[0];
			assert.ok(headingWidget.buildRendering, "heading widget was instantiated");
			assert.strictEqual(headingWidget.textContent, "original heading",
				"heading widget got title from main widget");
			assert.ok(buttonWidget.buildRendering, "button widget was instantiated");
			assert.strictEqual(buttonWidget.textContent.trim(), "original button label",
				"button widget got label from main widget");

			myComplexWidget.mix({
				heading: "new heading",
				buttonLabel: "new button label"
			});
			assert.strictEqual(headingWidget.textContent, "new heading", "heading changed");
			assert.strictEqual(buttonWidget.textContent.trim(), "new button label", "button changed");
		},

		html: function () {
			// Testing that parsing still works if ending tags are missing

			var TestHtml = register("test-html", [HTMLUListElement, Widget], {
				buildRendering: handlebars.compile("

1

<input>
")
			});

			var node = new TestHtml();
			assert.strictEqual(node.tagName.toLowerCase(), "ul", "root node exists");

			node = node.firstChild;
			assert.strictEqual(node.tagName.toLowerCase(), "li", "first li exists");
			assert.strictEqual(node.textContent, "1", "first li value");

			node = node.nextSibling;
			assert.strictEqual(node.tagName.toLowerCase(), "li", "second li exists");

			node = node.firstChild;
			assert.strictEqual(node.tagName.toLowerCase(), "input", "input exists");
		},

		svg: function () {
			// Testing template with embedded SVG, for:
			//		1. xmlns attribute recognized, calls createElementNS() not createElement()
			//		2. class attribute still works
			//		3. tags of SVG nodes are lowercase
			//		4. attribute names are case sensitive

			var TestSvg = register("test-svg", [HTMLElement, Widget], {
				buildRendering: svgTmpl
			});

			var node = new TestSvg();
			assert.strictEqual(node.tagName.toLowerCase(), "test-svg", "root node exists");

			node = node.firstChild;
			assert.strictEqual(node.tagName, "svg", "svg node exists");
			assert.strictEqual(node.getAttribute("class"), "svg-root-class", "svg node class attribute");
			assert.strictEqual(node.getAttribute("viewBox"), "0 0 30 30", "viewBox");
			assert.strictEqual(node.namespaceURI, "http://www.w3.org/2000/svg", "svg.namespaceURI");

			node = node.firstChild;
			assert.strictEqual(node.tagName, "rect", "rect node exists");
			assert.strictEqual(node.namespaceURI, "http://www.w3.org/2000/svg", "rect.namespaceURI");
		},

		teardown: function () {
			container.parentNode.removeChild(container);
		}
	});
});
<|endoftext|>


<commit_before>var core = require('../core'),
    // a sprite use dfor rendering textures..
    tempPoint = new core.Point();

/**
 * A tiling sprite is a fast way of rendering a tiling image
 *
 * @class
 * @extends PIXI.Sprite
 * @memberof PIXI.extras
 * @param texture {Texture} the texture of the tiling sprite
 * @param width {number}  the width of the tiling sprite
 * @param height {number} the height of the tiling sprite
 */
function TilingSprite(texture, width, height)
{
    core.Sprite.call(this, texture);

    /**
     * The scaling of the image that is being tiled
     *
     * @member {PIXI.Point}
     */
    this.tileScale = new core.Point(1,1);

    /**
     * The offset position of the image that is being tiled
     *
     * @member {PIXI.Point}
     */
    this.tilePosition = new core.Point(0,0);

    ///// private

    /**
     * The with of the tiling sprite
     *
     * @member {number}
     * @private
     */
    this._width = width || 100;

    /**
     * The height of the tiling sprite
     *
     * @member {number}
     * @private
     */
    this._height = height || 100;

    /**
     * An internal WebGL UV cache.
     *
     * @member {PIXI.TextureUvs}
     * @private
     */
    this._uvs = new core.TextureUvs();

    this._canvasPattern = null;

    //TODO move..
    this.shader = new core.AbstractFilter(

      [
        'precision lowp float;',
        'attribute vec2 aVertexPosition;',
        'attribute vec2 aTextureCoord;',
        'attribute vec4 aColor;',

        'uniform mat3 projectionMatrix;',

        'uniform vec4 uFrame;',
        'uniform vec4 uTransform;',

        'varying vec2 vTextureCoord;',
        'varying vec4 vColor;',

        'void main(void){',
        '   gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);',

        '   vec2 coord = aTextureCoord;',
        '   coord -= uTransform.xy;',
        '   coord /= uTransform.zw;',
        '   vTextureCoord = coord;',

        '   vColor = vec4(aColor.rgb * aColor.a, aColor.a);',
        '}'
      ].join('\n'),
      [
        'precision lowp float;',

        'varying vec2 vTextureCoord;',
        'varying vec4 vColor;',

        'uniform sampler2D uSampler;',
        'uniform vec4 uFrame;',
        'uniform vec2 uPixelSize;',

        'void main(void){',

        '   vec2 coord = mod(vTextureCoord, uFrame.zw);',
        '   coord = clamp(coord, uPixelSize, uFrame.zw - uPixelSize);',
        '   coord += uFrame.xy;',

        '   gl_FragColor =  texture2D(uSampler, coord) * vColor ;',
        '}'
      ].join('\n'),

            // set the uniforms
            {
                uFrame: { type: '4fv', value: [0,0,1,1] },
                uTransform: { type: '4fv', value: [0,0,1,1] },
                uPixelSize : { type : '2fv', value: [1, 1]}
            }
      );
}

TilingSprite.prototype = Object.create(core.Sprite.prototype);
TilingSprite.prototype.constructor = TilingSprite;
module.exports = TilingSprite;

Object.defineProperties(TilingSprite.prototype, {
    /**
     * The width of the sprite, setting this will actually modify the scale to achieve the value set
     *
     * @member {number}
     * @memberof PIXI.extras.TilingSprite#
     */
    width: {
        get: function ()
        {
            return this._width;
        },
        set: function (value)
        {
            this._width = value;
        }
    },

    /**
     * The height of the TilingSprite, setting this will actually modify the scale to achieve the value set
     *
     * @member {number}
     * @memberof PIXI.extras.TilingSprite#
     */
    height: {
        get: function ()
        {
            return this._height;
        },
        set: function (value)
        {
            this._height = value;
        }
    }
});

TilingSprite.prototype._onTextureUpdate = function ()
{
    return;
};

/**
 * Renders the object using the WebGL renderer
 *
 * @param renderer {PIXI.WebGLRenderer}
 * @private
 */
TilingSprite.prototype._renderWebGL = function (renderer)
{
    // tweak our texture temporarily..
    var texture = this._texture;

    if(!texture || !texture._uvs)
    {
        return;
    }

    var tempUvs = texture._uvs,
        tempWidth = texture._frame.width,
        tempHeight = texture._frame.height,
        tw = texture.baseTexture.width,
        th = texture.baseTexture.height;

    texture._uvs = this._uvs;
    texture._frame.width = this.width;
    texture._frame.height = this.height;

    this.shader.uniforms.uPixelSize.value[0] = 1.0/tw;
    this.shader.uniforms.uPixelSize.value[1] = 1.0/th;

    this.shader.uniforms.uFrame.value[0] = tempUvs.x0;
    this.shader.uniforms.uFrame.value[1] = tempUvs.y0;
    this.shader.uniforms.uFrame.value[2] = tempUvs.x1 - tempUvs.x0;
    this.shader.uniforms.uFrame.value[3] = tempUvs.y2 - tempUvs.y0;

    this.shader.uniforms.uTransform.value[0] = (this.tilePosition.x % (tempWidth * this.tileScale.x)) / this._width;
    this.shader.uniforms.uTransform.value[1] = (this.tilePosition.y % (tempHeight * this.tileScale.y)) / this._height;
    this.shader.uniforms.uTransform.value[2] = ( tw / this._width ) * this.tileScale.x;
    this.shader.uniforms.uTransform.value[3] = ( th / this._height ) * this.tileScale.y;

    renderer.setObjectRenderer(renderer.plugins.sprite);
    renderer.plugins.sprite.render(this);

    texture._uvs = tempUvs;
    texture._frame.width = tempWidth;
    texture._frame.height = tempHeight;
};

/**
 * Renders the object using the Canvas renderer
 *
 * @param renderer {PIXI.CanvasRenderer} a reference to the canvas renderer
 * @private
 */
TilingSprite.prototype._renderCanvas = function (renderer)
{
    var texture = this._texture;

    if (!texture.baseTexture.hasLoaded)
    {
      return;
    }

    var context = renderer.context,
        transform = this.worldTransform,
        resolution = renderer.resolution,
        baseTexture = texture.baseTexture,
        modX = this.tilePosition.x % (texture._frame.width * this.tileScale.x),
        modY = this.tilePosition.y % (texture._frame.height * this.tileScale.y);

    // create a nice shiny pattern!
    // TODO this needs to be refreshed if texture changes..
    if(!this._canvasPattern)
    {
        // cut an object from a spritesheet..
        var tempCanvas = new core.CanvasBuffer(texture._frame.width, texture._frame.height);
        tempCanvas.context.drawImage(baseTexture.source, -texture._frame.x,-texture._frame.y);
        this._canvasPattern = tempCanvas.context.createPattern( tempCanvas.canvas, 'repeat' );
    }

    // set context state..
    context.globalAlpha = this.worldAlpha;
    context.setTransform(transform.a * resolution,
                       transform.b * resolution,
                       transform.c * resolution,
                       transform.d * resolution,
                       transform.tx * resolution,
                       transform.ty * resolution);

    // TODO - this should be rolled into the setTransform above..
    context.scale(this.tileScale.x,this.tileScale.y);

    context.translate(modX + (this.anchor.x * -this._width ),
                      modY + (this.anchor.y * -this._height));

    // check blend mode
    var compositeOperation = renderer.blendModes[this.blendMode];
    if (compositeOperation !== renderer.context.globalCompositeOperation)
    {
        context.globalCompositeOperation = compositeOperation;
    }

    // fill the pattern!
    context.fillStyle = this._canvasPattern;
    context.fillRect(-modX,
                     -modY,
                     this._width / this.tileScale.x,
                     this._height / this.tileScale.y);

    //TODO - pretty sure this can be deleted...
    //context.translate(-this.tilePosition.x + (this.anchor.x * this._width), -this.tilePosition.y + (this.anchor.y * this._height));
    //context.scale(1 / this.tileScale.x, 1 / this.tileScale.y);
};

/**
 * Returns the framing rectangle of the sprite as a Rectangle object
*
 * @return {PIXI.Rectangle} the framing rectangle
 */
TilingSprite.prototype.getBounds = function ()
{
    var width = this._width;
    var height = this._height;

    var w0 = width * (1-this.anchor.x);
    var w1 = width * -this.anchor.x;

    var h0 = height * (1-this.anchor.y);
    var h1 = height * -this.anchor.y;

    var worldTransform = this.worldTransform;

    var a = worldTransform.a;
    var b = worldTransform.b;
    var c = worldTransform.c;
    var d = worldTransform.d;
    var tx = worldTransform.tx;
    var ty = worldTransform.ty;

    var x1 = a * w1 + c * h1 + tx;
    var y1 = d * h1 + b * w1 + ty;

    var x2 = a * w0 + c * h1 + tx;
    var y2 = d * h1 + b * w0 + ty;

    var x3 = a * w0 + c * h0 + tx;
    var y3 = d * h0 + b * w0 + ty;

    var x4 =  a * w1 + c * h0 + tx;
    var y4 =  d * h0 + b * w1 + ty;

    var minX,
        maxX,
        minY,
        maxY;

    minX = x1;
    minX = x2 < minX ? x2 : minX;
    minX = x3 < minX ? x3 : minX;
    minX = x4 < minX ? x4 : minX;

    minY = y1;
    minY = y2 < minY ? y2 : minY;
    minY = y3 < minY ? y3 : minY;
    minY = y4 < minY ? y4 : minY;

    maxX = x1;
    maxX = x2 > maxX ? x2 : maxX;
    maxX = x3 > maxX ? x3 : maxX;
    maxX = x4 > maxX ? x4 : maxX;

    maxY = y1;
    maxY = y2 > maxY ? y2 : maxY;
    maxY = y3 > maxY ? y3 : maxY;
    maxY = y4 > maxY ? y4 : maxY;

    var bounds = this._bounds;

    bounds.x = minX;
    bounds.width = maxX - minX;

    bounds.y = minY;
    bounds.height = maxY - minY;

    // store a reference so that if this function gets called again in the render cycle we do not have to recalculate
    this._currentBounds = bounds;

    return bounds;
};

/**
 * Checks if a point is inside this tiling sprite
 * @param point {PIXI.Point} the point to check
 */
TilingSprite.prototype.containsPoint = function( point )
{
    this.worldTransform.applyInverse(point,  tempPoint);

    var width = this._width;
    var height = this._height;
    var x1 = -width * this.anchor.x;
    var y1;

    if ( tempPoint.x > x1 && tempPoint.x < x1 + width )
    {
        y1 = -height * this.anchor.y;

        if ( tempPoint.y > y1 && tempPoint.y < y1 + height )
        {
            return true;
        }
    }

    return false;
};

/**
 * Destroys this tiling sprite
 *
 */
TilingSprite.prototype.destroy = function () {
    core.Sprite.prototype.destroy.call(this);

    this.tileScale = null;
    this._tileScaleOffset = null;
    this.tilePosition = null;

    this._uvs = null;
};

/**
 * Helper function that creates a tiling sprite that will use a texture from the TextureCache based on the frameId
 * The frame ids are created when a Texture packer file has been loaded
 *
 * @static
 * @param frameId {string} The frame Id of the texture in the cache
 * @return {PIXI.extras.TilingSprite} A new TilingSprite using a texture from the texture cache matching the frameId
 * @param width {number}  the width of the tiling sprite
 * @param height {number} the height of the tiling sprite
 */
TilingSprite.fromFrame = function (frameId,width,height)
{
    var texture = core.utils.TextureCache[frameId];

    if (!texture)
    {
        throw new Error('The frameId "' + frameId + '" does not exist in the texture cache ' + this);
    }

    return new TilingSprite(texture,width,height);
};

/**
 * Helper function that creates a sprite that will contain a texture based on an image url
 * If the image is not in the texture cache it will be loaded
 *
 * @static
 * @param imageId {string} The image url of the texture
 * @param width {number}  the width of the tiling sprite
 * @param height {number} the height of the tiling sprite
 * @param [crossorigin=(auto)] {boolean} if you want to specify the cross-origin parameter
 * @param [scaleMode=PIXI.SCALE_MODES.DEFAULT] {number} if you want to specify the scale mode, see {@link PIXI.SCALE_MODES} for possible values
 * @return {PIXI.extras.TilingSprite} A new TilingSprite using a texture from the texture cache matching the image id
 */
TilingSprite.fromImage = function (imageId, width, height, crossorigin, scaleMode)
{
    return new TilingSprite(core.Texture.fromImage(imageId, crossorigin, scaleMode),width,height);
};
<commit_msg>Fix TilingSprite offset issue with CanvasRenderer<commit_after>var core = require('../core'),
    // a sprite use dfor rendering textures..
    tempPoint = new core.Point();

/**
 * A tiling sprite is a fast way of rendering a tiling image
 *
 * @class
 * @extends PIXI.Sprite
 * @memberof PIXI.extras
 * @param texture {Texture} the texture of the tiling sprite
 * @param width {number}  the width of the tiling sprite
 * @param height {number} the height of the tiling sprite
 */
function TilingSprite(texture, width, height)
{
    core.Sprite.call(this, texture);

    /**
     * The scaling of the image that is being tiled
     *
     * @member {PIXI.Point}
     */
    this.tileScale = new core.Point(1,1);

    /**
     * The offset position of the image that is being tiled
     *
     * @member {PIXI.Point}
     */
    this.tilePosition = new core.Point(0,0);

    ///// private

    /**
     * The with of the tiling sprite
     *
     * @member {number}
     * @private
     */
    this._width = width || 100;

    /**
     * The height of the tiling sprite
     *
     * @member {number}
     * @private
     */
    this._height = height || 100;

    /**
     * An internal WebGL UV cache.
     *
     * @member {PIXI.TextureUvs}
     * @private
     */
    this._uvs = new core.TextureUvs();

    this._canvasPattern = null;

    //TODO move..
    this.shader = new core.AbstractFilter(

      [
        'precision lowp float;',
        'attribute vec2 aVertexPosition;',
        'attribute vec2 aTextureCoord;',
        'attribute vec4 aColor;',

        'uniform mat3 projectionMatrix;',

        'uniform vec4 uFrame;',
        'uniform vec4 uTransform;',

        'varying vec2 vTextureCoord;',
        'varying vec4 vColor;',

        'void main(void){',
        '   gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);',

        '   vec2 coord = aTextureCoord;',
        '   coord -= uTransform.xy;',
        '   coord /= uTransform.zw;',
        '   vTextureCoord = coord;',

        '   vColor = vec4(aColor.rgb * aColor.a, aColor.a);',
        '}'
      ].join('\n'),
      [
        'precision lowp float;',

        'varying vec2 vTextureCoord;',
        'varying vec4 vColor;',

        'uniform sampler2D uSampler;',
        'uniform vec4 uFrame;',
        'uniform vec2 uPixelSize;',

        'void main(void){',

        '   vec2 coord = mod(vTextureCoord, uFrame.zw);',
        '   coord = clamp(coord, uPixelSize, uFrame.zw - uPixelSize);',
        '   coord += uFrame.xy;',

        '   gl_FragColor =  texture2D(uSampler, coord) * vColor ;',
        '}'
      ].join('\n'),

            // set the uniforms
            {
                uFrame: { type: '4fv', value: [0,0,1,1] },
                uTransform: { type: '4fv', value: [0,0,1,1] },
                uPixelSize : { type : '2fv', value: [1, 1]}
            }
      );
}

TilingSprite.prototype = Object.create(core.Sprite.prototype);
TilingSprite.prototype.constructor = TilingSprite;
module.exports = TilingSprite;

Object.defineProperties(TilingSprite.prototype, {
    /**
     * The width of the sprite, setting this will actually modify the scale to achieve the value set
     *
     * @member {number}
     * @memberof PIXI.extras.TilingSprite#
     */
    width: {
        get: function ()
        {
            return this._width;
        },
        set: function (value)
        {
            this._width = value;
        }
    },

    /**
     * The height of the TilingSprite, setting this will actually modify the scale to achieve the value set
     *
     * @member {number}
     * @memberof PIXI.extras.TilingSprite#
     */
    height: {
        get: function ()
        {
            return this._height;
        },
        set: function (value)
        {
            this._height = value;
        }
    }
});

TilingSprite.prototype._onTextureUpdate = function ()
{
    return;
};

/**
 * Renders the object using the WebGL renderer
 *
 * @param renderer {PIXI.WebGLRenderer}
 * @private
 */
TilingSprite.prototype._renderWebGL = function (renderer)
{
    // tweak our texture temporarily..
    var texture = this._texture;

    if(!texture || !texture._uvs)
    {
        return;
    }

    var tempUvs = texture._uvs,
        tempWidth = texture._frame.width,
        tempHeight = texture._frame.height,
        tw = texture.baseTexture.width,
        th = texture.baseTexture.height;

    texture._uvs = this._uvs;
    texture._frame.width = this.width;
    texture._frame.height = this.height;

    this.shader.uniforms.uPixelSize.value[0] = 1.0/tw;
    this.shader.uniforms.uPixelSize.value[1] = 1.0/th;

    this.shader.uniforms.uFrame.value[0] = tempUvs.x0;
    this.shader.uniforms.uFrame.value[1] = tempUvs.y0;
    this.shader.uniforms.uFrame.value[2] = tempUvs.x1 - tempUvs.x0;
    this.shader.uniforms.uFrame.value[3] = tempUvs.y2 - tempUvs.y0;

    this.shader.uniforms.uTransform.value[0] = (this.tilePosition.x % (tempWidth * this.tileScale.x)) / this._width;
    this.shader.uniforms.uTransform.value[1] = (this.tilePosition.y % (tempHeight * this.tileScale.y)) / this._height;
    this.shader.uniforms.uTransform.value[2] = ( tw / this._width ) * this.tileScale.x;
    this.shader.uniforms.uTransform.value[3] = ( th / this._height ) * this.tileScale.y;

    renderer.setObjectRenderer(renderer.plugins.sprite);
    renderer.plugins.sprite.render(this);

    texture._uvs = tempUvs;
    texture._frame.width = tempWidth;
    texture._frame.height = tempHeight;
};

/**
 * Renders the object using the Canvas renderer
 *
 * @param renderer {PIXI.CanvasRenderer} a reference to the canvas renderer
 * @private
 */
TilingSprite.prototype._renderCanvas = function (renderer)
{
    var texture = this._texture;

    if (!texture.baseTexture.hasLoaded)
    {
      return;
    }

    var context = renderer.context,
        transform = this.worldTransform,
        resolution = renderer.resolution,
        baseTexture = texture.baseTexture,
        modX = (this.tilePosition.x / this.tileScale.x) % texture._frame.width,
        modY = (this.tilePosition.y / this.tileScale.y) % texture._frame.height;

    // create a nice shiny pattern!
    // TODO this needs to be refreshed if texture changes..
    if(!this._canvasPattern)
    {
        // cut an object from a spritesheet..
        var tempCanvas = new core.CanvasBuffer(texture._frame.width, texture._frame.height);
        tempCanvas.context.drawImage(baseTexture.source, -texture._frame.x,-texture._frame.y);
        this._canvasPattern = tempCanvas.context.createPattern( tempCanvas.canvas, 'repeat' );
    }

    // set context state..
    context.globalAlpha = this.worldAlpha;
    context.setTransform(transform.a * resolution,
                       transform.b * resolution,
                       transform.c * resolution,
                       transform.d * resolution,
                       transform.tx * resolution,
                       transform.ty * resolution);

    // TODO - this should be rolled into the setTransform above..
    context.scale(this.tileScale.x,this.tileScale.y);

    context.translate(modX + (this.anchor.x * -this._width ),
                      modY + (this.anchor.y * -this._height));

    // check blend mode
    var compositeOperation = renderer.blendModes[this.blendMode];
    if (compositeOperation !== renderer.context.globalCompositeOperation)
    {
        context.globalCompositeOperation = compositeOperation;
    }

    // fill the pattern!
    context.fillStyle = this._canvasPattern;
    context.fillRect(-modX,
                     -modY,
                     this._width / this.tileScale.x,
                     this._height / this.tileScale.y);

    //TODO - pretty sure this can be deleted...
    //context.translate(-this.tilePosition.x + (this.anchor.x * this._width), -this.tilePosition.y + (this.anchor.y * this._height));
    //context.scale(1 / this.tileScale.x, 1 / this.tileScale.y);
};

/**
 * Returns the framing rectangle of the sprite as a Rectangle object
*
 * @return {PIXI.Rectangle} the framing rectangle
 */
TilingSprite.prototype.getBounds = function ()
{
    var width = this._width;
    var height = this._height;

    var w0 = width * (1-this.anchor.x);
    var w1 = width * -this.anchor.x;

    var h0 = height * (1-this.anchor.y);
    var h1 = height * -this.anchor.y;

    var worldTransform = this.worldTransform;

    var a = worldTransform.a;
    var b = worldTransform.b;
    var c = worldTransform.c;
    var d = worldTransform.d;
    var tx = worldTransform.tx;
    var ty = worldTransform.ty;

    var x1 = a * w1 + c * h1 + tx;
    var y1 = d * h1 + b * w1 + ty;

    var x2 = a * w0 + c * h1 + tx;
    var y2 = d * h1 + b * w0 + ty;

    var x3 = a * w0 + c * h0 + tx;
    var y3 = d * h0 + b * w0 + ty;

    var x4 =  a * w1 + c * h0 + tx;
    var y4 =  d * h0 + b * w1 + ty;

    var minX,
        maxX,
        minY,
        maxY;

    minX = x1;
    minX = x2 < minX ? x2 : minX;
    minX = x3 < minX ? x3 : minX;
    minX = x4 < minX ? x4 : minX;

    minY = y1;
    minY = y2 < minY ? y2 : minY;
    minY = y3 < minY ? y3 : minY;
    minY = y4 < minY ? y4 : minY;

    maxX = x1;
    maxX = x2 > maxX ? x2 : maxX;
    maxX = x3 > maxX ? x3 : maxX;
    maxX = x4 > maxX ? x4 : maxX;

    maxY = y1;
    maxY = y2 > maxY ? y2 : maxY;
    maxY = y3 > maxY ? y3 : maxY;
    maxY = y4 > maxY ? y4 : maxY;

    var bounds = this._bounds;

    bounds.x = minX;
    bounds.width = maxX - minX;

    bounds.y = minY;
    bounds.height = maxY - minY;

    // store a reference so that if this function gets called again in the render cycle we do not have to recalculate
    this._currentBounds = bounds;

    return bounds;
};

/**
 * Checks if a point is inside this tiling sprite
 * @param point {PIXI.Point} the point to check
 */
TilingSprite.prototype.containsPoint = function( point )
{
    this.worldTransform.applyInverse(point,  tempPoint);

    var width = this._width;
    var height = this._height;
    var x1 = -width * this.anchor.x;
    var y1;

    if ( tempPoint.x > x1 && tempPoint.x < x1 + width )
    {
        y1 = -height * this.anchor.y;

        if ( tempPoint.y > y1 && tempPoint.y < y1 + height )
        {
            return true;
        }
    }

    return false;
};

/**
 * Destroys this tiling sprite
 *
 */
TilingSprite.prototype.destroy = function () {
    core.Sprite.prototype.destroy.call(this);

    this.tileScale = null;
    this._tileScaleOffset = null;
    this.tilePosition = null;

    this._uvs = null;
};

/**
 * Helper function that creates a tiling sprite that will use a texture from the TextureCache based on the frameId
 * The frame ids are created when a Texture packer file has been loaded
 *
 * @static
 * @param frameId {string} The frame Id of the texture in the cache
 * @return {PIXI.extras.TilingSprite} A new TilingSprite using a texture from the texture cache matching the frameId
 * @param width {number}  the width of the tiling sprite
 * @param height {number} the height of the tiling sprite
 */
TilingSprite.fromFrame = function (frameId,width,height)
{
    var texture = core.utils.TextureCache[frameId];

    if (!texture)
    {
        throw new Error('The frameId "' + frameId + '" does not exist in the texture cache ' + this);
    }

    return new TilingSprite(texture,width,height);
};

/**
 * Helper function that creates a sprite that will contain a texture based on an image url
 * If the image is not in the texture cache it will be loaded
 *
 * @static
 * @param imageId {string} The image url of the texture
 * @param width {number}  the width of the tiling sprite
 * @param height {number} the height of the tiling sprite
 * @param [crossorigin=(auto)] {boolean} if you want to specify the cross-origin parameter
 * @param [scaleMode=PIXI.SCALE_MODES.DEFAULT] {number} if you want to specify the scale mode, see {@link PIXI.SCALE_MODES} for possible values
 * @return {PIXI.extras.TilingSprite} A new TilingSprite using a texture from the texture cache matching the image id
 */
TilingSprite.fromImage = function (imageId, width, height, crossorigin, scaleMode)
{
    return new TilingSprite(core.Texture.fromImage(imageId, crossorigin, scaleMode),width,height);
};
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the License);
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.u2',
  name: 'HTMLValidator',
  extends: 'foam.u2.DefaultValidator',

  axioms: [ foam.pattern.Singleton.create() ],

  methods: [
    function sanitizeText(text) {
      // TODO: validate text
      return text;
    }
  ]
});

// An Element which does not escape HTML content
foam.CLASS({
  package: 'foam.u2',
  name: 'HTMLElement',
  extends: 'foam.u2.Element',

  exports: [ 'validator as elementValidator' ],

  properties: [
    {
      class: 'Proxy',
      of: 'foam.u2.DefaultValidator',
      name: 'validator',
      value: foam.u2.HTMLValidator.create()
    }
  ]
});
<commit_msg>Use a factory instead of creating an HTMLValidator inline.<commit_after>/**
 * @license
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the License);
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.u2',
  name: 'HTMLValidator',
  extends: 'foam.u2.DefaultValidator',

  axioms: [ foam.pattern.Singleton.create() ],

  methods: [
    function sanitizeText(text) {
      // TODO: validate text
      return text;
    }
  ]
});

// An Element which does not escape HTML content
foam.CLASS({
  package: 'foam.u2',
  name: 'HTMLElement',
  extends: 'foam.u2.Element',

  requires: [ 'foam.u2.HTMLValidator' ],

  exports: [ 'validator as elementValidator' ],

  properties: [
    {
      class: 'Proxy',
      of: 'foam.u2.DefaultValidator',
      name: 'validator',
      factory: function() { return this.HTMLValidator.create() }
    }
  ]
});
<|endoftext|>


<commit_before>var canvas = null;
var ctx = null;

var xhead; //head position
var yhead; //^
var dx=cw; //amount of distance it moves
var dy=cw; //^
var x1food; //wrong food position
var y1food;
var x2food;
var y2food;
var x3food; //correct food position
var y3food;
var randnum1; //random numbers
var randnum2;
var randnum3;
var ques; //question
var cw=15; //cell width
var animx; //gobbling animation x
var animy; // y^
var anim_check;

var rightPressed = true; //snake initially moves right
var leftPressed = false;
var topPressed = false;
var bottomPressed = false;
var directionflag=1;

var snake_array=[]; //snake body in an array
var speed=150;
var ds=5; //change in speed
var clrReturn;
var score=0;
var length=4;
var flag=0;
var life=3;
var rotate=2; //1 is top, 2 right, 3 down, 4 left

var headtop=new Image();
headtop.src="images/headtop.png";

var headright=new Image();
headright.src="images/headright.png";

var headdown=new Image();
headdown.src="images/headdown.png";

var headleft=new Image();
headleft.src="images/headleft.png";

function create_snake(){

	for(var i=length-1;i>=0;i--){
		snake_array.push({ x:(i+2) , y: 2 }); //snake object with x position variable
	}
	xhead = snake_array[0].x;
	yhead = snake_array[0].y;
}

function drawbody(){

	for(var i=0; i<snake_array.length; i++){

		var temp=snake_array[i];
		if(i==0){
			ctx.beginPath();
			if(rotate==1){
				ctx.drawImage(headtop,temp.x*cw-10,temp.y*cw-20,20,30);
			}
			if(rotate==2){
				ctx.drawImage(headright,temp.x*cw-10,temp.y*cw-10,30,20);
			}
			if(rotate==3){
				ctx.drawImage(headdown,temp.x*cw-10,temp.y*cw-10,20,30);
			}
			if(rotate==4){
				ctx.drawImage(headleft,temp.x*cw-20,temp.y*cw-10,30,20);
			}
	ctx.closePath();
		} else if(temp.x==animx && temp.y==animy){ // for gobbling
		ctx.beginPath();
	ctx.arc(temp.x*cw,temp.y*cw,11,0,2*Math.PI);
	ctx.fillStyle = "darkgreen";
	ctx.fill();
	ctx.strokeStyle = "black";
	ctx.stroke();
	ctx.closePath(); }
	else {
		ctx.beginPath();
	ctx.arc(temp.x*cw,temp.y*cw,8,0,2*Math.PI);
	ctx.fillStyle = "darkgreen";
	ctx.fill();
	ctx.strokeStyle = "black";
	ctx.stroke();
	ctx.closePath();
	}
}
reset_anim();
}

function reset_anim() {
	if(anim_check==0){
	animx=null;
	animy=null;
	}else anim_check--;
}

function food_circle(randnum,xfood,yfood){
		ctx.fillStyle="yellow";
	if(randnum.toString().length==1){
		ctx.arc(xfood,yfood,12,0,2*Math.PI,false);
		ctx.fill();
		ctx.fillStyle="black";
		ctx.fillText(randnum,xfood-5,yfood+7);}
	  else if(randnum.toString().length==2){
		ctx.arc(xfood,yfood,13,0,2*Math.PI,false);
		ctx.fill();
		ctx.fillStyle="black";
		ctx.fillText(randnum,xfood-9,yfood+7);}
	  else if(randnum.toString().length==3){
		ctx.arc(xfood,yfood,15,0,2*Math.PI,false);
		ctx.fill();
		ctx.fillStyle="black";
		ctx.fillText(randnum,xfood-14,yfood+7);}
}

function drawfood(){
	ctx.beginPath();
	ctx.font="bold 16px arial";
	food_circle(randnum1,x1food,y1food);
	ctx.closePath();
	ctx.beginPath();
	food_circle(randnum2,x2food,y2food);
	ctx.closePath();
	ctx.beginPath();
	food_circle(randnum3,x3food,y3food);
	ctx.closePath();
}

function border(){
	ctx.beginPath();
	ctx.rect(0,0,cw+cw/2,canvas.height);
	ctx.rect(0,0,canvas.width,cw+cw/2);
	ctx.rect(canvas.width-cw-cw/2,0,cw+cw/2,canvas.height);
	ctx.rect(0,canvas.height-15,canvas.width,15);
	ctx.fillStyle="#6c2e08";
	ctx.fill();
	/*ctx.font="20px arial";
	ctx.fillStyle="black";
	ctx.fillText("Speed: "+speed,20,300);*/
	ctx.closePath();
}

function question(){
	ques=3+Math.floor(Math.random()*12);
	document.getElementById('ques').innerHTML=ques;
}

/*function drawques(){
	ctx.beginPath();
	ctx.fillStyle="blue";
	ctx.font="20px arial";
	ctx.fillText("Which of these numbers is divisible by "+ques ,200,395);
	ctx.closePath();
}*/

function update_game(){
	x1food=45+Math.floor(Math.random()*(canvas.width-80)/15)*15; //between 30 and width-15
	y1food=45+Math.floor(Math.random()*(canvas.height-80)/15)*15; // ^
	x2food=45+Math.floor(Math.random()*(canvas.width-80)/15)*15; //between 30 and width-15
	y2food=45+Math.floor(Math.random()*(canvas.height-80)/15)*15;
	x3food=45+Math.floor(Math.random()*(canvas.width-80)/15)*15; //between 30 and width-15
	y3food=45+Math.floor(Math.random()*(canvas.height-80)/15)*15;
	if(x1food<x2food+30 && y1food<y2food+30 && x1food>x2food-30 && y1food>y2food-30 || x2food<x3food+30 && y2food<y3food+30 && x2food>x3food-30 && y2food>y3food-30 || x1food<x3food+30 && y1food<y3food+30 && x1food>x3food-30 && y1food>y3food-30 ){
		update_game();
	}
	randnum1=2+Math.floor(Math.random()*150);
	randnum2=2+Math.floor(Math.random()*150);
	question();
	randnum3=ques*Math.floor(2+Math.random()*10);
		if(randnum1==randnum2 || randnum2==randnum3 || randnum3==randnum1 || randnum1%ques==0 || randnum2%ques==0){
			update_game();
		} else {
			update_speed();
	}
}

function update_speed(){
	clearInterval(clrReturn);   // clear the initial set interval
		if(speed==80){
			clrReturn=setInterval(move,speed);
		} else{
			speed=speed-ds;				// update the speed to make it faster
			clrReturn=setInterval(move,speed);  // new set interval with new speed
		}
}

function check(){
	if(xhead*15==x3food && yhead*15==y3food){
		update_game();
		score++;		// eats the right food
		flag=1;
		animx=xhead; animy=yhead; //save the place where gobbling animation takes place
		anim_check=snake_array.length;
	} else if (xhead*15==x1food && yhead*15== y1food || xhead*15==x2food && yhead*15==y2food) {
		update_game();
		if(score){
		score--;
		}
		life--;		//eats the wrong food
		document.getElementById("life"+(life+1)).style.display= "none";
		flag=1;
		animx=xhead; animy=yhead; //save the place where gobbling animation takes place
		anim_check=snake_array.length;
	}
	document.getElementById('score').innerHTML=score;
}

function move(){
	ctx.clearRect(0,0,canvas.width,canvas.height);
	drawbody();
	drawfood();
	//drawques();
	border();
	conditions();
	direction();
	collision();
	check();

	if(flag==1){
		flag=0;
		var tail={ x:xhead, y:yhead };		//tail becomes the new head and tail
	}else {
	var tail=snake_array.pop();		//pop the tail
	tail={ x:xhead, y:yhead };
			}
	snake_array.unshift(tail);		//add tail at the start

	directionflag=1;

}

function conditions(){
			if(xhead*cw<=cw || xhead*cw>=canvas.width-cw || yhead*cw<=cw || yhead*cw>=canvas.height-20 || !life){  //border and lives
				after_collision();
			}
}

function collision(){
	for(var i=0;i<snake_array.length;i++){
		if (snake_array[i].x==xhead && snake_array[i].y==yhead){	//body collision
			after_collision();
		}
	}
}

function after_collision(){
			ctx.beginPath();
			ctx.fillStyle="red";
			ctx.arc(xhead*cw,yhead*cw,10,0,2*Math.PI);
			ctx.fill();
			ctx.strokeStyle="black";
			ctx.stroke();
			ctx.closePath();
			clearInterval(clrReturn);
			play_again();
}

addEventListener("keydown", keyDownHandler, false);

function keyDownHandler(e) {
	if(directionflag==1){
    if( (e.keyCode == 39 || e.keyCode==68) && leftPressed!=true) { 	   //right
        	keyreset();
        	rightPressed = true;
        	directionflag=0;
        	rotate=2;
    }

    else if( (e.keyCode == 37 || e.keyCode==65) && rightPressed!=true) { //left
        	keyreset();
        	leftPressed = true;
        	directionflag=0;
        	rotate=4;
    }

    else if( (e.keyCode == 38 || e.keyCode==87) && bottomPressed!=true){  //top
        	keyreset();
        	topPressed = true;
        	directionflag=0;
        	rotate=1;
    }

    else if( (e.keyCode == 40 || e.keyCode==83)&& topPressed!=true){  //down
        	keyreset();
        	bottomPressed = true;
        	directionflag=0;
        	rotate=3;
    }
}
}

function direction(){

	if(rightPressed==true){ //new head is at the right
		xhead++;
	}
	else if(leftPressed==true){	//new head is at the left
		xhead--;
	}
	else if(bottomPressed==true){	//new head is at the bottom
		yhead++;
	}
	else if(topPressed==true){	//new head is at the top
		yhead--;
	}
}

function keyreset() {
    rightPressed = false;
    leftPressed = false;
    topPressed = false;
    bottomPressed = false;
}

function play_again(){
	alert("GAME OVER\nYour score is: "+score);
	if(confirm("Play again?")){
			location.reload();
	}
}

window.onload = function() {
	canvas = document.getElementById("myCanvas");
	ctx = canvas.getContext("2d");

	for(var i=1;i<=3;i++){
	document.getElementById('life'+i).innerHTML="";
	}

	canvas.width=600; //width
	canvas.height=400; //height

	create_snake();
	update_game();
}
<commit_msg>red life loss<commit_after>var canvas = null;
var ctx = null;

var xhead; //head position
var yhead; //^
var dx=cw; //amount of distance it moves
var dy=cw; //^
var x1food; //wrong food position
var y1food;
var x2food;
var y2food;
var x3food; //correct food position
var y3food;
var randnum1; //random numbers
var randnum2;
var randnum3;
var ques; //question
var cw=15; //cell width
var animx; //gobbling animation x
var animy; // y^
var anim_check;

var rightPressed = true; //snake initially moves right
var leftPressed = false;
var topPressed = false;
var bottomPressed = false;
var directionflag=1;

var snake_array=[]; //snake body in an array
var speed=150;
var ds=5; //change in speed
var clrReturn;
var score=0;
var length=4;
var flag=0;
var life=3;
var rotate=2; //1 is top, 2 right, 3 down, 4 left

var headtop=new Image();
headtop.src="images/headtop.png";

var headright=new Image();
headright.src="images/headright.png";

var headdown=new Image();
headdown.src="images/headdown.png";

var headleft=new Image();
headleft.src="images/headleft.png";

function create_snake(){

	for(var i=length-1;i>=0;i--){
		snake_array.push({ x:(i+2) , y: 2 }); //snake object with x position variable
	}
	xhead = snake_array[0].x;
	yhead = snake_array[0].y;
}

function drawbody(){

	for(var i=0; i<snake_array.length; i++){

		var temp=snake_array[i];
		if(i==0){
			ctx.beginPath();
			if(rotate==1){
				ctx.drawImage(headtop,temp.x*cw-10,temp.y*cw-20,20,30);
			}
			if(rotate==2){
				ctx.drawImage(headright,temp.x*cw-10,temp.y*cw-10,30,20);
			}
			if(rotate==3){
				ctx.drawImage(headdown,temp.x*cw-10,temp.y*cw-10,20,30);
			}
			if(rotate==4){
				ctx.drawImage(headleft,temp.x*cw-20,temp.y*cw-10,30,20);
			}
	ctx.closePath();
		} else if(temp.x==animx && temp.y==animy){ // for gobbling
		ctx.beginPath();
	ctx.arc(temp.x*cw,temp.y*cw,11,0,2*Math.PI);
	ctx.fillStyle = "darkgreen";
	ctx.fill();
	ctx.strokeStyle = "black";
	ctx.stroke();
	ctx.closePath(); }
	else {
		ctx.beginPath();
	ctx.arc(temp.x*cw,temp.y*cw,8,0,2*Math.PI);
	ctx.fillStyle = "darkgreen";
	ctx.fill();
	ctx.strokeStyle = "black";
	ctx.stroke();
	ctx.closePath();
	}
}
reset_anim();
}

function reset_anim() {
	if(anim_check==0){
	animx=null;
	animy=null;
	}else anim_check--;
}

function food_circle(randnum,xfood,yfood){
		ctx.fillStyle="yellow";
	if(randnum.toString().length==1){
		ctx.arc(xfood,yfood,12,0,2*Math.PI,false);
		ctx.fill();
		ctx.fillStyle="black";
		ctx.fillText(randnum,xfood-5,yfood+7);}
	  else if(randnum.toString().length==2){
		ctx.arc(xfood,yfood,13,0,2*Math.PI,false);
		ctx.fill();
		ctx.fillStyle="black";
		ctx.fillText(randnum,xfood-9,yfood+7);}
	  else if(randnum.toString().length==3){
		ctx.arc(xfood,yfood,15,0,2*Math.PI,false);
		ctx.fill();
		ctx.fillStyle="black";
		ctx.fillText(randnum,xfood-14,yfood+7);}
}

function drawfood(){
	ctx.beginPath();
	ctx.font="bold 16px arial";
	food_circle(randnum1,x1food,y1food);
	ctx.closePath();
	ctx.beginPath();
	food_circle(randnum2,x2food,y2food);
	ctx.closePath();
	ctx.beginPath();
	food_circle(randnum3,x3food,y3food);
	ctx.closePath();
}

function border(){
	ctx.beginPath();
	ctx.rect(0,0,cw+cw/2,canvas.height); //left vertical wall
	ctx.rect(0,0,canvas.width,cw+cw/2);  //top horizontal wall
	ctx.rect(canvas.width-cw-cw/2,0,cw+cw/2,canvas.height); //right vertical wall
	ctx.rect(0,canvas.height-cw,canvas.width,cw); //bottom horizontal wall
	ctx.fillStyle="#6c2e08";
	ctx.fill();
	/*ctx.font="20px arial";
	ctx.fillStyle="black";
	ctx.fillText("Speed: "+speed,20,300);*/
	ctx.closePath();
}

function question(){
	ques=3+Math.floor(Math.random()*12);
	document.getElementById('ques').innerHTML=ques;
}

/*function drawques(){
	ctx.beginPath();
	ctx.fillStyle="blue";
	ctx.font="20px arial";
	ctx.fillText("Which of these numbers is divisible by "+ques ,200,395);
	ctx.closePath();
}*/

function update_game(){
	x1food=45+Math.floor(Math.random()*(canvas.width-80)/15)*15; //between 30 and width-15
	y1food=45+Math.floor(Math.random()*(canvas.height-80)/15)*15; // ^
	x2food=45+Math.floor(Math.random()*(canvas.width-80)/15)*15; //between 30 and width-15
	y2food=45+Math.floor(Math.random()*(canvas.height-80)/15)*15;
	x3food=45+Math.floor(Math.random()*(canvas.width-80)/15)*15; //between 30 and width-15
	y3food=45+Math.floor(Math.random()*(canvas.height-80)/15)*15;
	if(x1food<x2food+30 && y1food<y2food+30 && x1food>x2food-30 && y1food>y2food-30 || x2food<x3food+30 && y2food<y3food+30 && x2food>x3food-30 && y2food>y3food-30 || x1food<x3food+30 && y1food<y3food+30 && x1food>x3food-30 && y1food>y3food-30 ){
		update_game();
	}
	randnum1=2+Math.floor(Math.random()*150);
	randnum2=2+Math.floor(Math.random()*150);
	question();
	randnum3=ques*Math.floor(2+Math.random()*10);
		if(randnum1==randnum2 || randnum2==randnum3 || randnum3==randnum1 || randnum1%ques==0 || randnum2%ques==0){
			update_game();
		} else {
			update_speed();
	}
}

function update_speed(){
	clearInterval(clrReturn);   // clear the initial set interval
		if(speed==50){
			clrReturn=setInterval(move,speed);
		} else{
			speed=speed-ds;				// update the speed to make it faster
			clrReturn=setInterval(move,speed);  // new set interval with new speed
		}
}

function check(){
	document.getElementById("myCanvas").style.backgroundColor="#22d822";
	if(xhead*15==x3food && yhead*15==y3food){
		update_game();
		score++;		// eats the right food
		flag=1;
		animx=xhead; animy=yhead; //save the place where gobbling animation takes place
		anim_check=snake_array.length;
	} else if (xhead*15==x1food && yhead*15== y1food || xhead*15==x2food && yhead*15==y2food) {
		update_game();
		if(score){
		score--;
		}
		life--;		//eats the wrong food
			/*ctx.beginPath();
			ctx.fillStyle="red";
			ctx.rect(cw+cw/2,cw+cw/2,canvas.width-45,canvas.height-35);
			ctx.fill();
			ctx.closePath();*/	//red effect for whole canvas rect
		document.getElementById("myCanvas").style.backgroundColor="red"; //giving red effect
		document.getElementById("life"+(life+1)).style.display= "none";
		flag=1;
		animx=xhead; animy=yhead; //save the place where gobbling animation takes place
		anim_check=snake_array.length;
	}
	document.getElementById('score').innerHTML=score;
}

function move(){
	ctx.clearRect(0,0,canvas.width,canvas.height);
	document.body.style.backgroundColor="white";
	drawbody();
	drawfood();
	//drawques();
	border();
	conditions();
	direction();
	collision();
	check();
	if(flag==1){
		flag=0;
		var tail={ x:xhead, y:yhead };		//tail becomes the new head and tail
	}else {
	var tail=snake_array.pop();		//pop the tail
	tail={ x:xhead, y:yhead };
			}
	snake_array.unshift(tail);		//add tail at the start

	directionflag=1;

}

function conditions(){
			if(xhead*cw<=cw || xhead*cw>=canvas.width-cw || yhead*cw<=cw || yhead*cw>=canvas.height-20 || !life){  //border and lives
				after_collision();
			}
}

function collision(){
	for(var i=0;i<snake_array.length;i++){
		if (snake_array[i].x==xhead && snake_array[i].y==yhead){	//body collision
			after_collision();
		}
	}
}

function after_collision(){
			ctx.beginPath();
			ctx.fillStyle="red";
			ctx.arc(xhead*cw,yhead*cw,10,0,2*Math.PI);
			ctx.fill();
			ctx.strokeStyle="black";
			ctx.stroke();
			ctx.closePath();
			clearInterval(clrReturn);
			play_again();
}

addEventListener("keydown", keyDownHandler, false);

function keyDownHandler(e) {
	if(directionflag==1){
    if( (e.keyCode == 39 || e.keyCode==68) && leftPressed!=true) { 	   //right
        	keyreset();
        	rightPressed = true;
        	directionflag=0;
        	rotate=2;
    }

    else if( (e.keyCode == 37 || e.keyCode==65) && rightPressed!=true) { //left
        	keyreset();
        	leftPressed = true;
        	directionflag=0;
        	rotate=4;
    }

    else if( (e.keyCode == 38 || e.keyCode==87) && bottomPressed!=true){  //top
        	keyreset();
        	topPressed = true;
        	directionflag=0;
        	rotate=1;
    }

    else if( (e.keyCode == 40 || e.keyCode==83)&& topPressed!=true){  //down
        	keyreset();
        	bottomPressed = true;
        	directionflag=0;
        	rotate=3;
    }
}
}

function direction(){

	if(rightPressed==true){ //new head is at the right
		xhead++;
	}
	else if(leftPressed==true){	//new head is at the left
		xhead--;
	}
	else if(bottomPressed==true){	//new head is at the bottom
		yhead++;
	}
	else if(topPressed==true){	//new head is at the top
		yhead--;
	}
}

function keyreset() {
    rightPressed = false;
    leftPressed = false;
    topPressed = false;
    bottomPressed = false;
}

function play_again(){
	alert("GAME OVER\nYour score is: "+score);
	if(confirm("Play again?")){
			location.reload();
	}
}

window.onload = function() {
	canvas = document.getElementById("myCanvas");
	ctx = canvas.getContext("2d");

	for(var i=1;i<=3;i++){
	document.getElementById('life'+i).innerHTML="";
	}

	canvas.width=600; //width
	canvas.height=400; //height

	create_snake();
	update_game();
}
<|endoftext|>


<commit_before>
const EXPORT = ['Config'];

const PrefsBackgroundImage = 'extensions.hatenabookmark.addPanel.backgroundImage';

let Config = {
    get strings() {
        if (!Config._strings) {
            Config._strings = new Strings("chrome://hatenabookmark/locale/config.properties");
        }
        return Config._strings;
    },
    openURLEditor: function() {
        let features = 'chrome,titlebar,toolbar,centerscreen,modal';
        window.openDialog('chrome://hatenabookmark/content/urlEditor.xul', 'URLEditor', features);
    },
    openDialog: function() {
        let features;
        if (Prefs.global.get('browser.preferences.instantApply')) {
            features = 'chrome,titlebar,toolbar,centerscreen,dialog=no';
        } else {
            features = 'chrome,titlebar,toolbar,centerscreen,modal';
        }
        window.openDialog('chrome://hatenabookmark/content/config.xul', 'Preferences', features);
    },
    initDataPane: function() {
        let login = document.getElementById('pref-login');
        let nologin = document.getElementById('pref-nologin');
        let loginbox = document.getElementById('pref-loginbox');
        if (User.user) {
            nologin.setAttribute('hidden', true);
            login.setAttribute('value', Config.strings.get('nowLogin', [User.user.name]));
            loginbox.removeAttribute('hidden');
        } else {
            loginbox.setAttribute('hidden', true);
            nologin.removeAttribute('hidden');
        }
    },
    syncALL: function() {
        if (Config.syncCheck()) return;
        let res = UIUtils.confirm(Config.strings.get('reSyncNotice'));
        if (res) {
            hBookmark.Model.resetAll();
            Sync.sync();
        }
    },
    sync: function() {
        if (Config.syncCheck()) return;
        Sync.sync();
    },
    deleteAll: function() {
        let res = UIUtils.confirm(Config.strings.get('deleteAllNotice'));
        if (res) {
            Config._deleteAll();
        }
    },
    _deleteAll: function() {
        User.logout(); // logout しないと、DB のコネクションが残り、SQLite ファイルが削除できない
        let pd = DirectoryService.get("ProfD", Ci.nsIFile);
        pd.append('hatenabookmark');
        if (pd.exists() && pd.isDirectory()) {
            pd.remove(true);
        }
    },
    syncCheck: function() {
        if (!User.user) {
            // むむ
            alert(Config.strings.get('loginToHatena'));
            // pref window がでてると、dialog 表示で addons window がおかしくなる
            // UIUtils.encourageLogin();
            return true;
        }
        if (Sync.nowSyncing) {
            // むむ
            alert(Config.strings.get('nowSyncing'));
            return true;
        }
        return false;
    },
    updateUI: function() {
        let file = document.getElementById(PrefsBackgroundImage).value;
        if (file) {
            let fileField = document.getElementById('addPanel.backgroundImage');
            if (fileField)
                fileField.file = file;
        }
        let migemo = document.getElementById('addPanel.xulMigemo');
        if (!XMigemoCore) {
            migemo.removeAttribute('preference');
            migemo.preference = null;
            migemo.setAttribute('checked', false);
            migemo.setAttribute('disabled', true);
        }
    },
    updateStatus: function() {
        let checked = document.getElementById('extensions.hatenabookmark.commentviewer.autoResize-check').checked;

        let w = document.getElementById('commentviewer.width');
        let h = document.getElementById('commentviewer.height');
        if (checked) {
            w.setAttribute('disabled', true);
            h.setAttribute('disabled', true);
        } else {
            w.removeAttribute('disabled');
            h.removeAttribute('disabled');
        }

        checked = document.getElementById('extensions.hatenabookmark.commentviewer.autoFilter-check').checked;
        let th = document.getElementById('commentviewer.autoFilterThreshold');
        if (checked) {
            th.removeAttribute('disabled');
        } else {
            th.setAttribute('disabled', true);
        }
    },
    browsingStatusDependencies: {
        'enabled-check': ['counter-check', 'addButton-check'],
        'search-check': ['searchCount-field'],
    },
    updateBrowsingStatus: function() {
        const ID_PREFIX = 'extensions.hatenabookmark.embed.';
        for (let [master, slaves] in Iterator(this.browsingStatusDependencies)) {
            let disabled = !document.getElementById(ID_PREFIX + master).checked;
            slaves.forEach(function (slave) {
                document.getElementById(ID_PREFIX + slave).disabled = disabled;
            });
        }
    },
    clearImageFile: function() {
        let file = document.getElementById(PrefsBackgroundImage).value;
        if (file) {
            let fileField = document.getElementById('addPanel.backgroundImage');
            fileField.file = null;
            fileField.label = '';
            try {
                document.getElementById(PrefsBackgroundImage).reset();
            } catch(e) {};
        }
        // let fileField = document.getElementById('addPanel.backgroundImage');
        // fileField.file = '';
        // fileField.label = '';
    },
    selectImageFile: function() {
        let filePicker = Components.classes["@mozilla.org/filepicker;1"]
                         .createInstance(Components.interfaces.nsIFilePicker);
        filePicker.init(window, UIEncodeText("画像を選択して下さい"), filePicker.modeOpen);
        filePicker.appendFilters(Components.interfaces.nsIFilePicker.filterIamges);
        if (filePicker.show() == filePicker.returnOK) {
            document.getElementById(PrefsBackgroundImage).value = filePicker.file;
            Config.updateUI();
        }
    },
    goHelp: function(event) {
        hOpenUILink('http://b.hatena.ne.jp/help/firefox_addon_view', event);
    },
};

/*
 * base code by XUL/Migemo config.js.
 * thx Piro!
 */
Config.ShortCut = {
    prefPrefix: 'extensions.hatenabookmark.shortcut.keys.',
    KEYS: ['add', 'comment', 'sidebar'],
    keys: {},
    initPane: function() {
        var self = this;
        this.KEYS.forEach(function(key) {
            let k = document.getElementById(self.prefPrefix + key + '-input');
            k.keyData = parseShortcut(k.value);
            self.keys[key] = k;
        });
        // let add = document.getElementById('add-input');
        // add.keyData = parseShortcut(add.value);
        // this.add = add;
    },
    set: function(aNode) {
        let keyData = {};
        window.openDialog(
            'chrome://hatenabookmark/content/keyDetecter.xul',
            '_blank',
            'chrome,modal,resizable=no,titlebar=no,centerscreen',
            keyData,
            Config.strings.get('setShortcut'),
            Config.strings.get('cancel')
        );
        if (keyData.modified) {
            aNode.value = keyData.string;
            var event = document.createEvent('UIEvents');
            event.initUIEvent('input', true, false, window, 0);
            aNode.dispatchEvent(event);
        }
    },
    clear: function(aNode) {
        aNode.value = '';
        aNode.keyData = parseShortcut(aNode.value);
        aNode.keyData.modified = true;

        fireInputEvent(aNode);
    },
}

function fireInputEvent(aNode)
{
    var event = document.createEvent('UIEvents');
    event.initUIEvent('input', true, false, window, 0);
    aNode.dispatchEvent(event);
}

<commit_msg>Web検索と全文検索の統合: ログインしてないとき、プラスユーザでないときは設定をいじれないように。<commit_after>
const EXPORT = ['Config'];

const PrefsBackgroundImage = 'extensions.hatenabookmark.addPanel.backgroundImage';

let Config = {
    get strings() {
        if (!Config._strings) {
            Config._strings = new Strings("chrome://hatenabookmark/locale/config.properties");
        }
        return Config._strings;
    },
    openURLEditor: function() {
        let features = 'chrome,titlebar,toolbar,centerscreen,modal';
        window.openDialog('chrome://hatenabookmark/content/urlEditor.xul', 'URLEditor', features);
    },
    openDialog: function() {
        let features;
        if (Prefs.global.get('browser.preferences.instantApply')) {
            features = 'chrome,titlebar,toolbar,centerscreen,dialog=no';
        } else {
            features = 'chrome,titlebar,toolbar,centerscreen,modal';
        }
        window.openDialog('chrome://hatenabookmark/content/config.xul', 'Preferences', features);
    },
    initDataPane: function() {
        let login = document.getElementById('pref-login');
        let nologin = document.getElementById('pref-nologin');
        let loginbox = document.getElementById('pref-loginbox');
        if (User.user) {
            nologin.setAttribute('hidden', true);
            login.setAttribute('value', Config.strings.get('nowLogin', [User.user.name]));
            loginbox.removeAttribute('hidden');
        } else {
            loginbox.setAttribute('hidden', true);
            nologin.removeAttribute('hidden');
        }
    },
    syncALL: function() {
        if (Config.syncCheck()) return;
        let res = UIUtils.confirm(Config.strings.get('reSyncNotice'));
        if (res) {
            hBookmark.Model.resetAll();
            Sync.sync();
        }
    },
    sync: function() {
        if (Config.syncCheck()) return;
        Sync.sync();
    },
    deleteAll: function() {
        let res = UIUtils.confirm(Config.strings.get('deleteAllNotice'));
        if (res) {
            Config._deleteAll();
        }
    },
    _deleteAll: function() {
        User.logout(); // logout しないと、DB のコネクションが残り、SQLite ファイルが削除できない
        let pd = DirectoryService.get("ProfD", Ci.nsIFile);
        pd.append('hatenabookmark');
        if (pd.exists() && pd.isDirectory()) {
            pd.remove(true);
        }
    },
    syncCheck: function() {
        if (!User.user) {
            // むむ
            alert(Config.strings.get('loginToHatena'));
            // pref window がでてると、dialog 表示で addons window がおかしくなる
            // UIUtils.encourageLogin();
            return true;
        }
        if (Sync.nowSyncing) {
            // むむ
            alert(Config.strings.get('nowSyncing'));
            return true;
        }
        return false;
    },
    updateUI: function() {
        let file = document.getElementById(PrefsBackgroundImage).value;
        if (file) {
            let fileField = document.getElementById('addPanel.backgroundImage');
            if (fileField)
                fileField.file = file;
        }
        let migemo = document.getElementById('addPanel.xulMigemo');
        if (!XMigemoCore) {
            migemo.removeAttribute('preference');
            migemo.preference = null;
            migemo.setAttribute('checked', false);
            migemo.setAttribute('disabled', true);
        }
    },
    updateStatus: function() {
        let checked = document.getElementById('extensions.hatenabookmark.commentviewer.autoResize-check').checked;

        let w = document.getElementById('commentviewer.width');
        let h = document.getElementById('commentviewer.height');
        if (checked) {
            w.setAttribute('disabled', true);
            h.setAttribute('disabled', true);
        } else {
            w.removeAttribute('disabled');
            h.removeAttribute('disabled');
        }

        checked = document.getElementById('extensions.hatenabookmark.commentviewer.autoFilter-check').checked;
        let th = document.getElementById('commentviewer.autoFilterThreshold');
        if (checked) {
            th.removeAttribute('disabled');
        } else {
            th.setAttribute('disabled', true);
        }
    },
    browsingStatusDependencies: {
        'enabled-check': ['counter-check', 'addButton-check'],
        'search-check': ['searchCount-field'],
    },
    updateBrowsingStatus: function() {
        const ID_PREFIX = 'extensions.hatenabookmark.embed.';
        let dependencies = this.browsingStatusDependencies;
        for (let [master, slaves] in Iterator(dependencies)) {
            let disabled = !document.getElementById(ID_PREFIX + master).checked;
            slaves.forEach(function (slave) {
                document.getElementById(ID_PREFIX + slave).disabled = disabled;
            });
        }
        if (!User.user || !User.user.plususer) {
            ['search-check'].concat(dependencies['search-check']).forEach(function (key) {
                document.getElementById(ID_PREFIX + key).disabled = true;
            });
        }
    },
    clearImageFile: function() {
        let file = document.getElementById(PrefsBackgroundImage).value;
        if (file) {
            let fileField = document.getElementById('addPanel.backgroundImage');
            fileField.file = null;
            fileField.label = '';
            try {
                document.getElementById(PrefsBackgroundImage).reset();
            } catch(e) {};
        }
        // let fileField = document.getElementById('addPanel.backgroundImage');
        // fileField.file = '';
        // fileField.label = '';
    },
    selectImageFile: function() {
        let filePicker = Components.classes["@mozilla.org/filepicker;1"]
                         .createInstance(Components.interfaces.nsIFilePicker);
        filePicker.init(window, UIEncodeText("画像を選択して下さい"), filePicker.modeOpen);
        filePicker.appendFilters(Components.interfaces.nsIFilePicker.filterIamges);
        if (filePicker.show() == filePicker.returnOK) {
            document.getElementById(PrefsBackgroundImage).value = filePicker.file;
            Config.updateUI();
        }
    },
    goHelp: function(event) {
        hOpenUILink('http://b.hatena.ne.jp/help/firefox_addon_view', event);
    },
};

/*
 * base code by XUL/Migemo config.js.
 * thx Piro!
 */
Config.ShortCut = {
    prefPrefix: 'extensions.hatenabookmark.shortcut.keys.',
    KEYS: ['add', 'comment', 'sidebar'],
    keys: {},
    initPane: function() {
        var self = this;
        this.KEYS.forEach(function(key) {
            let k = document.getElementById(self.prefPrefix + key + '-input');
            k.keyData = parseShortcut(k.value);
            self.keys[key] = k;
        });
        // let add = document.getElementById('add-input');
        // add.keyData = parseShortcut(add.value);
        // this.add = add;
    },
    set: function(aNode) {
        let keyData = {};
        window.openDialog(
            'chrome://hatenabookmark/content/keyDetecter.xul',
            '_blank',
            'chrome,modal,resizable=no,titlebar=no,centerscreen',
            keyData,
            Config.strings.get('setShortcut'),
            Config.strings.get('cancel')
        );
        if (keyData.modified) {
            aNode.value = keyData.string;
            var event = document.createEvent('UIEvents');
            event.initUIEvent('input', true, false, window, 0);
            aNode.dispatchEvent(event);
        }
    },
    clear: function(aNode) {
        aNode.value = '';
        aNode.keyData = parseShortcut(aNode.value);
        aNode.keyData.modified = true;

        fireInputEvent(aNode);
    },
}

function fireInputEvent(aNode)
{
    var event = document.createEvent('UIEvents');
    event.initUIEvent('input', true, false, window, 0);
    aNode.dispatchEvent(event);
}

<|endoftext|>