<commit_before>/* global describe, it */

'use strict';

const { expect } = require('chai');

const xmlReader = require('../lib/xml-reader');

describe('xml-reader', () => {
    describe('DataSources', () => {
        it('should parse simple database data source without query', done => {
            xmlReader(__dirname + '/fixtures/xml-reader/datasource-simple.xml')
                .then(config => {
                    expect(config.dataSources).to.deep.equal({
                        primary: {
                            type: 'mysql',
                            database: 'db',
                            table: 'country'
                        }
                    });
                    done();
                })
                .catch(done);
        });

        it('should parse database data source with SQL query', done => {
            xmlReader(__dirname + '/fixtures/xml-reader/datasource-custom-query.xml')
                .then(config => {
                    expect(config.dataSources).to.eql({
                        primary: {
                            type: 'mysql',
                            database: 'db',
                            query: "SELECT * FROM foo WHERE field = 'bar'"
                        }
                    });
                    done();
                })
                .catch(done);
        });

        it('should parse join attributes', done => {
            xmlReader(__dirname + '/fixtures/xml-reader/datasource-join-attributes.xml')
                .then(config => {
                    expect(config.attributes['sub-resource'].dataSources).to.eql({
                        primary: {
                            type: 'mysql',
                            database: 'db',
                            table: 'some_table',
                            parentKey: '{primary}',
                            childKey: '{primary}',
                            joinVia: 'some_relation_table',
                            many: 'true'
                        }
                    });
                    done();
                })
                .catch(done);
        });

        it('should throw an error on option w/o name attribute', done => {
            xmlReader(__dirname + '/fixtures/xml-reader/datasource-option-without-name-attr.xml').catch(err => {
                expect(err).to.be.instanceof(Error);
                expect(err.message).to.have.string('flora:option element requires a name attribute');
                done();
            });
        });

        it('should throw an error on duplicate option names', done => {
            xmlReader(__dirname + '/fixtures/xml-reader/datasource-duplicate-option.xml').catch(err => {
                expect(err).to.be.instanceof(Error);
                expect(err.message).to.have.string('Data source option "query" already defined');
                done();
            });
        });

        it('should throw an error on duplicate data source names', done => {
            xmlReader(__dirname + '/fixtures/xml-reader/datasource-duplicates.xml').catch(err => {
                expect(err).to.be.instanceof(Error);
                expect(err.message).to.have.string('Data source "primary" already defined');
                done();
            });
        });

        it('should throw an error if datasource node contains text nodes', done => {
            xmlReader(__dirname + '/fixtures/xml-reader/invalid-datasource-text-node.xml').catch(err => {
                expect(err).to.be.instanceof(Error);
                expect(err.message).to.contains('dataSource contains useless text');
                done();
            });
        });

        it('should throw an if xml contains invalid text nodes', done => {
            xmlReader(__dirname + '/fixtures/xml-reader/invalid-text-node.xml').catch(err => {
                try {
                    expect(err).to.be.instanceof(Error);
                    expect(err.message).to.contains('Config contains unnecessary text');
                    done();
                } catch (e) {
                    done(e);
                }
            });
        });
    });

    it('should parse primary keys', done => {
        xmlReader(__dirname + '/fixtures/xml-reader/primary-keys.xml')
            .then(config => {
                expect(config).to.eql({
                    primaryKey: 'pk_id',
                    attributes: {
                        subresource1: {
                            primaryKey: 'id',
                            dataSources: {
                                primary: { type: 'mysql', database: 'db', table: 'table' }
                            },
                            attributes: { name: {} }
                        }
                    }
                });
                done();
            })
            .catch(done);
    });

    it('should parse attributes', done => {
        xmlReader(__dirname + '/fixtures/xml-reader/attributes.xml')
            .then(config => {
                expect(config).to.eql({
                    attributes: {
                        someAttribute: { type: 'integer' },
                        someOtherAttribute: { order: 'true' },
                        someBooleanAttribute: { type: 'boolean', map: 'weirdField' },
                        group: {
                            attributes: {
                                subAttribute1: { filter: 'equals' },
                                subAttribute2: {}
                            }
                        }
                    }
                });
                done();
            })
            .catch(done);
    });

    it('should not parse namespaced nodes (i.e. flora:xxx) as attributes', done => {
        xmlReader(__dirname + '/fixtures/xml-reader/subfilter.xml')
            .then(config => {
                expect(config).to.eql({
                    attributes: {
                        'sub-resource': {
                            type: 'resource',
                            resource: 'some-resource',
                            subFilters: [{ attribute: 'otherAttribute', filter: 'equal' }]
                        }
                    },
                    subFilters: [{ attribute: 'someAttribute', filter: 'equal' }]
                });
                done();
            })
            .catch(done);
    });

    it('should parse sub-resources (with all options)', done => {
        xmlReader(__dirname + '/fixtures/xml-reader/subresource.xml')
            .then(config => {
                expect(config).to.eql({
                    attributes: {
                        subresource1: { type: 'resource', resource: 'otherresource' },
                        attr: {},
                        subresource2: {
                            primaryKey: 'id',
                            parentKey: '{primary}',
                            childKey: '{primary}',
                            dataSources: {
                                primary: {
                                    type: 'mysql',
                                    database: 'db',
                                    table: 'table'
                                }
                            },
                            attributes: {
                                id: { type: 'integer' },
                                name: {}
                            }
                        }
                    }
                });
                done();
            })
            .catch(done);
    });

    it('should preserve order for attributes and sub-resources', done => {
        xmlReader(__dirname + '/fixtures/xml-reader/subresource.xml')
            .then(config => {
                const keys = Object.keys(config.attributes);
                expect(keys[0]).to.equal('subresource1');
                expect(keys[1]).to.equal('attr');
                expect(keys[2]).to.equal('subresource2');
                done();
            })
            .catch(done);
    });

    it('should generate an error if XML cannot be parsed', done => {
        xmlReader(__dirname + '/fixtures/xml-reader/broken.xml').catch(err => {
            expect(err).to.be.instanceof(Error);
            done();
        });
    });

    it('should generate an error if XML contains nodes with same name', done => {
        xmlReader(__dirname + '/fixtures/xml-reader/duplicate-node.xml').catch(err => {
            expect(err)
                .to.be.instanceof(Error)
                .and.has.property('message', 'Resource already contains an attribute with name "node"');
            done();
        });
    });

    it('should parse flora specific elements by uri namespace (instead of prefix)', done => {
        xmlReader(__dirname + '/fixtures/xml-reader/namespace-uri.xml')
            .then(config => {
                expect(config).to.eql({
                    dataSources: {
                        primary: {
                            type: 'mysql',
                            database: 'db',
                            table: 't'
                        }
                    }
                });
                done();
            })
            .catch(done);
    });
});
<commit_msg>Async-awaitify xml-reader tests<commit_after>/* global describe, it */

'use strict';

const { expect } = require('chai');

const xmlReader = require('../lib/xml-reader');

describe('xml-reader', () => {
    describe('DataSources', () => {
        it('should parse simple database data source without query', async () => {
            const config = await xmlReader(__dirname + '/fixtures/xml-reader/datasource-simple.xml');

            expect(config.dataSources).to.deep.equal({
                primary: {
                    type: 'mysql',
                    database: 'db',
                    table: 'country'
                }
            });
        });

        it('should parse database data source with SQL query', async () => {
            const config = await xmlReader(__dirname + '/fixtures/xml-reader/datasource-custom-query.xml');

            expect(config.dataSources).to.eql({
                primary: {
                    type: 'mysql',
                    database: 'db',
                    query: "SELECT * FROM foo WHERE field = 'bar'"
                }
            });
        });

        it('should parse join attributes', async () => {
            const config = await xmlReader(__dirname + '/fixtures/xml-reader/datasource-join-attributes.xml');

            expect(config.attributes['sub-resource'].dataSources).to.eql({
                primary: {
                    type: 'mysql',
                    database: 'db',
                    table: 'some_table',
                    parentKey: '{primary}',
                    childKey: '{primary}',
                    joinVia: 'some_relation_table',
                    many: 'true'
                }
            });
        });

        it('should throw an error on option w/o name attribute', async () => {
            try {
                await xmlReader(__dirname + '/fixtures/xml-reader/datasource-option-without-name-attr.xml');
            } catch (err) {
                expect(err)
                    .to.be.instanceof(Error)
                    .and.to.have.property('message', 'flora:option element requires a name attribute');
                return;
            }

            throw new Error('Expected an error');
        });

        it('should throw an error on duplicate option names', async () => {
            try {
                await xmlReader(__dirname + '/fixtures/xml-reader/datasource-duplicate-option.xml');
            } catch (err) {
                expect(err)
                    .to.be.instanceof(Error)
                    .and.to.have.property('message', 'Data source option "query" already defined');
                return;
            }

            throw new Error('Expected an error');
        });

        it('should throw an error on duplicate data source names', async () => {
            try {
                await xmlReader(__dirname + '/fixtures/xml-reader/datasource-duplicates.xml');
            } catch (err) {
                expect(err)
                    .to.be.instanceof(Error)
                    .and.to.have.property('message', 'Data source "primary" already defined');
                return;
            }

            throw new Error('Expected an error');
        });

        it('should throw an error if datasource node contains text nodes', async () => {
            try {
                await xmlReader(__dirname + '/fixtures/xml-reader/invalid-datasource-text-node.xml');
            } catch (err) {
                expect(err)
                    .to.be.instanceof(Error)
                    .and.to.have.property('message')
                    .contains('dataSource contains useless text');
                return;
            }

            throw new Error('Expected an error');
        });

        it('should throw an if xml contains invalid text nodes', async () => {
            try {
                await xmlReader(__dirname + '/fixtures/xml-reader/invalid-text-node.xml');
            } catch (err) {
                expect(err)
                    .to.be.instanceof(Error)
                    .to.have.property('message')
                    .contains('Config contains unnecessary text');
                return;
            }

            throw new Error('Expected an error');
        });
    });

    it('should parse primary keys', async () => {
        const config = await xmlReader(__dirname + '/fixtures/xml-reader/primary-keys.xml');

        expect(config).to.eql({
            primaryKey: 'pk_id',
            attributes: {
                subresource1: {
                    primaryKey: 'id',
                    dataSources: {
                        primary: { type: 'mysql', database: 'db', table: 'table' }
                    },
                    attributes: { name: {} }
                }
            }
        });
    });

    it('should parse attributes', async () => {
        const config = await xmlReader(__dirname + '/fixtures/xml-reader/attributes.xml');

        expect(config).to.eql({
            attributes: {
                someAttribute: { type: 'integer' },
                someOtherAttribute: { order: 'true' },
                someBooleanAttribute: { type: 'boolean', map: 'weirdField' },
                group: {
                    attributes: {
                        subAttribute1: { filter: 'equals' },
                        subAttribute2: {}
                    }
                }
            }
        });
    });

    it('should not parse namespaced nodes (i.e. flora:xxx) as attributes', async () => {
        const config = await xmlReader(__dirname + '/fixtures/xml-reader/subfilter.xml');

        expect(config).to.eql({
            attributes: {
                'sub-resource': {
                    type: 'resource',
                    resource: 'some-resource',
                    subFilters: [{ attribute: 'otherAttribute', filter: 'equal' }]
                }
            },
            subFilters: [{ attribute: 'someAttribute', filter: 'equal' }]
        });
    });

    it('should parse sub-resources (with all options)', async () => {
        const config = await xmlReader(__dirname + '/fixtures/xml-reader/subresource.xml');

        expect(config).to.eql({
            attributes: {
                subresource1: { type: 'resource', resource: 'otherresource' },
                attr: {},
                subresource2: {
                    primaryKey: 'id',
                    parentKey: '{primary}',
                    childKey: '{primary}',
                    dataSources: {
                        primary: {
                            type: 'mysql',
                            database: 'db',
                            table: 'table'
                        }
                    },
                    attributes: {
                        id: { type: 'integer' },
                        name: {}
                    }
                }
            }
        });
    });

    it('should preserve order for attributes and sub-resources', async () => {
        const config = await xmlReader(__dirname + '/fixtures/xml-reader/subresource.xml');
        const keys = Object.keys(config.attributes);

        expect(keys).to.eql(['subresource1', 'attr', 'subresource2']);
    });

    it('should generate an error if XML cannot be parsed', async () => {
        try {
            await xmlReader(__dirname + '/fixtures/xml-reader/broken.xml');
        } catch (err) {
            expect(err).to.be.instanceof(Error);
            return;
        }

        throw new Error('Expected an error');
    });

    it('should generate an error if XML contains nodes with same name', async () => {
        try {
            await xmlReader(__dirname + '/fixtures/xml-reader/duplicate-node.xml');
        } catch (err) {
            expect(err)
                .to.be.instanceof(Error)
                .and.has.property('message', 'Resource already contains an attribute with name "node"');
            return;
        }

        throw new Error('Expected an error');
    });

    it('should parse flora specific elements by uri namespace (instead of prefix)', async () => {
        const config = await xmlReader(__dirname + '/fixtures/xml-reader/namespace-uri.xml');

        expect(config).to.eql({
            dataSources: {
                primary: {
                    type: 'mysql',
                    database: 'db',
                    table: 't'
                }
            }
        });
    });
});
<|endoftext|>


