'use strict';

var toArray  = require('es5-ext/array/from')
  , htmlForm = require('dom-ext/html-form-element/valid-html-form-element')

  , isArray = Array.isArray, forEach = Array.prototype.forEach
  , push = Array.prototype.push;

module.exports = function () {
	var data = {};
	forEach.call(htmlForm(this).elements, function (control) {
		var name, type, nodeName, value;
		if (control.disabled) return;
		nodeName = control.nodeName.toLowerCase();
		if (nodeName === 'fieldset') return;
		if (nodeName === 'button') return;

		value = control.value;
		if (nodeName === 'select') {
			if (control.multiple) {
				value = [];
				forEach.call(control.options, function (option) {
					if (option.selected) value.push(option.value);
				});
			}
		} else if (nodeName === 'input') {
			type = control.getAttribute('type') || 'text';
			if ((type === 'submit') || (type === 'image') || (type === 'reset') || (type === 'button')) {
				return;
			}
			if (((type === 'radio') || (type === 'checkbox')) && !control.checked) {
				return;
			}
			if (type === 'file') {
				value = toArray(control.files);
				if (!value.length) value = null;
				else if (value.length === 1) value = value[0];
			}
		}
		name = control.name;
		if (data.hasOwnProperty(name)) {
			if (value == null) return;
			if (!isArray(data[name])) (data[name] = [data[name]]);
			if (isArray(value)) push.apply(data[name], value);
			else data[name].push(value);
			return;
		}
		data[name] = value;
	});
	return data;
};

@@ -1310,16 +1310,25 @@
 %5Bname%5D))
+ %7B%0A%09%09%09%09if
  (data%5Bn
@@ -1337,23 +1337,97 @@
 e%5D =
- %5Bdata%5Bname%5D%5D);
+= null) %7B%0A%09%09%09%09%09data%5Bname%5D = value;%0A%09%09%09%09%09return;%0A%09%09%09%09%7D%0A%09%09%09%09data%5Bname%5D = %5Bdata%5Bname%5D%5D;%0A%09%09%09%7D
 %0A%09%09%09

Improve null value handling