<commit_before>var esprima = require('esprima');
var fs = require('fs');

Blend.defineClass('Builder.analyzer.Parser', {
    parseOptions: null,
    lastError: null,
    visitor: function () {
        return false;
    },
    init: function () {
        var me = this;
        me.callParent.apply(me, arguments);
        me.parseOptions = me.parseOptions || {};
        me.parseOptions = Blend.apply(me.parseOptions, {tolerant: true});
    },
    parse: function (filename) {
        var me = this,
                syntax;
        try {
            syntax = esprima.parse(fs.readFileSync(filename, 'utf-8'), me.parseOptions);
            return {
                success: me.traverse(syntax),
                error: me.lastError
            };
        } catch (e) {
            return {
                success: false,
                error: e
            };
        }
    },
    /**
     * Executes visitor on the object and its children (recursively).
     * Source: esprima.org
     * @param {type} object
     * @param {type} visitor
     * @returns {undefined}
     */
    traverse: function (object) {
        var me = this, key, child, ok;
        ok = me.visitor.apply(me, [object]);
        if (ok) {
            for (key in object) {
                if (object.hasOwnProperty(key) && ok) {
                    child = object[key];
                    if (typeof child === 'object' && child !== null) {
                        ok = me.traverse(child);
                    }
                }
            }
        }
        return ok;
    },
});

<commit_msg>Added NULL AST checker function<commit_after>var esprima = require('esprima');
var fs = require('fs');

Blend.defineClass('Builder.analyzer.Parser', {
    parseOptions: null,
    lastError: null,
    visitor: function () {
        return false;
    },
    init: function () {
        var me = this;
        me.callParent.apply(me, arguments);
        me.parseOptions = me.parseOptions || {};
        me.parseOptions = Blend.apply(me.parseOptions, {tolerant: true});
    },
    parse: function (filename) {
        var me = this,
                syntax;
        try {
            syntax = esprima.parse(fs.readFileSync(filename, 'utf-8'), me.parseOptions);
            return {
                success: me.traverse(syntax),
                error: me.lastError
            };
        } catch (e) {
            return {
                success: false,
                error: e
            };
        }
    },
    /**
     * Executes visitor on the object and its children (recursively).
     * Source: esprima.org
     * @param {type} object
     * @param {type} visitor
     * @returns {undefined}
     */
    traverse: function (object) {
        var me = this, key, child, ok;
        ok = me.visitor.apply(me, [object]);
        if (ok) {
            for (key in object) {
                if (object.hasOwnProperty(key) && ok) {
                    child = object[key];
                    if (typeof child === 'object' && child !== null) {
                        ok = me.traverse(child);
                    }
                }
            }
        }
        return ok;
    },
    isNullAST: function (obj) {
        return (obj.type && obj.type === 'Literal' && obj.value === null);
    }
});

<|endoftext|>


<commit_before>define(function (require, exports, module) {
    "use strict";

    var CommandManager = brackets.getModule("command/CommandManager"),
        Menus          = brackets.getModule("command/Menus"),
        WorkspaceManager = brackets.getModule("view/WorkspaceManager");

    var parse = require("slowparse/slowparse");

    // Function to run when the menu item is clicked
    function parser() {
        var result = parse.HTML(document, '<a href+></a>');
        console.log(result.error);
        var obj = result.error;
        console.log(obj.type);
        console.log(obj.start);
        console.log(obj.end);
    }

    // First, register a command - a UI-less object associating an id to a handler
    var MY_COMMAND_ID = "slowparse"; // package-style naming to avoid collisions
    CommandManager.register("Show Slowparse Panel", MY_COMMAND_ID, parser);

    // Then create a menu item bound to the command
    // The label of the menu item is the name we gave the command (see above)
    var menu = Menus.getMenu(Menus.AppMenuBar.FILE_MENU);
    menu.addMenuItem(MY_COMMAND_ID);

    // We could also add a key binding at the same time:
    //menu.addMenuItem(MY_COMMAND_ID, "Ctrl-Alt-H");
    // (Note: "Ctrl" is automatically mapped to "Cmd" on Mac)
});<commit_msg>added getText and null condition<commit_after>define(function (require, exports, module) {
    "use strict";

    var CommandManager = brackets.getModule("command/CommandManager"),
        Menus          = brackets.getModule("command/Menus"),
        EditorManager   = brackets.getModule("editor/EditorManager"),
        WorkspaceManager = brackets.getModule("view/WorkspaceManager");

    var parse = require("slowparse/slowparse");

    // Function to run when the menu item is clicked
    function parser() {
        var editor = EditorManager.getFocusedEditor();
        var text   = editor.document.getText();
        var result = parse.HTML(document, text);
        console.log(result.error);

        if(result.error){
            var obj = result.error;
            console.log(obj.type);
            console.log(obj.start);
            console.log(obj.end);
        }
    }

    // First, register a command - a UI-less object associating an id to a handler
    var MY_COMMAND_ID = "slowparse"; // package-style naming to avoid collisions
    CommandManager.register("Show Slowparse Panel", MY_COMMAND_ID, parser);

    // Then create a menu item bound to the command
    // The label of the menu item is the name we gave the command (see above)
    var menu = Menus.getMenu(Menus.AppMenuBar.FILE_MENU);
    menu.addMenuItem(MY_COMMAND_ID);

    // We could also add a key binding at the same time:
    //menu.addMenuItem(MY_COMMAND_ID, "Ctrl-Alt-H");
    // (Note: "Ctrl" is automatically mapped to "Cmd" on Mac)
});<|endoftext|>


<commit_before>import {S3} from "aws-sdk";
import s3 from "s3";

const AWS_ACCESS_KEY_ID = process.env.AWS_ACCESS_KEY_ID;
const AWS_SECRET_ACCESS_KEY = process.env.AWS_SECRET_ACCESS_KEY;
const S3_BUCKET = process.env.S3_BUCKET;
const APP_DOMAIN = process.env.APP_DOMAIN;
const APP_STAGE = process.env.APP_DOMAIN;
const APP_SOURCE_DIR = process.argv[2];

const s3Client = new S3({
    apiVersion: "2006-03-01",
    accessKeyId: AWS_ACCESS_KEY_ID,
    secretAccessKey: AWS_SECRET_ACCESS_KEY
});

s3Client.getBucketLocation({Bucket: S3_BUCKET}, (err, res) => {
    s3
        .createClient({
            s3Options: {
                accessKeyId: AWS_ACCESS_KEY_ID,
                secretAccessKey: AWS_SECRET_ACCESS_KEY,
                region: res.LocationConstraint
            }
        })
        .uploadDir({
            localDir: APP_SOURCE_DIR,
            s3Params: {
                Bucket: S3_BUCKET,
                Prefix: `/${APP_DOMAIN}/${APP_STAGE}`
            }
        })
        .on("end", () => {
            console.log("Uploaded succeeded");
        });
});
<commit_msg>Fix APP_STAGE<commit_after>import {S3} from "aws-sdk";
import {execSync} from "child_process";
import s3 from "s3";

function getAppStage () {
    return (
        process.env.APP_STAGE ||
        execSync("git rev-parse --abbrev-ref HEAD")
    );
}

const AWS_ACCESS_KEY_ID = process.env.AWS_ACCESS_KEY_ID;
const AWS_SECRET_ACCESS_KEY = process.env.AWS_SECRET_ACCESS_KEY;
const S3_BUCKET = process.env.S3_BUCKET;
const APP_DOMAIN = process.env.APP_DOMAIN;
const APP_STAGE = getAppStage();
const APP_SOURCE_DIR = process.argv[2];

const s3Client = new S3({
    apiVersion: "2006-03-01",
    accessKeyId: AWS_ACCESS_KEY_ID,
    secretAccessKey: AWS_SECRET_ACCESS_KEY
});

s3Client.getBucketLocation({Bucket: S3_BUCKET}, (err, res) => {
    s3
        .createClient({
            s3Options: {
                accessKeyId: AWS_ACCESS_KEY_ID,
                secretAccessKey: AWS_SECRET_ACCESS_KEY,
                region: res.LocationConstraint
            }
        })
        .uploadDir({
            localDir: APP_SOURCE_DIR,
            s3Params: {
                Bucket: S3_BUCKET,
                Prefix: `/${APP_DOMAIN}/${APP_STAGE}`
            }
        })
        .on("end", () => {
            console.log("Uploaded succeeded");
        });
});
<|endoftext|>


<commit_before>(function(hello) {

	hello.init({

		linkedin: {

			oauth: {
				version: 2,
				response_type: 'code',
				auth: 'https://www.linkedin.com/uas/oauth2/authorization',
				grant: 'https://www.linkedin.com/uas/oauth2/accessToken'
			},

			// Refresh the access_token once expired
			refresh: true,

			scope: {
				basic: 'r_fullprofile',
				email: 'r_emailaddress',
				friends: 'r_network',
				publish: 'rw_nus'
			},
			scope_delim: ' ',

			base: 'https://api.linkedin.com/v1/',

			get: {
				me: 'people/~:(picture-url,first-name,last-name,id,formatted-name,email-address)',
				'me/friends': 'people/~/connections?count=@{limit|500}',
				'me/followers': 'people/~/connections?count=@{limit|500}',
				'me/following': 'people/~/connections?count=@{limit|500}',

				// See: http://developer.linkedin.com/documents/get-network-updates-and-statistics-api
				'me/share': 'people/~/network/updates?count=@{limit|250}'
			},

			post: {

				// See: https://developer.linkedin.com/documents/api-requests-json
				'me/share': function(p, callback) {
					var data = {
						visibility: {
							code: 'anyone'
						}
					};

					if (p.data.id) {

						data.attribution = {
							share: {
								id: p.data.id
							}
						};

					}
					else {
						data.comment = p.data.message;
						if (p.data.picture && p.data.link) {
							data.content = {
								'submitted-url': p.data.link,
								'submitted-image-url': p.data.picture
							};
						}
					}

					p.data = JSON.stringify(data);

					callback('people/~/shares?format=json');
				},

				'me/like': like
			},

			del:{
				'me/like': like
			},

			wrap: {
				me: function(o) {
					formatError(o);
					formatUser(o);
					return o;
				},

				'me/friends': formatFriends,
				'me/following': formatFriends,
				'me/followers': formatFriends,
				'me/share': function(o) {
					formatError(o);
					paging(o);
					if (o.values) {
						o.data = o.values.map(formatUser);
						o.data.forEach(function(item) {
							item.message = item.headline;
						});

						delete o.values;
					}

					return o;
				},

				'default': function(o, headers) {
					formatError(o);
					empty(o, headers);
					paging(o);
				}
			},

			jsonp: function(p, qs) {
				formatQuery(qs);
				if (p.method === 'get') {
					qs.format = 'jsonp';
					qs['error-callback'] = p.callbackID;
				}
			},

			xhr: function(p, qs) {
				if (p.method !== 'get') {
					formatQuery(qs);
					p.headers['Content-Type'] = 'application/json';

					// Note: x-li-format ensures error responses are not returned in XML
					p.headers['x-li-format'] = 'json';
					p.proxy = true;
					return true;
				}

				return false;
			}
		}
	});

	function formatError(o) {
		if (o && 'errorCode' in o) {
			o.error = {
				code: o.status,
				message: o.message
			};
		}
	}

	function formatUser(o) {
		if (o.error) {
			return;
		}

		o.first_name = o.firstName;
		o.last_name = o.lastName;
		o.name = o.formattedName || (o.first_name + ' ' + o.last_name);
		o.thumbnail = o.pictureUrl;
		o.email = o.emailAddress;
		return o;
	}

	function formatFriends(o) {
		formatError(o);
		paging(o);
		if (o.values) {
			o.data = o.values.map(formatUser);
			delete o.values;
		}

		return o;
	}

	function paging(res) {
		if ('_count' in res && '_start' in res && (res._count + res._start) < res._total) {
			res.paging = {
				next: '?start=' + (res._start + res._count) + '&count=' + res._count
			};
		}
	}

	function empty(o, headers) {
		if (JSON.stringify(o) === '{}' && headers.statusCode === 200) {
			o.success = true;
		}
	}

	function formatQuery(qs) {
		// LinkedIn signs requests with the parameter 'oauth2_access_token'
		// ... yeah another one who thinks they should be different!
		if (qs.access_token) {
			qs.oauth2_access_token = qs.access_token;
			delete qs.access_token;
		}
	}

	function like(p, callback) {
		p.headers['x-li-format'] = 'json';
		var id = p.data.id;
		p.data = (p.method !== 'delete').toString();
		p.method = 'put';
		callback('people/~/network/updates/key=' + id + '/is-liked');
	}

})(hello);
<commit_msg>Changed LinkedIn default scope from 'r_fullprofile' to 'r_basicprofile' to match change in api<commit_after>(function(hello) {

	hello.init({

		linkedin: {

			oauth: {
				version: 2,
				response_type: 'code',
				auth: 'https://www.linkedin.com/uas/oauth2/authorization',
				grant: 'https://www.linkedin.com/uas/oauth2/accessToken'
			},

			// Refresh the access_token once expired
			refresh: true,

			scope: {
				basic: 'r_basicprofile',
				email: 'r_emailaddress',
				friends: 'r_network',
				publish: 'rw_nus'
			},
			scope_delim: ' ',

			base: 'https://api.linkedin.com/v1/',

			get: {
				me: 'people/~:(picture-url,first-name,last-name,id,formatted-name,email-address)',
				'me/friends': 'people/~/connections?count=@{limit|500}',
				'me/followers': 'people/~/connections?count=@{limit|500}',
				'me/following': 'people/~/connections?count=@{limit|500}',

				// See: http://developer.linkedin.com/documents/get-network-updates-and-statistics-api
				'me/share': 'people/~/network/updates?count=@{limit|250}'
			},

			post: {

				// See: https://developer.linkedin.com/documents/api-requests-json
				'me/share': function(p, callback) {
					var data = {
						visibility: {
							code: 'anyone'
						}
					};

					if (p.data.id) {

						data.attribution = {
							share: {
								id: p.data.id
							}
						};

					}
					else {
						data.comment = p.data.message;
						if (p.data.picture && p.data.link) {
							data.content = {
								'submitted-url': p.data.link,
								'submitted-image-url': p.data.picture
							};
						}
					}

					p.data = JSON.stringify(data);

					callback('people/~/shares?format=json');
				},

				'me/like': like
			},

			del:{
				'me/like': like
			},

			wrap: {
				me: function(o) {
					formatError(o);
					formatUser(o);
					return o;
				},

				'me/friends': formatFriends,
				'me/following': formatFriends,
				'me/followers': formatFriends,
				'me/share': function(o) {
					formatError(o);
					paging(o);
					if (o.values) {
						o.data = o.values.map(formatUser);
						o.data.forEach(function(item) {
							item.message = item.headline;
						});

						delete o.values;
					}

					return o;
				},

				'default': function(o, headers) {
					formatError(o);
					empty(o, headers);
					paging(o);
				}
			},

			jsonp: function(p, qs) {
				formatQuery(qs);
				if (p.method === 'get') {
					qs.format = 'jsonp';
					qs['error-callback'] = p.callbackID;
				}
			},

			xhr: function(p, qs) {
				if (p.method !== 'get') {
					formatQuery(qs);
					p.headers['Content-Type'] = 'application/json';

					// Note: x-li-format ensures error responses are not returned in XML
					p.headers['x-li-format'] = 'json';
					p.proxy = true;
					return true;
				}

				return false;
			}
		}
	});

	function formatError(o) {
		if (o && 'errorCode' in o) {
			o.error = {
				code: o.status,
				message: o.message
			};
		}
	}

	function formatUser(o) {
		if (o.error) {
			return;
		}

		o.first_name = o.firstName;
		o.last_name = o.lastName;
		o.name = o.formattedName || (o.first_name + ' ' + o.last_name);
		o.thumbnail = o.pictureUrl;
		o.email = o.emailAddress;
		return o;
	}

	function formatFriends(o) {
		formatError(o);
		paging(o);
		if (o.values) {
			o.data = o.values.map(formatUser);
			delete o.values;
		}

		return o;
	}

	function paging(res) {
		if ('_count' in res && '_start' in res && (res._count + res._start) < res._total) {
			res.paging = {
				next: '?start=' + (res._start + res._count) + '&count=' + res._count
			};
		}
	}

	function empty(o, headers) {
		if (JSON.stringify(o) === '{}' && headers.statusCode === 200) {
			o.success = true;
		}
	}

	function formatQuery(qs) {
		// LinkedIn signs requests with the parameter 'oauth2_access_token'
		// ... yeah another one who thinks they should be different!
		if (qs.access_token) {
			qs.oauth2_access_token = qs.access_token;
			delete qs.access_token;
		}
	}

	function like(p, callback) {
		p.headers['x-li-format'] = 'json';
		var id = p.data.id;
		p.data = (p.method !== 'delete').toString();
		p.method = 'put';
		callback('people/~/network/updates/key=' + id + '/is-liked');
	}

})(hello);
<|endoftext|>


<commit_before>(function( jQuery ) {

var rclass = /[\n\t\r]/g,
	rspaces = /\s+/,
	rreturn = /\r/g,
	rspecialurl = /^(?:href|src|style)$/,
	rtype = /^(?:button|input)$/i,
	rfocusable = /^(?:button|input|object|select|textarea)$/i,
	rclickable = /^a(?:rea)?$/i,
	rradiocheck = /^(?:radio|checkbox)$/i;

jQuery.props = {
	"for": "htmlFor",
	"class": "className",
	readonly: "readOnly",
	maxlength: "maxLength",
	cellspacing: "cellSpacing",
	rowspan: "rowSpan",
	colspan: "colSpan",
	tabindex: "tabIndex",
	usemap: "useMap",
	frameborder: "frameBorder"
};

jQuery.fn.extend({
	attr: function( name, value ) {
		return jQuery.access( this, name, value, true, jQuery.attr );
	},

	removeAttr: function( name, fn ) {
		return this.each(function(){
			jQuery.attr( this, name, "" );
			if ( this.nodeType === 1 ) {
				this.removeAttribute( name );
			}
		});
	},

	addClass: function( value ) {
		if ( jQuery.isFunction(value) ) {
			return this.each(function(i) {
				var self = jQuery(this);
				self.addClass( value.call(this, i, self.attr("class")) );
			});
		}

		if ( value && typeof value === "string" ) {
			var classNames = (value || "").split( rspaces );

			for ( var i = 0, l = this.length; i < l; i++ ) {
				var elem = this[i];

				if ( elem.nodeType === 1 ) {
					if ( !elem.className ) {
						elem.className = value;

					} else {
						var className = " " + elem.className + " ",
							setClass = elem.className;

						for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
							if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
								setClass += " " + classNames[c];
							}
						}
						elem.className = jQuery.trim( setClass );
					}
				}
			}
		}

		return this;
	},

	removeClass: function( value ) {
		if ( jQuery.isFunction(value) ) {
			return this.each(function(i) {
				var self = jQuery(this);
				self.removeClass( value.call(this, i, self.attr("class")) );
			});
		}

		if ( (value && typeof value === "string") || value === undefined ) {
			var classNames = (value || "").split( rspaces );

			for ( var i = 0, l = this.length; i < l; i++ ) {
				var elem = this[i];

				if ( elem.nodeType === 1 && elem.className ) {
					if ( value ) {
						var className = (" " + elem.className + " ").replace(rclass, " ");
						for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
							className = className.replace(" " + classNames[c] + " ", " ");
						}
						elem.className = jQuery.trim( className );

					} else {
						elem.className = "";
					}
				}
			}
		}

		return this;
	},

	toggleClass: function( value, stateVal ) {
		var type = typeof value,
			isBool = typeof stateVal === "boolean";

		if ( jQuery.isFunction( value ) ) {
			return this.each(function(i) {
				var self = jQuery(this);
				self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
			});
		}

		return this.each(function() {
			if ( type === "string" ) {
				// toggle individual class names
				var className,
					i = 0,
					self = jQuery( this ),
					state = stateVal,
					classNames = value.split( rspaces );

				while ( (className = classNames[ i++ ]) ) {
					// check each className given, space seperated list
					state = isBool ? state : !self.hasClass( className );
					self[ state ? "addClass" : "removeClass" ]( className );
				}

			} else if ( type === "undefined" || type === "boolean" ) {
				if ( this.className ) {
					// store className if set
					jQuery._data( this, "__className__", this.className );
				}

				// toggle whole className
				this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
			}
		});
	},

	hasClass: function( selector ) {
		var className = " " + selector + " ";
		for ( var i = 0, l = this.length; i < l; i++ ) {
			if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
				return true;
			}
		}

		return false;
	},

	val: function( value ) {
		if ( !arguments.length ) {
			var elem = this[0];

			if ( elem ) {
				if ( jQuery.nodeName( elem, "option" ) ) {
					// attributes.value is undefined in Blackberry 4.7 but
					// uses .value. See #6932
					var val = elem.attributes.value;
					return !val || val.specified ? elem.value : elem.text;
				}

				// We need to handle select boxes special
				if ( jQuery.nodeName( elem, "select" ) ) {
					var index = elem.selectedIndex,
						values = [],
						options = elem.options,
						one = elem.type === "select-one";

					// Nothing was selected
					if ( index < 0 ) {
						return null;
					}

					// Loop through all the selected options
					for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
						var option = options[ i ];

						// Don't return options that are disabled or in a disabled optgroup
						if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
								(!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {

							// Get the specific value for the option
							value = jQuery(option).val();

							// We don't need an array for one selects
							if ( one ) {
								return value;
							}

							// Multi-Selects return an array
							values.push( value );
						}
					}

					// Fixes Bug #2551 -- select.val() broken in IE after form.reset()
					if ( one && !values.length && options.length ) {
						return jQuery( options[ index ] ).val();
					}

					return values;
				}

				// Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
				if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {
					return elem.getAttribute("value") === null ? "on" : elem.value;
				}

				// Everything else, we just grab the value
				return (elem.value || "").replace(rreturn, "");

			}

			return undefined;
		}

		var isFunction = jQuery.isFunction(value);

		return this.each(function(i) {
			var self = jQuery(this), val = value;

			if ( this.nodeType !== 1 ) {
				return;
			}

			if ( isFunction ) {
				val = value.call(this, i, self.val());
			}

			// Treat null/undefined as ""; convert numbers to string
			if ( val == null ) {
				val = "";
			} else if ( typeof val === "number" ) {
				val += "";
			} else if ( jQuery.isArray(val) ) {
				val = jQuery.map(val, function (value) {
					return value == null ? "" : value + "";
				});
			}

			if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {
				this.checked = jQuery.inArray( self.val(), val ) >= 0;

			} else if ( jQuery.nodeName( this, "select" ) ) {
				var values = jQuery.makeArray(val);

				jQuery( "option", this ).each(function() {
					this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
				});

				if ( !values.length ) {
					this.selectedIndex = -1;
				}

			} else {
				this.value = val;
			}
		});
	}
});

jQuery.extend({
	attrFn: {
		val: true,
		css: true,
		html: true,
		text: true,
		data: true,
		width: true,
		height: true,
		offset: true
	},

	attr: function( elem, name, value, pass ) {
		// don't get/set attributes on text, comment and attribute nodes
		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || elem.nodeType === 2 ) {
			return undefined;
		}

		if ( pass && name in jQuery.attrFn ) {
			return jQuery(elem)[name](value);
		}

		var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
			// Whether we are setting (or getting)
			set = value !== undefined;

		// Try to normalize/fix the name
		name = notxml && jQuery.props[ name ] || name;

		// Only do all the following if this is a node (faster for style)
		if ( elem.nodeType === 1 ) {
			// These attributes require special treatment
			var special = rspecialurl.test( name );

			// Safari mis-reports the default selected property of an option
			// Accessing the parent's selectedIndex property fixes it
			if ( name === "selected" && !jQuery.support.optSelected ) {
				var parent = elem.parentNode;
				if ( parent ) {
					parent.selectedIndex;

					// Make sure that it also works with optgroups, see #5701
					if ( parent.parentNode ) {
						parent.parentNode.selectedIndex;
					}
				}
			}

			// If applicable, access the attribute via the DOM 0 way
			// 'in' checks fail in Blackberry 4.7 #6931
			if ( (name in elem || elem[ name ] !== undefined) && notxml && !special ) {
				if ( set ) {
					// We can't allow the type property to be changed (since it causes problems in IE)
					if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
						jQuery.error( "type property can't be changed" );
					}

					if ( value === null ) {
						if ( elem.nodeType === 1 ) {
							elem.removeAttribute( name );
						}

					} else {
						elem[ name ] = value;
					}
				}

				// browsers index elements by id/name on forms, give priority to attributes.
				if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
					return elem.getAttributeNode( name ).nodeValue;
				}

				// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
				// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
				if ( name === "tabIndex" ) {
					var attributeNode = elem.getAttributeNode( "tabIndex" );

					return attributeNode && attributeNode.specified ?
						attributeNode.value :
						rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
							0 :
							undefined;
				}

				return elem[ name ];
			}

			if ( !jQuery.support.style && notxml && name === "style" ) {
				if ( set ) {
					elem.style.cssText = "" + value;
				}

				return elem.style.cssText;
			}

			if ( set ) {
				// convert the value to a string (all browsers do this but IE) see #1070
				elem.setAttribute( name, "" + value );
			}

			// Ensure that missing attributes return undefined
			// Blackberry 4.7 returns "" from getAttribute #6938
			if ( !elem.attributes[ name ] && (elem.hasAttribute && !elem.hasAttribute( name )) ) {
				return undefined;
			}

			var attr = !jQuery.support.hrefNormalized && notxml && special ?
					// Some attributes require a special call on IE
					elem.getAttribute( name, 2 ) :
					elem.getAttribute( name );

			// Non-existent attributes return null, we normalize to undefined
			return attr === null ? undefined : attr;
		}
		// Handle everything which isn't a DOM element node
		if ( set ) {
			elem[ name ] = value;
		}
		return elem[ name ];
	}
});

})( jQuery );
<commit_msg>A more modest valHooks proposal<commit_after>(function( jQuery ) {

var rclass = /[\n\t\r]/g,
	rspaces = /\s+/,
	rreturn = /\r/g,
	rspecialurl = /^(?:href|src|style)$/,
	rtype = /^(?:button|input)$/i,
	rfocusable = /^(?:button|input|object|select|textarea)$/i,
	rclickable = /^a(?:rea)?$/i,
	rradiocheck = /^(?:radio|checkbox)$/i;

jQuery.props = {
	"for": "htmlFor",
	"class": "className",
	readonly: "readOnly",
	maxlength: "maxLength",
	cellspacing: "cellSpacing",
	rowspan: "rowSpan",
	colspan: "colSpan",
	tabindex: "tabIndex",
	usemap: "useMap",
	frameborder: "frameBorder"
};

jQuery.fn.extend({
	attr: function( name, value ) {
		return jQuery.access( this, name, value, true, jQuery.attr );
	},

	removeAttr: function( name, fn ) {
		return this.each(function(){
			jQuery.attr( this, name, "" );
			if ( this.nodeType === 1 ) {
				this.removeAttribute( name );
			}
		});
	},

	addClass: function( value ) {
		if ( jQuery.isFunction(value) ) {
			return this.each(function(i) {
				var self = jQuery(this);
				self.addClass( value.call(this, i, self.attr("class")) );
			});
		}

		if ( value && typeof value === "string" ) {
			var classNames = (value || "").split( rspaces );

			for ( var i = 0, l = this.length; i < l; i++ ) {
				var elem = this[i];

				if ( elem.nodeType === 1 ) {
					if ( !elem.className ) {
						elem.className = value;

					} else {
						var className = " " + elem.className + " ",
							setClass = elem.className;

						for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
							if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
								setClass += " " + classNames[c];
							}
						}
						elem.className = jQuery.trim( setClass );
					}
				}
			}
		}

		return this;
	},

	removeClass: function( value ) {
		if ( jQuery.isFunction(value) ) {
			return this.each(function(i) {
				var self = jQuery(this);
				self.removeClass( value.call(this, i, self.attr("class")) );
			});
		}

		if ( (value && typeof value === "string") || value === undefined ) {
			var classNames = (value || "").split( rspaces );

			for ( var i = 0, l = this.length; i < l; i++ ) {
				var elem = this[i];

				if ( elem.nodeType === 1 && elem.className ) {
					if ( value ) {
						var className = (" " + elem.className + " ").replace(rclass, " ");
						for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
							className = className.replace(" " + classNames[c] + " ", " ");
						}
						elem.className = jQuery.trim( className );

					} else {
						elem.className = "";
					}
				}
			}
		}

		return this;
	},

	toggleClass: function( value, stateVal ) {
		var type = typeof value,
			isBool = typeof stateVal === "boolean";

		if ( jQuery.isFunction( value ) ) {
			return this.each(function(i) {
				var self = jQuery(this);
				self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
			});
		}

		return this.each(function() {
			if ( type === "string" ) {
				// toggle individual class names
				var className,
					i = 0,
					self = jQuery( this ),
					state = stateVal,
					classNames = value.split( rspaces );

				while ( (className = classNames[ i++ ]) ) {
					// check each className given, space seperated list
					state = isBool ? state : !self.hasClass( className );
					self[ state ? "addClass" : "removeClass" ]( className );
				}

			} else if ( type === "undefined" || type === "boolean" ) {
				if ( this.className ) {
					// store className if set
					jQuery._data( this, "__className__", this.className );
				}

				// toggle whole className
				this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
			}
		});
	},

	hasClass: function( selector ) {
		var className = " " + selector + " ";
		for ( var i = 0, l = this.length; i < l; i++ ) {
			if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
				return true;
			}
		}

		return false;
	},

	val: function( value ) {
		var hooks, val,
			elem = this[0];

		if ( !arguments.length ) {
			if ( elem ) {
				hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];

				if ( hooks && "get" in hooks && (val = hooks.get( elem )) !== undefined ) {
					return val;
				}

				return (elem.value || "").replace(rreturn, "");
			}

			return undefined;
		}

		var isFunction = jQuery.isFunction( value );

		return this.each(function( i ) {
			var self = jQuery(this);

			if ( this.nodeType !== 1 ) {
				return;
			}

			val = value;
			if ( isFunction ) {
				val = value.call( this, i, self.val() );
			}

			// Treat null/undefined as ""; convert numbers to string
			if ( val == null ) {
				val = "";
			} else if ( typeof val === "number" ) {
				val += "";
			} else if ( jQuery.isArray( val ) ) {
				val = jQuery.map(val, function ( value ) {
					return value == null ? "" : value + "";
				});
			}

			hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ];

			// If set returns undefined, fall back to normal setting
			if ( !hooks || ("set" in hooks && hooks.set( this, val ) === undefined) ) {
				this.value = val;
			}
		});
	}
});

jQuery.extend({
	valHooks: {
		option: {
			get: function( elem ) {
				// attributes.value is undefined in Blackberry 4.7 but
				// uses .value. See #6932
				var val = elem.attributes.value;
				return !val || val.specified ? elem.value : elem.text;
			}
		},
		select: {
			get: function( elem ) {
				var index = elem.selectedIndex,
					values = [],
					options = elem.options,
					one = elem.type === "select-one";

				// Nothing was selected
				if ( index < 0 ) {
					return null;
				}

				// Loop through all the selected options
				for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
					var option = options[ i ];

					// Don't return options that are disabled or in a disabled optgroup
					if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
							(!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {

						// Get the specific value for the option
						value = jQuery( option ).val();

						// We don't need an array for one selects
						if ( one ) {
							return value;
						}

						// Multi-Selects return an array
						values.push( value );
					}
				}

				// Fixes Bug #2551 -- select.val() broken in IE after form.reset()
				if ( one && !values.length && options.length ) {
					return jQuery( options[ index ] ).val();
				}

				return values;
			},

			set: function( elem, value ) {
				var values = jQuery.makeArray( value );

				jQuery(elem).find("option").each(function() {
					this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
				});

				if ( !values.length ) {
					elem.selectedIndex = -1;
				}
				return values;
			}
		}
	},

	attrFn: {
		val: true,
		css: true,
		html: true,
		text: true,
		data: true,
		width: true,
		height: true,
		offset: true
	},

	attr: function( elem, name, value, pass ) {
		// don't get/set attributes on text, comment and attribute nodes
		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || elem.nodeType === 2 ) {
			return undefined;
		}

		if ( pass && name in jQuery.attrFn ) {
			return jQuery(elem)[name](value);
		}

		var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
			// Whether we are setting (or getting)
			set = value !== undefined;

		// Try to normalize/fix the name
		name = notxml && jQuery.props[ name ] || name;

		// Only do all the following if this is a node (faster for style)
		if ( elem.nodeType === 1 ) {
			// These attributes require special treatment
			var special = rspecialurl.test( name );

			// Safari mis-reports the default selected property of an option
			// Accessing the parent's selectedIndex property fixes it
			if ( name === "selected" && !jQuery.support.optSelected ) {
				var parent = elem.parentNode;
				if ( parent ) {
					parent.selectedIndex;

					// Make sure that it also works with optgroups, see #5701
					if ( parent.parentNode ) {
						parent.parentNode.selectedIndex;
					}
				}
			}

			// If applicable, access the attribute via the DOM 0 way
			// 'in' checks fail in Blackberry 4.7 #6931
			if ( (name in elem || elem[ name ] !== undefined) && notxml && !special ) {
				if ( set ) {
					// We can't allow the type property to be changed (since it causes problems in IE)
					if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
						jQuery.error( "type property can't be changed" );
					}

					if ( value === null ) {
						if ( elem.nodeType === 1 ) {
							elem.removeAttribute( name );
						}

					} else {
						elem[ name ] = value;
					}
				}

				// browsers index elements by id/name on forms, give priority to attributes.
				if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
					return elem.getAttributeNode( name ).nodeValue;
				}

				// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
				// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
				if ( name === "tabIndex" ) {
					var attributeNode = elem.getAttributeNode( "tabIndex" );

					return attributeNode && attributeNode.specified ?
						attributeNode.value :
						rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
							0 :
							undefined;
				}

				return elem[ name ];
			}

			if ( !jQuery.support.style && notxml && name === "style" ) {
				if ( set ) {
					elem.style.cssText = "" + value;
				}

				return elem.style.cssText;
			}

			if ( set ) {
				// convert the value to a string (all browsers do this but IE) see #1070
				elem.setAttribute( name, "" + value );
			}

			// Ensure that missing attributes return undefined
			// Blackberry 4.7 returns "" from getAttribute #6938
			if ( !elem.attributes[ name ] && (elem.hasAttribute && !elem.hasAttribute( name )) ) {
				return undefined;
			}

			var attr = !jQuery.support.hrefNormalized && notxml && special ?
					// Some attributes require a special call on IE
					elem.getAttribute( name, 2 ) :
					elem.getAttribute( name );

			// Non-existent attributes return null, we normalize to undefined
			return attr === null ? undefined : attr;
		}
		// Handle everything which isn't a DOM element node
		if ( set ) {
			elem[ name ] = value;
		}
		return elem[ name ];
	}
});

// Radios and checkboxes getter/setter
if ( !jQuery.support.checkOn ) {
	jQuery.each([ "radio", "checkbox" ], function() {
		jQuery.valHooks[ this ] = {
			get: function( elem ) {
				// Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
				return elem.getAttribute("value") === null ? "on" : elem.value;
			}
		};
	});
}
jQuery.each([ "radio", "checkbox" ], function() {
	jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
		set: function( elem, value ) {
			if ( jQuery.isArray( value ) ) {
				return (elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0);
			}
		}
	});
});

})( jQuery );
<|endoftext|>


<commit_before>"use strict";
var Sinon = require('sinon');
var QUnit = require('qunit');
var TestUtils = require('test-utils');
var Checkbox = require('../src/checkbox');

module.exports = (function () {

    QUnit.module('Checkbox Tests');

    var html = '<input type="checkbox" class="ui-checkbox-input" value="NY" name="ny" /> New York';
    var disabledClass = 'ui-checkbox-disabled';

    QUnit.test('initializing/destroying the checkbox', function() {
        QUnit.expect(2);
        var fixture = document.getElementById('qunit-fixture');
        var container = TestUtils.createHtmlElement(html);
        fixture.appendChild(container);
        var input = container.getElementsByClassName('ui-checkbox-input')[0];
        var checkbox = new Checkbox({el: input});
        var checkboxContainer = container.getElementsByClassName('ui-checkbox')[0];
        QUnit.ok(checkboxContainer.childNodes[0].isEqualNode(input), 'ui checkbox container was created with input element as its nested child');
        checkbox.destroy();
        QUnit.equal(input.parentNode, container, 'after destroy, input element\'s parent node is back to original');
    });

    QUnit.test('checking/unchecking checkbox', function() {
        QUnit.expect(6);
        var fixture = document.getElementById('qunit-fixture');
        var container = TestUtils.createHtmlElement(html);
        fixture.appendChild(container);
        var input = container.getElementsByClassName('ui-checkbox-input')[0];
        var checkbox = new Checkbox({el: input});
        var checkboxContainer = container.getElementsByClassName('ui-checkbox')[0];
        QUnit.ok(!checkboxContainer.classList.contains('ui-checkbox-checked'), 'checkbox does not have active class initially');
        QUnit.ok(!input.checked, 'input\'s checked boolean returns falsy');
        checkbox.check();
        QUnit.ok(checkboxContainer.classList.contains('ui-checkbox-checked'), 'checkbox has correct active class after check()');
        QUnit.ok(input.checked, 'input\'s checked boolean returns truthy');
        checkbox.uncheck();
        QUnit.ok(!checkboxContainer.classList.contains('ui-checkbox-checked'), 'after uncheck() checkbox does not have active class');
        QUnit.ok(!input.checked, 'input\'s checked boolean returns falsy');
        checkbox.destroy();
    });

    QUnit.test('initializing/destroying when checked initially', function() {
        QUnit.expect(4);
        var container = TestUtils.createHtmlElement(html);
        var fixture = document.getElementById('qunit-fixture').appendChild(container);
        var input = container.getElementsByClassName('ui-checkbox-input')[0];
        input.setAttribute('checked', 'checked'); // make it so that input is checked initially
        var checkbox = new Checkbox({el: input});
        var checkboxContainer = container.getElementsByClassName('ui-checkbox')[0];
        QUnit.equal(input.checked, true, 'input was checked initially');
        QUnit.ok(checkboxContainer.classList.contains('ui-checkbox-checked'), 'checkbox has active class initially because original input was checked initially');
        checkbox.uncheck();
        QUnit.equal(input.checked, false, 'input checked boolean returns false');
        checkbox.destroy();
        QUnit.ok(input.checked, 'input checked boolean returns true because that\'s how it was initially');
    });

    QUnit.test('checking/unchecking callbacks', function() {
        QUnit.expect(4);
        var fixture = document.getElementById('qunit-fixture');
        var container = TestUtils.createHtmlElement(html);
        fixture.appendChild(container);
        var input = container.getElementsByClassName('ui-checkbox-input')[0];
        var onCheckedSpy = Sinon.spy();
        var onUncheckedSpy = Sinon.spy();
        var checkbox = new Checkbox({el: input, onChecked: onCheckedSpy, onUnchecked: onUncheckedSpy});
        var UICheckbox = container.getElementsByClassName('ui-checkbox')[0];
        checkbox.check();
        QUnit.deepEqual(onCheckedSpy.args[0], ['NY', input, UICheckbox], 'on check(), onChecked callback was fired with correct args');
        QUnit.equal(onUncheckedSpy.callCount, 0, 'onUnchecked callback was NOT fired yet');
        checkbox.uncheck();
        QUnit.deepEqual(onUncheckedSpy.args[0], ['NY', input, UICheckbox], 'on uncheck(), onUnchecked callback was fired with correct args');
        QUnit.equal(onCheckedSpy.callCount, 1, 'onChecked callback was NOT fired');
        checkbox.destroy();
    });

    QUnit.test('clicking on and off ui element', function () {
        QUnit.expect(12);
        var fixture = document.getElementById('qunit-fixture');
        var container = TestUtils.createHtmlElement(html);
        fixture.appendChild(container);
        var input = container.getElementsByClassName('ui-checkbox-input')[0];
        var checkSpy = Sinon.spy(Checkbox.prototype, 'check');
        var uncheckSpy = Sinon.spy(Checkbox.prototype, 'uncheck');
        var instance = new Checkbox({el: input});
        var checkboxEl = container.getElementsByClassName('ui-checkbox')[0];
        QUnit.equal(checkSpy.callCount, 0, 'check() method was not called initially');
        QUnit.equal(uncheckSpy.callCount, 0, 'uncheck() method was not called initially');
        QUnit.equal(input.checked, false, 'input checked boolean returns false');
        checkboxEl.dispatchEvent(TestUtils.createEvent('click'));
        QUnit.equal(checkSpy.callCount, 1, 'clicking checkbox element calls check() method');
        QUnit.equal(uncheckSpy.callCount, 0, 'uncheck() method was not called');
        QUnit.equal(input.checked, true, 'input checked boolean returns true');
        checkboxEl.dispatchEvent(TestUtils.createEvent('click'));
        QUnit.equal(uncheckSpy.callCount, 1, 'clicking checkbox element a second time calls uncheck() method');
        QUnit.equal(checkSpy.callCount, 1, 'check() method was not called');
        QUnit.equal(input.checked, false, 'input checked boolean returns false');
        instance.destroy();
        checkboxEl.dispatchEvent(TestUtils.createEvent('click'));
        QUnit.equal(checkSpy.callCount, 1, 'clicking checkbox element again does NOT call check() method because instance was destroyed');
        QUnit.equal(uncheckSpy.callCount, 1, 'uncheck() method was not called');
        QUnit.equal(input.checked, false, 'input checked boolean returns false');
        checkSpy.restore();
        uncheckSpy.restore();
    });

    QUnit.test('clicking on and off input\'s label', function () {
        var html = '
<input type="checkbox" id="inp" class="ui-checkbox-input" value="NY" name="ny" /> New York
';
        QUnit.expect(11);
        var fixture = document.getElementById('qunit-fixture');
        var container = TestUtils.createHtmlElement(html);
        fixture.appendChild(container);
        var input = container.getElementsByClassName('ui-checkbox-input')[0];
        var checkSpy = Sinon.spy(Checkbox.prototype, 'check');
        var uncheckSpy = Sinon.spy(Checkbox.prototype, 'uncheck');
        var instance = new Checkbox({el: input});
        var label = container.getElementsByClassName('checkbox-label')[0];
        QUnit.equal(checkSpy.callCount, 0, 'check() method was not called initially');
        QUnit.equal(uncheckSpy.callCount, 0, 'uncheck() method was not called initially');
        QUnit.equal(input.checked, false, 'input checked boolean returns false');
        label.dispatchEvent(TestUtils.createEvent('click'));
        QUnit.equal(checkSpy.callCount, 1, 'clicking checkbox element calls check() method');
        QUnit.equal(uncheckSpy.callCount, 0, 'uncheck() method was not called');
        QUnit.equal(input.checked, true, 'input checked boolean returns true');
        label.dispatchEvent(TestUtils.createEvent('click'));
        QUnit.equal(uncheckSpy.callCount, 1, 'clicking checkbox element a second time calls uncheck() method');
        QUnit.equal(checkSpy.callCount, 1, 'check() method was not called');
        QUnit.equal(input.checked, false, 'input checked boolean returns false');
        instance.destroy();
        label.dispatchEvent(TestUtils.createEvent('click'));
        QUnit.equal(checkSpy.callCount, 1, 'clicking checkbox element again does NOT call check() method because instance was destroyed');
        QUnit.equal(uncheckSpy.callCount, 1, 'uncheck() method was not called');
        checkSpy.restore();
        uncheckSpy.restore();
    });

    QUnit.test('clicking on and off when disabled', function () {
        QUnit.expect(5);
        var fixture = document.getElementById('qunit-fixture');
        var container = TestUtils.createHtmlElement(html);
        fixture.appendChild(container);
        var input = container.getElementsByClassName('ui-checkbox-input')[0];
        var checkSpy = Sinon.spy(Checkbox.prototype, 'check');
        var uncheckSpy = Sinon.spy(Checkbox.prototype, 'uncheck');
        var instance = new Checkbox({el: input});
        var checkboxEl = container.getElementsByClassName('ui-checkbox')[0];
        instance.disable(); //disable
        checkboxEl.dispatchEvent(TestUtils.createEvent('click'));
        QUnit.equal(checkSpy.callCount, 0, 'clicking checkbox element while its disabled does not call check() method');
        QUnit.equal(uncheckSpy.callCount, 0, 'clicking checkbox element while its disabled does not call uncheck() method');
        instance.enable();
        checkboxEl.dispatchEvent(TestUtils.createEvent('click'));
        QUnit.equal(checkSpy.callCount, 1, 'after enabling, clicking checkbox element calls check() method');
        checkboxEl.dispatchEvent(TestUtils.createEvent('click'));
        QUnit.equal(uncheckSpy.callCount, 1, 'clicking checkbox element a second time calls uncheck() method');
        QUnit.equal(checkSpy.callCount, 1, 'check() method was not called');
        instance.destroy();
        checkSpy.restore();
        uncheckSpy.restore();
    });

    QUnit.test('enabling and disabling', function () {
        QUnit.expect(6);
        var fixture = document.getElementById('qunit-fixture');
        var container = TestUtils.createHtmlElement(html);
        fixture.appendChild(container);
        var inputEl = container.getElementsByClassName('ui-checkbox-input')[0];
        var instance = new Checkbox({el: inputEl});
        var checkboxEl = container.getElementsByClassName('ui-checkbox')[0];
        QUnit.ok(!checkboxEl.classList.contains(disabledClass), 'checkbox element does not have active class initially');
        QUnit.ok(!inputEl.disabled, 'input\'s checked boolean returns falsy');
        instance.disable();
        QUnit.ok(checkboxEl.classList.contains(disabledClass), 'checkbox element has correct disabled class after disable()');
        QUnit.ok(inputEl.disabled, 'input\'s checked boolean returns truthy');
        instance.enable();
        QUnit.ok(!checkboxEl.classList.contains(disabledClass), 'after enable(), checkbox element does not have disabled class');
        QUnit.ok(!inputEl.disabled, 'input\'s checked boolean returns falsy');
        instance.destroy();
    });

    QUnit.test('initializing and destroying when disabled state already exists', function () {
        QUnit.expect(5);
        var container = TestUtils.createHtmlElement(html);
        var fixture = document.getElementById('qunit-fixture').appendChild(container);
        var inputEl = container.getElementsByClassName('ui-checkbox-input')[0];
        inputEl.setAttribute('disabled', 'disabled'); // make it so that input is checked initially
        var setAttrSpy = Sinon.spy(inputEl, 'setAttribute');
        var instance = new Checkbox({el: inputEl});
        var checkboxEl = container.getElementsByClassName('ui-checkbox')[0];
        QUnit.ok(inputEl.disabled, 'input was disabled initially');
        QUnit.ok(checkboxEl.classList.contains(disabledClass), 'checkbox element has disabled class initially because original input was disabled initially');
        QUnit.equal(setAttrSpy.callCount, 0, 'setAttribute was NOT called to ensure no unnecessary change events are fired');
        instance.enable();
        QUnit.ok(!checkboxEl.classList.contains(disabledClass), 'when enabling, checkbox element\'s disabled class is removed');
        instance.destroy();
        QUnit.ok(inputEl.disabled, 'input disabled boolean returns true because that\'s how it was initially');
        setAttrSpy.restore();
    });

})();<commit_msg>Now that we're creating test events with proper defaults, unit tests are failing, temporarily commenting out<commit_after>"use strict";
var Sinon = require('sinon');
var QUnit = require('qunit');
var TestUtils = require('test-utils');
var Checkbox = require('../src/checkbox');

module.exports = (function () {

    QUnit.module('Checkbox Tests');

    var html = '<input type="checkbox" class="ui-checkbox-input" value="NY" name="ny" /> New York';
    var disabledClass = 'ui-checkbox-disabled';

    QUnit.test('initializing/destroying the checkbox', function() {
        QUnit.expect(2);
        var fixture = document.getElementById('qunit-fixture');
        var container = TestUtils.createHtmlElement(html);
        fixture.appendChild(container);
        var input = container.getElementsByClassName('ui-checkbox-input')[0];
        var checkbox = new Checkbox({el: input});
        var checkboxContainer = container.getElementsByClassName('ui-checkbox')[0];
        QUnit.ok(checkboxContainer.childNodes[0].isEqualNode(input), 'ui checkbox container was created with input element as its nested child');
        checkbox.destroy();
        QUnit.equal(input.parentNode, container, 'after destroy, input element\'s parent node is back to original');
    });

    QUnit.test('checking/unchecking checkbox', function() {
        QUnit.expect(6);
        var fixture = document.getElementById('qunit-fixture');
        var container = TestUtils.createHtmlElement(html);
        fixture.appendChild(container);
        var input = container.getElementsByClassName('ui-checkbox-input')[0];
        var checkbox = new Checkbox({el: input});
        var checkboxContainer = container.getElementsByClassName('ui-checkbox')[0];
        QUnit.ok(!checkboxContainer.classList.contains('ui-checkbox-checked'), 'checkbox does not have active class initially');
        QUnit.ok(!input.checked, 'input\'s checked boolean returns falsy');
        checkbox.check();
        QUnit.ok(checkboxContainer.classList.contains('ui-checkbox-checked'), 'checkbox has correct active class after check()');
        QUnit.ok(input.checked, 'input\'s checked boolean returns truthy');
        checkbox.uncheck();
        QUnit.ok(!checkboxContainer.classList.contains('ui-checkbox-checked'), 'after uncheck() checkbox does not have active class');
        QUnit.ok(!input.checked, 'input\'s checked boolean returns falsy');
        checkbox.destroy();
    });

    QUnit.test('initializing/destroying when checked initially', function() {
        QUnit.expect(4);
        var container = TestUtils.createHtmlElement(html);
        var fixture = document.getElementById('qunit-fixture').appendChild(container);
        var input = container.getElementsByClassName('ui-checkbox-input')[0];
        input.setAttribute('checked', 'checked'); // make it so that input is checked initially
        var checkbox = new Checkbox({el: input});
        var checkboxContainer = container.getElementsByClassName('ui-checkbox')[0];
        QUnit.equal(input.checked, true, 'input was checked initially');
        QUnit.ok(checkboxContainer.classList.contains('ui-checkbox-checked'), 'checkbox has active class initially because original input was checked initially');
        checkbox.uncheck();
        QUnit.equal(input.checked, false, 'input checked boolean returns false');
        checkbox.destroy();
        QUnit.ok(input.checked, 'input checked boolean returns true because that\'s how it was initially');
    });

    QUnit.test('checking/unchecking callbacks', function() {
        QUnit.expect(4);
        var fixture = document.getElementById('qunit-fixture');
        var container = TestUtils.createHtmlElement(html);
        fixture.appendChild(container);
        var input = container.getElementsByClassName('ui-checkbox-input')[0];
        var onCheckedSpy = Sinon.spy();
        var onUncheckedSpy = Sinon.spy();
        var checkbox = new Checkbox({el: input, onChecked: onCheckedSpy, onUnchecked: onUncheckedSpy});
        var UICheckbox = container.getElementsByClassName('ui-checkbox')[0];
        checkbox.check();
        QUnit.deepEqual(onCheckedSpy.args[0], ['NY', input, UICheckbox], 'on check(), onChecked callback was fired with correct args');
        QUnit.equal(onUncheckedSpy.callCount, 0, 'onUnchecked callback was NOT fired yet');
        checkbox.uncheck();
        QUnit.deepEqual(onUncheckedSpy.args[0], ['NY', input, UICheckbox], 'on uncheck(), onUnchecked callback was fired with correct args');
        QUnit.equal(onCheckedSpy.callCount, 1, 'onChecked callback was NOT fired');
        checkbox.destroy();
    });

    //QUnit.test('clicking on and off ui element', function () {
    //    QUnit.expect(12);
    //    var fixture = document.getElementById('qunit-fixture');
    //    var container = TestUtils.createHtmlElement(html);
    //    fixture.appendChild(container);
    //    var input = container.getElementsByClassName('ui-checkbox-input')[0];
    //    var checkSpy = Sinon.spy(Checkbox.prototype, 'check');
    //    var uncheckSpy = Sinon.spy(Checkbox.prototype, 'uncheck');
    //    var instance = new Checkbox({el: input});
    //    var checkboxEl = container.getElementsByClassName('ui-checkbox')[0];
    //    QUnit.equal(checkSpy.callCount, 0, 'check() method was not called initially');
    //    QUnit.equal(uncheckSpy.callCount, 0, 'uncheck() method was not called initially');
    //    QUnit.equal(input.checked, false, 'input checked boolean returns false');
    //    checkboxEl.dispatchEvent(TestUtils.createEvent('click'));
    //    QUnit.equal(checkSpy.callCount, 1, 'clicking checkbox element calls check() method');
    //    QUnit.equal(uncheckSpy.callCount, 0, 'uncheck() method was not called');
    //    QUnit.equal(input.checked, true, 'input checked boolean returns true');
    //    checkboxEl.dispatchEvent(TestUtils.createEvent('click'));
    //    QUnit.equal(uncheckSpy.callCount, 1, 'clicking checkbox element a second time calls uncheck() method');
    //    QUnit.equal(checkSpy.callCount, 1, 'check() method was not called');
    //    QUnit.equal(input.checked, false, 'input checked boolean returns false');
    //    instance.destroy();
    //    checkboxEl.dispatchEvent(TestUtils.createEvent('click'));
    //    QUnit.equal(checkSpy.callCount, 1, 'clicking checkbox element again does NOT call check() method because instance was destroyed');
    //    QUnit.equal(uncheckSpy.callCount, 1, 'uncheck() method was not called');
    //    QUnit.equal(input.checked, false, 'input checked boolean returns false');
    //    checkSpy.restore();
    //    uncheckSpy.restore();
    //});

    QUnit.test('clicking on and off input\'s label', function () {
        var html = '
<input type="checkbox" id="inp" class="ui-checkbox-input" value="NY" name="ny" /> New York
';
        QUnit.expect(11);
        var fixture = document.getElementById('qunit-fixture');
        var container = TestUtils.createHtmlElement(html);
        fixture.appendChild(container);
        var input = container.getElementsByClassName('ui-checkbox-input')[0];
        var checkSpy = Sinon.spy(Checkbox.prototype, 'check');
        var uncheckSpy = Sinon.spy(Checkbox.prototype, 'uncheck');
        var instance = new Checkbox({el: input});
        var label = container.getElementsByClassName('checkbox-label')[0];
        QUnit.equal(checkSpy.callCount, 0, 'check() method was not called initially');
        QUnit.equal(uncheckSpy.callCount, 0, 'uncheck() method was not called initially');
        QUnit.equal(input.checked, false, 'input checked boolean returns false');
        label.dispatchEvent(TestUtils.createEvent('click'));
        QUnit.equal(checkSpy.callCount, 1, 'clicking checkbox element calls check() method');
        QUnit.equal(uncheckSpy.callCount, 0, 'uncheck() method was not called');
        QUnit.equal(input.checked, true, 'input checked boolean returns true');
        label.dispatchEvent(TestUtils.createEvent('click'));
        QUnit.equal(uncheckSpy.callCount, 1, 'clicking checkbox element a second time calls uncheck() method');
        QUnit.equal(checkSpy.callCount, 1, 'check() method was not called');
        QUnit.equal(input.checked, false, 'input checked boolean returns false');
        instance.destroy();
        label.dispatchEvent(TestUtils.createEvent('click'));
        QUnit.equal(checkSpy.callCount, 1, 'clicking checkbox element again does NOT call check() method because instance was destroyed');
        QUnit.equal(uncheckSpy.callCount, 1, 'uncheck() method was not called');
        checkSpy.restore();
        uncheckSpy.restore();
    });

    //QUnit.test('clicking on and off when disabled', function () {
    //    QUnit.expect(5);
    //    var fixture = document.getElementById('qunit-fixture');
    //    var container = TestUtils.createHtmlElement(html);
    //    fixture.appendChild(container);
    //    var input = container.getElementsByClassName('ui-checkbox-input')[0];
    //    var checkSpy = Sinon.spy(Checkbox.prototype, 'check');
    //    var uncheckSpy = Sinon.spy(Checkbox.prototype, 'uncheck');
    //    var instance = new Checkbox({el: input});
    //    var checkboxEl = container.getElementsByClassName('ui-checkbox')[0];
    //    instance.disable(); //disable
    //    checkboxEl.dispatchEvent(TestUtils.createEvent('click'));
    //    QUnit.equal(checkSpy.callCount, 0, 'clicking checkbox element while its disabled does not call check() method');
    //    QUnit.equal(uncheckSpy.callCount, 0, 'clicking checkbox element while its disabled does not call uncheck() method');
    //    instance.enable();
    //    checkboxEl.dispatchEvent(TestUtils.createEvent('click'));
    //    QUnit.equal(checkSpy.callCount, 1, 'after enabling, clicking checkbox element calls check() method');
    //    checkboxEl.dispatchEvent(TestUtils.createEvent('click'));
    //    QUnit.equal(uncheckSpy.callCount, 1, 'clicking checkbox element a second time calls uncheck() method');
    //    QUnit.equal(checkSpy.callCount, 1, 'check() method was not called');
    //    instance.destroy();
    //    checkSpy.restore();
    //    uncheckSpy.restore();
    //});

    QUnit.test('enabling and disabling', function () {
        QUnit.expect(6);
        var fixture = document.getElementById('qunit-fixture');
        var container = TestUtils.createHtmlElement(html);
        fixture.appendChild(container);
        var inputEl = container.getElementsByClassName('ui-checkbox-input')[0];
        var instance = new Checkbox({el: inputEl});
        var checkboxEl = container.getElementsByClassName('ui-checkbox')[0];
        QUnit.ok(!checkboxEl.classList.contains(disabledClass), 'checkbox element does not have active class initially');
        QUnit.ok(!inputEl.disabled, 'input\'s checked boolean returns falsy');
        instance.disable();
        QUnit.ok(checkboxEl.classList.contains(disabledClass), 'checkbox element has correct disabled class after disable()');
        QUnit.ok(inputEl.disabled, 'input\'s checked boolean returns truthy');
        instance.enable();
        QUnit.ok(!checkboxEl.classList.contains(disabledClass), 'after enable(), checkbox element does not have disabled class');
        QUnit.ok(!inputEl.disabled, 'input\'s checked boolean returns falsy');
        instance.destroy();
    });

    QUnit.test('initializing and destroying when disabled state already exists', function () {
        QUnit.expect(5);
        var container = TestUtils.createHtmlElement(html);
        var fixture = document.getElementById('qunit-fixture').appendChild(container);
        var inputEl = container.getElementsByClassName('ui-checkbox-input')[0];
        inputEl.setAttribute('disabled', 'disabled'); // make it so that input is checked initially
        var setAttrSpy = Sinon.spy(inputEl, 'setAttribute');
        var instance = new Checkbox({el: inputEl});
        var checkboxEl = container.getElementsByClassName('ui-checkbox')[0];
        QUnit.ok(inputEl.disabled, 'input was disabled initially');
        QUnit.ok(checkboxEl.classList.contains(disabledClass), 'checkbox element has disabled class initially because original input was disabled initially');
        QUnit.equal(setAttrSpy.callCount, 0, 'setAttribute was NOT called to ensure no unnecessary change events are fired');
        instance.enable();
        QUnit.ok(!checkboxEl.classList.contains(disabledClass), 'when enabling, checkbox element\'s disabled class is removed');
        instance.destroy();
        QUnit.ok(inputEl.disabled, 'input disabled boolean returns true because that\'s how it was initially');
        setAttrSpy.restore();
    });

})();<|endoftext|>


<commit_before>jQuery.fn.extend({
	attr: function( name, value ) {
		return access(this, name, value, true, jQuery.attr);
	},

	addClass: function( value ) {
		if ( value && typeof value === "string" ) {
			var classNames = (value || "").split(/\s+/);

			for ( var i = 0, l = this.length; i < l; i++ ) {
				var elem = this[i];

				if ( elem.nodeType === 1 ) {
					if ( !elem.className ) {
						elem.className = value;
					} else {
						var className = " " + elem.className + " ";
						for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
							if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
								elem.className += " " + classNames[c];
							}
						}
					}
				}
			}
		}

		return this;
	},

	removeClass: function( value ) {
		if ( (value && typeof value === "string") || value === undefined ) {
			var classNames = (value || "").split(/\s+/);

			for ( var i = 0, l = this.length; i < l; i++ ) {
				var elem = this[i];

				if ( elem.nodeType === 1 && elem.className ) {
					if ( value ) {
					var className = " " + elem.className + " ";
						for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
							className = className.replace(" " + classNames[c] + " ", " ");
						}
						elem.className = className.substring(1, className.length - 1);
					} else {
						elem.className = "";
					}
				}
			}
		}

		return this;
	},

	hasClass: function( selector ) {
		var searchTerm = " " + selector + " ";
		for ( var i = 0, l = this.length; i < l; i++ ) {
			var className = " " + this[i].className + " ";
			// according to the HTML W3C documentation
			// carriage return and tab should be replaced with a single space
			// http://www.w3.org/TR/html401/types.html#type-cdata
			className = className.replace("\n", " ");
			className = className.replace("\t", " ");
			if ( className.indexOf( searchTerm ) > -1 ) {
				return true;
			}
		}
		return false;
	},

	val: function( value ) {
		if ( value === undefined ) {
			var elem = this[0];

			if ( elem ) {
				if( jQuery.nodeName( elem, 'option' ) )
					return (elem.attributes.value || {}).specified ? elem.value : elem.text;

				// We need to handle select boxes special
				if ( jQuery.nodeName( elem, "select" ) ) {
					var index = elem.selectedIndex,
						values = [],
						options = elem.options,
						one = elem.type == "select-one";

					// Nothing was selected
					if ( index < 0 )
						return null;

					// Loop through all the selected options
					for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
						var option = options[ i ];

						if ( option.selected ) {
							// Get the specifc value for the option
							value = jQuery(option).val();

							// We don't need an array for one selects
							if ( one )
								return value;

							// Multi-Selects return an array
							values.push( value );
						}
					}

					return values;
				}

				// Everything else, we just grab the value
				return (elem.value || "").replace(/\r/g, "");

			}

			return undefined;
		}

		// Typecast once if the value is a number
		if ( typeof value === "number" )
			value += '';

		var val = value;

		return this.each(function(){
			if(jQuery.isFunction(value)) {
				val = value.call(this);
				// Typecast each time if the value is a Function and the appended
				// value is therefore different each time.
				if( typeof val === "number" ) val += '';
			}

			if ( this.nodeType != 1 )
				return;

			if ( jQuery.isArray(val) && /radio|checkbox/.test( this.type ) )
				this.checked = jQuery.inArray(this.value || this.name, val) >= 0;

			else if ( jQuery.nodeName( this, "select" ) ) {
				var values = jQuery.makeArray(val);

				jQuery( "option", this ).each(function(){
					this.selected = jQuery.inArray( this.value || this.text, values ) >= 0;
				});

				if ( !values.length )
					this.selectedIndex = -1;

			} else
				this.value = val;
		});
	}
});

jQuery.each({
	removeAttr: function( name ) {
		jQuery.attr( this, name, "" );
		if (this.nodeType == 1)
			this.removeAttribute( name );
	},

	toggleClass: function( classNames, state ) {
		var type = typeof classNames;
		if ( type === "string" ) {
			// toggle individual class names
			var isBool = typeof state === "boolean", className, i = 0,
				classNames = classNames.split( /\s+/ );
			while ( (className = classNames[ i++ ]) ) {
				// check each className given, space seperated list
				state = isBool ? state : !jQuery(this).hasClass( className );
				jQuery(this)[ state ? "addClass" : "removeClass" ]( className );
			}
		} else if ( type === "undefined" || type === "boolean" ) {
			if ( this.className ) {
				// store className if set
				jQuery.data( this, "__className__", this.className );
			}
			// toggle whole className
			this.className = this.className || classNames === false ? "" : jQuery.data( this, "__className__" ) || "";
		}
	}
}, function(name, fn){
	jQuery.fn[ name ] = function(){
		return this.each( fn, arguments );
	};
});

jQuery.extend({
	attr: function( elem, name, value ) {
		// don't set attributes on text and comment nodes
		if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
			return undefined;

		if ( name in jQuery.fn && name !== "attr" ) {
			return jQuery(elem)[name](value);
		}

		var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
			// Whether we are setting (or getting)
			set = value !== undefined;

		// Try to normalize/fix the name
		name = notxml && jQuery.props[ name ] || name;

		// Only do all the following if this is a node (faster for style)
		if ( elem.nodeType === 1 ) {

			// These attributes require special treatment
			var special = /href|src|style/.test( name );

			// Safari mis-reports the default selected property of a hidden option
			// Accessing the parent's selectedIndex property fixes it
			if ( name == "selected" && elem.parentNode )
				elem.parentNode.selectedIndex;

			// If applicable, access the attribute via the DOM 0 way
			if ( name in elem && notxml && !special ) {
				if ( set ){
					// We can't allow the type property to be changed (since it causes problems in IE)
					if ( name == "type" && /(button|input)/i.test(elem.nodeName) && elem.parentNode )
						throw "type property can't be changed";

					elem[ name ] = value;
				}

				// browsers index elements by id/name on forms, give priority to attributes.
				if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )
					return elem.getAttributeNode( name ).nodeValue;

				// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
				// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
				if ( name == "tabIndex" ) {
					var attributeNode = elem.getAttributeNode( "tabIndex" );
					return attributeNode && attributeNode.specified
						? attributeNode.value
						: /(button|input|object|select|textarea)/i.test(elem.nodeName)
							? 0
							: /^(a|area)$/i.test(elem.nodeName) && elem.href
								? 0
								: undefined;
				}

				return elem[ name ];
			}

			if ( !jQuery.support.style && notxml && name == "style" ) {
				if ( set )
					elem.style.cssText = "" + value;

				return elem.style.cssText;
			}

			if ( set )
				// convert the value to a string (all browsers do this but IE) see #1070
				elem.setAttribute( name, "" + value );

			var attr = !jQuery.support.hrefNormalized && notxml && special
					// Some attributes require a special call on IE
					? elem.getAttribute( name, 2 )
					: elem.getAttribute( name );

			// Non-existent attributes return null, we normalize to undefined
			return attr === null ? undefined : attr;
		}

		// elem is actually elem.style ... set the style
		// Using attr for specific style information is now deprecated. Use style insead.
		return jQuery.style(elem, name, value);
	}
});
<commit_msg>Shorter code, using a regexp for replace<commit_after>jQuery.fn.extend({
	attr: function( name, value ) {
		return access(this, name, value, true, jQuery.attr);
	},

	addClass: function( value ) {
		if ( value && typeof value === "string" ) {
			var classNames = (value || "").split(/\s+/);

			for ( var i = 0, l = this.length; i < l; i++ ) {
				var elem = this[i];

				if ( elem.nodeType === 1 ) {
					if ( !elem.className ) {
						elem.className = value;
					} else {
						var className = " " + elem.className + " ";
						for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
							if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
								elem.className += " " + classNames[c];
							}
						}
					}
				}
			}
		}

		return this;
	},

	removeClass: function( value ) {
		if ( (value && typeof value === "string") || value === undefined ) {
			var classNames = (value || "").split(/\s+/);

			for ( var i = 0, l = this.length; i < l; i++ ) {
				var elem = this[i];

				if ( elem.nodeType === 1 && elem.className ) {
					if ( value ) {
					var className = " " + elem.className + " ";
						for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
							className = className.replace(" " + classNames[c] + " ", " ");
						}
						elem.className = className.substring(1, className.length - 1);
					} else {
						elem.className = "";
					}
				}
			}
		}

		return this;
	},

	hasClass: function( selector ) {
		var searchTerm = " " + selector + " ";
		for ( var i = 0, l = this.length; i < l; i++ ) {
			var className = " " + this[i].className + " ";
			// according to the HTML W3C documentation
			// carriage return and tab should be replaced with a single space
			// http://www.w3.org/TR/html401/types.html#type-cdata
			className = className.replace(/[\n\t]/g, " ");
			if ( className.indexOf( searchTerm ) > -1 ) {
				return true;
			}
		}
		return false;
	},

	val: function( value ) {
		if ( value === undefined ) {
			var elem = this[0];

			if ( elem ) {
				if( jQuery.nodeName( elem, 'option' ) )
					return (elem.attributes.value || {}).specified ? elem.value : elem.text;

				// We need to handle select boxes special
				if ( jQuery.nodeName( elem, "select" ) ) {
					var index = elem.selectedIndex,
						values = [],
						options = elem.options,
						one = elem.type == "select-one";

					// Nothing was selected
					if ( index < 0 )
						return null;

					// Loop through all the selected options
					for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
						var option = options[ i ];

						if ( option.selected ) {
							// Get the specifc value for the option
							value = jQuery(option).val();

							// We don't need an array for one selects
							if ( one )
								return value;

							// Multi-Selects return an array
							values.push( value );
						}
					}

					return values;
				}

				// Everything else, we just grab the value
				return (elem.value || "").replace(/\r/g, "");

			}

			return undefined;
		}

		// Typecast once if the value is a number
		if ( typeof value === "number" )
			value += '';

		var val = value;

		return this.each(function(){
			if(jQuery.isFunction(value)) {
				val = value.call(this);
				// Typecast each time if the value is a Function and the appended
				// value is therefore different each time.
				if( typeof val === "number" ) val += '';
			}

			if ( this.nodeType != 1 )
				return;

			if ( jQuery.isArray(val) && /radio|checkbox/.test( this.type ) )
				this.checked = jQuery.inArray(this.value || this.name, val) >= 0;

			else if ( jQuery.nodeName( this, "select" ) ) {
				var values = jQuery.makeArray(val);

				jQuery( "option", this ).each(function(){
					this.selected = jQuery.inArray( this.value || this.text, values ) >= 0;
				});

				if ( !values.length )
					this.selectedIndex = -1;

			} else
				this.value = val;
		});
	}
});

jQuery.each({
	removeAttr: function( name ) {
		jQuery.attr( this, name, "" );
		if (this.nodeType == 1)
			this.removeAttribute( name );
	},

	toggleClass: function( classNames, state ) {
		var type = typeof classNames;
		if ( type === "string" ) {
			// toggle individual class names
			var isBool = typeof state === "boolean", className, i = 0,
				classNames = classNames.split( /\s+/ );
			while ( (className = classNames[ i++ ]) ) {
				// check each className given, space seperated list
				state = isBool ? state : !jQuery(this).hasClass( className );
				jQuery(this)[ state ? "addClass" : "removeClass" ]( className );
			}
		} else if ( type === "undefined" || type === "boolean" ) {
			if ( this.className ) {
				// store className if set
				jQuery.data( this, "__className__", this.className );
			}
			// toggle whole className
			this.className = this.className || classNames === false ? "" : jQuery.data( this, "__className__" ) || "";
		}
	}
}, function(name, fn){
	jQuery.fn[ name ] = function(){
		return this.each( fn, arguments );
	};
});

jQuery.extend({
	attr: function( elem, name, value ) {
		// don't set attributes on text and comment nodes
		if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
			return undefined;

		if ( name in jQuery.fn && name !== "attr" ) {
			return jQuery(elem)[name](value);
		}

		var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
			// Whether we are setting (or getting)
			set = value !== undefined;

		// Try to normalize/fix the name
		name = notxml && jQuery.props[ name ] || name;

		// Only do all the following if this is a node (faster for style)
		if ( elem.nodeType === 1 ) {

			// These attributes require special treatment
			var special = /href|src|style/.test( name );

			// Safari mis-reports the default selected property of a hidden option
			// Accessing the parent's selectedIndex property fixes it
			if ( name == "selected" && elem.parentNode )
				elem.parentNode.selectedIndex;

			// If applicable, access the attribute via the DOM 0 way
			if ( name in elem && notxml && !special ) {
				if ( set ){
					// We can't allow the type property to be changed (since it causes problems in IE)
					if ( name == "type" && /(button|input)/i.test(elem.nodeName) && elem.parentNode )
						throw "type property can't be changed";

					elem[ name ] = value;
				}

				// browsers index elements by id/name on forms, give priority to attributes.
				if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )
					return elem.getAttributeNode( name ).nodeValue;

				// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
				// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
				if ( name == "tabIndex" ) {
					var attributeNode = elem.getAttributeNode( "tabIndex" );
					return attributeNode && attributeNode.specified
						? attributeNode.value
						: /(button|input|object|select|textarea)/i.test(elem.nodeName)
							? 0
							: /^(a|area)$/i.test(elem.nodeName) && elem.href
								? 0
								: undefined;
				}

				return elem[ name ];
			}

			if ( !jQuery.support.style && notxml && name == "style" ) {
				if ( set )
					elem.style.cssText = "" + value;

				return elem.style.cssText;
			}

			if ( set )
				// convert the value to a string (all browsers do this but IE) see #1070
				elem.setAttribute( name, "" + value );

			var attr = !jQuery.support.hrefNormalized && notxml && special
					// Some attributes require a special call on IE
					? elem.getAttribute( name, 2 )
					: elem.getAttribute( name );

			// Non-existent attributes return null, we normalize to undefined
			return attr === null ? undefined : attr;
		}

		// elem is actually elem.style ... set the style
		// Using attr for specific style information is now deprecated. Use style insead.
		return jQuery.style(elem, name, value);
	}
});
<|endoftext|>