├── CHANGELOG.md ├── .gitignore ├── LICENSE ├── .jshintrc ├── templates ├── amd.js ├── umd.js └── standalone.js ├── tasks ├── clean.js ├── changelog.js ├── bytesize.js ├── copy.js ├── markdox.js ├── uglify.js ├── watch.js ├── jscs.js ├── mocha.js ├── bump.js ├── jshint.js ├── copyright.js └── buildcontrol.js ├── .travis.yml ├── src ├── .jshintrc └── dominator.js ├── tests ├── bower.json ├── index.html └── spec │ └── test_dominator.js ├── bower.json ├── .jscsrc ├── Gruntfile.js ├── README.md └── package.json /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2 | ### 0.0.3 (2015-01-01) 3 | 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | /build 3 | /docs 4 | .DS_Store 5 | /tests/bower_components/ 6 | 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 | * You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "curly": true, 3 | "eqeqeq": true, 4 | "immed": true, 5 | "latedef": true, 6 | "newcap": true, 7 | "noarg": true, 8 | "sub": true, 9 | "undef": true, 10 | "unused": "vars", 11 | "boss": true, 12 | "eqnull": true, 13 | "node": true 14 | } 15 | -------------------------------------------------------------------------------- /templates/amd.js: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | define([], function () { 6 | {{ body }} 7 | }); 8 | 9 | -------------------------------------------------------------------------------- /templates/umd.js: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | module.exports = (function() { 6 | {{ body }} 7 | }()); 8 | 9 | -------------------------------------------------------------------------------- /templates/standalone.js: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | window.DOMinator = (function() { 6 | {{ body }} 7 | }()); 8 | 9 | -------------------------------------------------------------------------------- /tasks/clean.js: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | module.exports = function (grunt) { 6 | 'use strict'; 7 | 8 | grunt.config('clean', { 9 | build: ['build', 'docs'] 10 | }); 11 | }; 12 | -------------------------------------------------------------------------------- /tasks/changelog.js: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | module.exports = function (grunt) { 6 | 'use strict'; 7 | 8 | grunt.config('changelog', { 9 | options: { 10 | from: 'source-<%= pkgReadOnly.version %>' 11 | } 12 | }); 13 | }; 14 | -------------------------------------------------------------------------------- /tasks/bytesize.js: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | module.exports = function (grunt) { 6 | 'use strict'; 7 | 8 | grunt.config('bytesize', { 9 | all: { 10 | src: ['build/dominator.js', 'build/dominator.min.js'] 11 | } 12 | }); 13 | }; 14 | -------------------------------------------------------------------------------- /tasks/copy.js: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | module.exports = function (grunt) { 6 | 'use strict'; 7 | 8 | grunt.config('copy', { 9 | dist: { 10 | src: 'src/dominator.js', 11 | dest: 'build/dominator.js' 12 | } 13 | }); 14 | }; 15 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | cache: node_modules 3 | 4 | sudo: false 5 | 6 | notifications: 7 | email: 8 | recipients: 9 | - shane@shanetomlinson.com 10 | on_success: change 11 | on_failure: always 12 | 13 | node_js: 14 | - 0.10.25 15 | 16 | before_install: 17 | - phantomjs --version 18 | 19 | install: 20 | - travis_retry npm install --silent 21 | - npm run-script setup-bower 22 | 23 | script: 24 | - npm test 25 | 26 | -------------------------------------------------------------------------------- /src/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "curly": false, 3 | "eqeqeq": true, 4 | "immed": true, 5 | "latedef": "vars", 6 | "newcap": false, 7 | "noarg": true, 8 | "node": false, 9 | "sub": true, 10 | "undef": true, 11 | "devel": true, 12 | "unused": "vars", 13 | "boss": true, 14 | "eqnull": true, 15 | "browser": true, 16 | "globals": { 17 | "define": false, 18 | "require": false, 19 | "module": false 20 | }, 21 | "globalstrict": true 22 | } 23 | -------------------------------------------------------------------------------- /tasks/markdox.js: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | module.exports = function (grunt) { 6 | 'use strict'; 7 | 8 | grunt.config('markdox', { 9 | dist: { 10 | files: [ 11 | { src: 'src/dominator.js', dest: 'docs/api.md' } 12 | ] 13 | } 14 | }); 15 | }; 16 | -------------------------------------------------------------------------------- /tasks/uglify.js: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | module.exports = function (grunt) { 6 | 'use strict'; 7 | 8 | grunt.config('uglify', { 9 | options: { 10 | sourceMap: true 11 | }, 12 | dist: { 13 | files: { 14 | 'build/dominator.min.js': ['build/dominator.js'] 15 | } 16 | } 17 | }); 18 | }; 19 | -------------------------------------------------------------------------------- /tasks/watch.js: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | module.exports = function (grunt) { 6 | 'use strict'; 7 | 8 | grunt.config('watch', { 9 | dev: { 10 | options: { 11 | atBegin: true 12 | }, 13 | files: ['Gruntfile.js', 'src/**/*.js', 'tests/**/*.js'], 14 | tasks: ['build', 'mocha'] 15 | } 16 | }); 17 | }; 18 | -------------------------------------------------------------------------------- /tasks/jscs.js: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | module.exports = function (grunt) { 6 | 'use strict'; 7 | 8 | grunt.config('jscs', { 9 | src: [ 10 | '**/*.js', 11 | '!node_modules/**', 12 | '!build/**', 13 | '!docs/**', 14 | '!tests/**' 15 | ], 16 | options: { 17 | config: '.jscsrc' 18 | } 19 | }); 20 | }; 21 | -------------------------------------------------------------------------------- /tasks/mocha.js: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | module.exports = function (grunt) { 6 | 'use strict'; 7 | 8 | grunt.config('mocha', { 9 | test: { 10 | src: ['tests/index.html'], 11 | options: { 12 | run: true, 13 | log: true, 14 | logErrors: true, 15 | timeout: 20000 16 | } 17 | } 18 | }); 19 | }; 20 | -------------------------------------------------------------------------------- /tasks/bump.js: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | module.exports = function (grunt) { 6 | 'use strict'; 7 | 8 | grunt.config('bump', { 9 | options: { 10 | files: ['package.json', 'bower.json'], 11 | push: false, 12 | createTag: false, 13 | commitFiles: ['-a'], 14 | commitMessage: 'Start of release %VERSION%' 15 | } 16 | }); 17 | }; 18 | -------------------------------------------------------------------------------- /tasks/jshint.js: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | module.exports = function (grunt) { 6 | 'use strict'; 7 | 8 | grunt.config('jshint', { 9 | config: { 10 | options: {jshintrc: '.jshintrc'}, 11 | src: ['Gruntfile.js', 'tasks/*.js', 'config/**/*.js', 'node/**/*.js'] 12 | }, 13 | app: { 14 | options: {jshintrc: 'src/.jshintrc'}, 15 | src: ['src/*.js', 'src/lib/**/*'] 16 | } 17 | }); 18 | }; 19 | -------------------------------------------------------------------------------- /tests/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dominator-tests", 3 | "version": "0.0.0", 4 | "authors": [ 5 | "Shane Tomlinson " 6 | ], 7 | "description": "The tests for the dominator library", 8 | "moduleType": [ 9 | "amd", 10 | "es6" 11 | ], 12 | "license": "MPL 2.0", 13 | "private": true, 14 | "ignore": [ 15 | "**/.*", 16 | "node_modules", 17 | "bower_components", 18 | "test", 19 | "tests" 20 | ], 21 | "dependencies": { 22 | "chai": "1.10.0", 23 | "jquery": "2.1.3", 24 | "mocha": "2.1.0", 25 | "sinon": "http://sinonjs.org/releases/sinon-1.12.2.js" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tasks/copyright.js: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | module.exports = function (grunt) { 6 | 'use strict'; 7 | 8 | grunt.config('copyright', { 9 | app: { 10 | options: { 11 | pattern: /This Source Code Form is subject to the terms of the Mozilla Public/ 12 | }, 13 | src: [ 14 | '**/*.js', 15 | '!tests/bower_components/**', 16 | '!build/**', 17 | '!node_modules/**', 18 | '!docs/**' 19 | ] 20 | } 21 | }); 22 | }; 23 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dominator", 3 | "version": "0.0.4", 4 | "homepage": "https://github.com/shane-tomlinson/dominator", 5 | "authors": [ 6 | "Shane Tomlinson " 7 | ], 8 | "description": "DOMinator is a jQuery-like DOM micro library.", 9 | "main": "dominator.js", 10 | "moduleType": [ 11 | "amd", 12 | "globals", 13 | "node" 14 | ], 15 | "keywords": [ 16 | "DOM", 17 | "jQuery", 18 | "mircolibrary", 19 | "DOM", 20 | "manipulation" 21 | ], 22 | "license": "MPL 2.0", 23 | "ignore": [ 24 | "**/.*", 25 | "node_modules", 26 | "bower_components", 27 | "test", 28 | "tests" 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /tasks/buildcontrol.js: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | module.exports = function (grunt) { 6 | 'use strict'; 7 | 8 | grunt.config('buildcontrol', { 9 | options: { 10 | commit: true, 11 | push: true, 12 | remote: 'git@github.com:shane-tomlinson/dominator.git' 13 | }, 14 | release: { 15 | options: { 16 | branch: 'release', 17 | dir: 'build', 18 | tag: '<%= pkg.version %>' 19 | } 20 | }, 21 | docs: { 22 | options: { 23 | branch: 'gh-pages', 24 | dir: 'docs', 25 | tag: 'docs-<%= pkg.version %>' 26 | } 27 | } 28 | }); 29 | }; 30 | -------------------------------------------------------------------------------- /.jscsrc: -------------------------------------------------------------------------------- 1 | { 2 | "disallowKeywords": ["with", "eval"], 3 | "disallowKeywordsOnNewLine": ["else"], 4 | "requireSpaceBeforeBinaryOperators": ["?", "-", "/", "*", "=", "==", "===", "!=", "!==", ">", ">=", "<", "<="], 5 | "disallowMultipleLineStrings": true, 6 | "requireSpaceAfterBinaryOperators": ["?", "/", "*", ":", "=", "==", "===", "!=", "!==", ">", ">=", "<", "<="], 7 | "disallowSpaceAfterObjectKeys": true, 8 | "disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-"], 9 | "disallowSpaceBeforePostfixUnaryOperators": ["++", "--"], 10 | "maximumLineLength": 420, 11 | "requireCapitalizedConstructors": true, 12 | "requireLineFeedAtFileEnd": true, 13 | "requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return"], 14 | "validateIndentation": 2, 15 | "validateLineBreaks": "LF", 16 | "validateQuoteMarks": true, 17 | "validateJSDoc": { 18 | "checkParamNames": true, 19 | "checkRedundantParams": true, 20 | "requireParamTypes": true 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | module.exports = function (grunt) { 6 | // load all grunt tasks matching the `grunt-*` pattern 7 | require('load-grunt-tasks')(grunt); 8 | 9 | var pkg = grunt.file.readJSON('package.json'); 10 | 11 | grunt.initConfig({ 12 | pkg: pkg, 13 | pkgReadOnly: pkg 14 | }); 15 | 16 | // load local Grunt tasks 17 | grunt.loadTasks('tasks'); 18 | 19 | grunt.registerTask('build', 20 | 'Build compressed resources', 21 | ['clean', 'lint', 'copy', 'uglify', 'bytesize']); 22 | 23 | grunt.registerTask('test', 24 | 'Run tests', 25 | ['mocha']); 26 | 27 | grunt.registerTask('lint', 28 | 'Alias for jshint and jscs tasks', 29 | ['jshint', 'jscs']); 30 | 31 | grunt.registerTask('default', 32 | ['build']); 33 | 34 | grunt.registerTask('doc', 35 | ['markdox']); 36 | 37 | grunt.registerTask('release', 38 | ['build', 'bump-only', 'changelog', 'bump-commit', 'doc', 'buildcontrol']); 39 | }; 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DOMinator 2 | 3 | DOMinator is a jQuery-like DOM micro library. DOMinator is not meant to be fully compatible with jQuery, but to only provide a commonly used subset of functionality. DOMinator only works in modern browsers, including IE10+. DOMinator's lack of features has one significant benefit - its tiny size. Compare DOMinator's 1.3kb gzipped footprint to jQuery's 30+kb. 4 | 5 | ## Usage 6 | 7 | DOMinator is requires document.querySelectorAll, its primary purpose is 8 | within a browwser. The pre-built package in the `build` directory works 9 | as a standalone module under window.DOMinator, and can also be used with 10 | UMD or AMD module loaders. 11 | 12 | ## Documentation: 13 | See the [API docs](https://github.com/shane-tomlinson/dominator/blob/master/docs/api.md). 14 | 15 | ## Author: 16 | * Shane Tomlinson 17 | * shane@shanetomlinson.com 18 | * stomlinson@mozilla.com 19 | * set117@yahoo.com 20 | * https://shanetomlinson.com 21 | * http://github.com/shane-tomlinson 22 | * @shane_tomlinson 23 | 24 | ## Get involved: 25 | 26 | Any and all pull requests will be reviewed and considered. 27 | 28 | Specific needs: 29 | 30 | * Documentation 31 | * Cross browser testing 32 | * IE8/IE9 support 33 | * Bower package 34 | 35 | ## License: 36 | This software is available under version 2.0 of the MPL: 37 | 38 | https://www.mozilla.org/MPL/ 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /tests/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | DOMinator Unit Tests 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | AFrame.List test 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | A hidden element 45 | 46 | 47 | 48 | 49 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dominator", 3 | "version": "0.0.4", 4 | "description": "DOMinator is a jQuery-like DOM micro library.", 5 | "main": "build/dominator.js", 6 | "scripts": { 7 | "start": "grunt", 8 | "test": "grunt test", 9 | "setup": "npm install && npm run-script setup-bower", 10 | "setup-bower": "cd tests && bower install && cd ..", 11 | "contributors": "git shortlog -s | cut -c8- | sort -f > CONTRIBUTORS.md" 12 | }, 13 | "directories": { 14 | "test": "tests" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "git://github.com/shane-tomlinson/dominator.git" 19 | }, 20 | "keywords": [ 21 | "DOM", 22 | "jQuery", 23 | "microlibrary" 24 | ], 25 | "author": "Shane Tomlinson ", 26 | "license": "MPL 2.0", 27 | "bugs": { 28 | "url": "https://github.com/shane-tomlinson/dominator/issues" 29 | }, 30 | "homepage": "https://github.com/shane-tomlinson/dominator", 31 | "devDependencies": { 32 | "bower": "1.3.12", 33 | "grunt": "0.4.5", 34 | "grunt-build-control": "git://github.com/robwierzbowski/grunt-build-control#274952", 35 | "grunt-bump": "0.0.16", 36 | "grunt-bytesize": "0.1.1", 37 | "grunt-cli": "0.1.13", 38 | "grunt-contrib-clean": "0.6.0", 39 | "grunt-contrib-copy": "0.7.0", 40 | "grunt-contrib-jshint": "0.10.0", 41 | "grunt-contrib-uglify": "0.7.0", 42 | "grunt-contrib-watch": "0.6.1", 43 | "grunt-conventional-changelog": "1.1.0", 44 | "grunt-copyright": "0.1.0", 45 | "grunt-jscs": "1.1.0", 46 | "grunt-markdox": "1.2.1", 47 | "grunt-mocha": "0.4.11", 48 | "load-grunt-tasks": "2.0.0" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tests/spec/test_dominator.js: -------------------------------------------------------------------------------- 1 | describe('DOMinator', function() { 2 | var events; 3 | var eventCounts; 4 | var eventType; 5 | 6 | var assert = chai.assert; 7 | var genericHandler = function(event) { 8 | var eventName = (event && event.type) || eventType; 9 | events[eventName] = true; 10 | 11 | if (! (eventName in eventCounts)) { 12 | eventCounts[eventName] = 0; 13 | } 14 | eventCounts[eventName]++; 15 | }; 16 | 17 | beforeEach(function() { 18 | events = {}; 19 | eventCounts = {}; 20 | jQuery('.DOMSelection').empty().append('Part 1Part 2Part 3'); 21 | }); 22 | 23 | describe('constructor', function() { 24 | var elements, regetElements, regetSingleElement; 25 | 26 | beforeEach(function() { 27 | elements = DOMinator('body'); 28 | regetElements = DOMinator(elements); 29 | regetSingleElement = DOMinator(elements[0]); 30 | }); 31 | 32 | it('finds elements with the given selector', function() { 33 | assert.equal(1, elements.length); 34 | }); 35 | 36 | it('accepts a DOMinator list of elements', function() { 37 | assert.equal(1, regetElements.length); 38 | assert.equal(elements[ 0 ], regetElements[ 0 ]); 39 | }); 40 | 41 | it('accepts a DOM element', function() { 42 | assert.equal(1, regetSingleElement.length); 43 | assert.equal(elements[ 0 ], regetSingleElement[ 0 ]); 44 | }); 45 | }); 46 | 47 | describe('constructor with HTML', function() { 48 | var element; 49 | 50 | beforeEach(function() { 51 | element = DOMinator('some html contents').nth(0); 52 | }); 53 | 54 | it('creates the DOM elements', function() { 55 | assert.isTrue(jQuery(element).is('div'), 'element created'); 56 | assert.equal('some html contents', jQuery(element).html(), 'element has contents set'); 57 | }); 58 | }); 59 | 60 | describe('find', function() { 61 | var buttons; 62 | 63 | beforeEach(function() { 64 | buttons = DOMinator('body').find('.button'); 65 | }); 66 | 67 | it('finds descendent elements', function() { 68 | assert.isNumber(buttons.length); 69 | }); 70 | }); 71 | 72 | describe('findIncludeRoot', function() { 73 | var divsIncludingRoot; 74 | 75 | beforeEach(function() { 76 | divsIncludingRoot = DOMinator('.DOMSelection').findIncludeRoot('div'); 77 | }); 78 | 79 | it('includes the root, if the root matches the selector', function() { 80 | assert.equal(4, divsIncludingRoot.length); 81 | }); 82 | }); 83 | 84 | describe('children', function() { 85 | var children; 86 | 87 | beforeEach(function() { 88 | jQuery('.DOMSelection').empty().append('Part 1Part 2Part 3'); 89 | children = DOMinator('.DOMSelection').children(); 90 | }); 91 | 92 | it('returns all the children', function() { 93 | assert.equal(3, children.length); 94 | }); 95 | }); 96 | 97 | describe('nthChild', function() { 98 | var child; 99 | 100 | beforeEach(function() { 101 | child = DOMinator('.DOMSelection').nthChild(0); 102 | }); 103 | 104 | it('returns the nth child', function() { 105 | assert.isObject(child); 106 | }); 107 | }); 108 | 109 | describe('closest', function() { 110 | var closest; 111 | 112 | beforeEach(function() { 113 | closest = DOMinator('.list').closest('div'); 114 | }); 115 | 116 | it('finds the closest anscestor', function() { 117 | assert.equal('AFrame_List', $(closest).attr('id')); 118 | }); 119 | }); 120 | 121 | describe('forEach', function() { 122 | var children, maxIndex, context; 123 | 124 | beforeEach(function() { 125 | children = DOMinator('.DOMSelection').children(); 126 | maxIndex = -1; 127 | children.forEach(function(element, index) { 128 | maxIndex = index; 129 | context = this; 130 | }, this); 131 | }); 132 | 133 | it('iterates over all matched items', function() { 134 | assert.equal(2, maxIndex); 135 | assert.equal(this, context); 136 | }); 137 | }); 138 | 139 | describe('on and trigger', function() { 140 | beforeEach(function() { 141 | events.click = false; 142 | eventType = null; 143 | 144 | DOMinator('.DOMSelection').on('click', genericHandler).trigger('click'); 145 | }); 146 | 147 | it('binds a DOM event handler that is actually fired', function() { 148 | assert.isTrue(events.click); 149 | DOMinator('.DOMSelection').off('click', genericHandler); 150 | }); 151 | }); 152 | 153 | describe('once and trigger', function() { 154 | beforeEach(function() { 155 | events = {}; 156 | eventCounts = {}; 157 | eventType = null; 158 | 159 | DOMinator('.DOMSelection').once('click', genericHandler).trigger('click').trigger('click'); 160 | }); 161 | 162 | it('only triggers the handler once', function() { 163 | assert.equal(eventCounts.click, 1); 164 | DOMinator('.DOMSelection').off('click', genericHandler); 165 | }); 166 | }); 167 | 168 | describe('off', function() { 169 | beforeEach(function() { 170 | events.click = false; 171 | eventType = null; 172 | 173 | DOMinator('.DOMSelection').on('click', genericHandler).off('click', genericHandler).trigger('click'); 174 | }); 175 | 176 | it('removes the DOM event handler', function() { 177 | assert.isFalse(events.click); 178 | }); 179 | }); 180 | 181 | describe('val to set on a form field', function() { 182 | beforeEach(function() { 183 | DOMinator('#validationField').val('test element value'); 184 | }); 185 | 186 | it('sets the value of the field', function() { 187 | assert.equal('test element value', jQuery('#validationField').val()); 188 | }); 189 | }); 190 | 191 | describe('val to get a form field', function() { 192 | beforeEach(function() { 193 | DOMinator('#validationField').val('test element value'); 194 | }); 195 | 196 | it('gets the value of the field', function() { 197 | assert.equal('test element value', DOMinator('#validationField').val()); 198 | }); 199 | }); 200 | 201 | describe('val to set on a non-form field element', function() { 202 | it('throws an error', function() { 203 | var err; 204 | try { 205 | DOMinator('#testSetInnerNonInput').val('test element value'); 206 | } catch(e) { 207 | err = e; 208 | } finally { 209 | assert.ok(err); 210 | assert.notEqual('test element value', jQuery('#testSetInnerNonInput').html()); 211 | } 212 | }); 213 | }); 214 | 215 | describe('val to get on a non-form field element', function() { 216 | it('throws an error', function() { 217 | var err; 218 | try { 219 | DOMinator('#testSetInnerNonInput').val(); 220 | } catch(e) { 221 | err = e; 222 | } finally { 223 | assert.ok(err); 224 | } 225 | }); 226 | }); 227 | 228 | describe('html to set the html of an element', function() { 229 | beforeEach(function() { 230 | DOMinator('#testSetInnerNonInput').html('test element value'); 231 | }); 232 | 233 | it('sets the HTML of the element', function() { 234 | assert.equal('test element value', jQuery('#testSetInnerNonInput').html()); 235 | }); 236 | }); 237 | 238 | describe('html to get the html of an element', function() { 239 | beforeEach(function() { 240 | DOMinator('#testSetInnerNonInput').html('test element value'); 241 | }); 242 | 243 | it('gets the HTML of the element', function() { 244 | assert.equal('test element value', DOMinator('#testSetInnerNonInput').html()); 245 | }); 246 | }); 247 | 248 | describe('empty', function() { 249 | beforeEach(function() { 250 | DOMinator('#testSetInnerNonInput').html('test element value').empty(); 251 | }); 252 | 253 | it('emptys an element of contents', function() { 254 | assert.equal('', DOMinator('#testSetInnerNonInput').html()); 255 | }); 256 | }); 257 | 258 | describe('attr to set an attribute', function() { 259 | beforeEach(function() { 260 | DOMinator('#testSetInnerNonInput').attr('data-attr', 'test attr'); 261 | }); 262 | 263 | it('sets the attribute value', function() { 264 | assert.equal('test attr', jQuery('#testSetInnerNonInput').attr('data-attr')); 265 | }); 266 | }); 267 | 268 | describe('attr to get an attribute', function() { 269 | beforeEach(function() { 270 | DOMinator('#testSetInnerNonInput').attr('data-attr', 'test attr'); 271 | }); 272 | 273 | it('gets the attribute value', function() { 274 | assert.equal('test attr', DOMinator('#testSetInnerNonInput').attr('data-attr')); 275 | }); 276 | 277 | it('returns undefined on a non-existent element', function() { 278 | assert.isUndefined(DOMinator('#nonexistent').attr('data-attr')); 279 | }); 280 | }); 281 | 282 | describe('hasAttr', function() { 283 | beforeEach(function() { 284 | DOMinator('#testSetInnerNonInput').attr('data-attr', 'test attr'); 285 | }); 286 | 287 | it('returns true if an element has the attribute', function() { 288 | assert.isTrue(DOMinator('#testSetInnerNonInput').hasAttr('data-attr')); 289 | }); 290 | 291 | it('returns false if an element has the attribute', function() { 292 | assert.isFalse(DOMinator('body').hasAttr('data-attr')); 293 | }); 294 | 295 | it('returns false on a non-existent element', function() { 296 | assert.isFalse(DOMinator('#nonexistent').hasAttr('data-attr')); 297 | }); 298 | }); 299 | 300 | describe('removeAttr', function() { 301 | beforeEach(function() { 302 | DOMinator('#testSetInnerNonInput').attr('data-attr', 'test attr'); 303 | DOMinator('#testSetInnerNonInput').removeAttr('data-attr'); 304 | }); 305 | 306 | it('removes an attribute from an element', function() { 307 | assert.isFalse(DOMinator('#testSetInnerNonInput').hasAttr('data-attr')); 308 | }); 309 | }); 310 | 311 | describe('addClass', function() { 312 | beforeEach(function() { 313 | DOMinator('#testSetInnerNonInput') 314 | .removeClass('testClass') 315 | .addClass('testClass'); 316 | }); 317 | 318 | it('adds a class to an element', function() { 319 | assert.isTrue(jQuery('#testSetInnerNonInput').hasClass('testClass')); 320 | }); 321 | }); 322 | 323 | describe('removeClass', function() { 324 | beforeEach(function() { 325 | DOMinator('#testSetInnerNonInput') 326 | .addClass('testClass') 327 | .removeClass('testClass'); 328 | }); 329 | 330 | it('removes a class from an element', function() { 331 | assert.isFalse(jQuery('#testSetInnerNonInput').hasClass('testClass')); 332 | }); 333 | }); 334 | 335 | describe('hasClass', function() { 336 | beforeEach(function() { 337 | DOMinator('#testSetInnerNonInput').addClass('testClass'); 338 | }); 339 | 340 | it('returns true if element has the class', function() { 341 | assert.isTrue(DOMinator('#testSetInnerNonInput').hasClass('testClass')); 342 | }); 343 | 344 | it('returns false if the element does not have the class', function() { 345 | assert.isFalse(DOMinator('#testSetInnerNonInput').hasClass('nonexistentClass')); 346 | }); 347 | }); 348 | 349 | describe('append', function() { 350 | beforeEach(function() { 351 | DOMinator('#addedField').remove(); 352 | 353 | var element = DOMinator('added child').attr('id', 'addedField'); 354 | DOMinator('body').append(element); 355 | }); 356 | 357 | it('appends the elements to the current selection', function() { 358 | assert.equal(1, jQuery('#addedField').length); 359 | }); 360 | }); 361 | 362 | describe('appendTo', function() { 363 | beforeEach(function() { 364 | DOMinator('.DOMSelection').empty(); 365 | DOMinator('empty div').appendTo('.DOMSelection'); 366 | }); 367 | 368 | it('append selection to selector given in appendTo', function() { 369 | assert.equal(1, jQuery('.DOMSelection').children().length, 'appendTo appends'); 370 | }); 371 | }); 372 | 373 | describe('insertAfter', function() { 374 | beforeEach(function() { 375 | DOMinator('.DOMSelection').empty(); 376 | 377 | var first = DOMinator('first div').appendTo('.DOMSelection'); 378 | DOMinator('second div').insertAfter(first); 379 | }); 380 | 381 | it('inserts selection to selector given in insertAfter', function() { 382 | assert.equal(2, jQuery('.DOMSelection').children().length); 383 | }); 384 | }); 385 | 386 | describe('insertBefore', function() { 387 | beforeEach(function() { 388 | jQuery('.DOMSelection').empty(); 389 | 390 | var first = DOMinator('first div').appendTo('.DOMSelection'); 391 | DOMinator('second div').insertBefore(first); 392 | }); 393 | 394 | it('inserts selection before selector given in insertBefore', function() { 395 | assert.equal(2, jQuery('.DOMSelection').children().length); 396 | }); 397 | }); 398 | 399 | describe('insertAsNthChild', function() { 400 | beforeEach(function() { 401 | DOMinator('2nd child') 402 | .attr('id', 'second') 403 | .insertAsNthChild('.DOMSelection', 1); 404 | }); 405 | 406 | it('inserts into the correct position', function() { 407 | assert.equal(4, jQuery('.DOMSelection').children().length, 'appendTo appends'); 408 | }); 409 | }); 410 | 411 | describe('remove', function() { 412 | beforeEach(function() { 413 | DOMinator('#addedField').remove(); 414 | 415 | DOMinator('added child') 416 | .attr('id', 'addedField') 417 | .appendTo('body').remove(); 418 | }); 419 | 420 | it('removes the element from the DOM', function() { 421 | assert.equal(0, jQuery('#addedField').length); 422 | }); 423 | }); 424 | 425 | describe('is', function() { 426 | it('returns true if an element matches selector', function() { 427 | assert.isTrue(DOMinator('#textAreaField').is('#textAreaField')); 428 | }); 429 | 430 | it('returns false if an element does not match selector', function() { 431 | assert.isFalse(DOMinator('#textAreaField').is('body')); 432 | }); 433 | 434 | it('returns false if non-existent element', function() { 435 | assert.isFalse(DOMinator('#nonexistent').is('body')); 436 | }); 437 | }); 438 | 439 | describe('focus', function() { 440 | beforeEach(function() { 441 | DOMinator('#textAreaField').focus(); 442 | }); 443 | 444 | it('focuses an element', function() { 445 | /*assert.isTrue(jQuery('#textAreaField').is(':focus'));*/ 446 | }); 447 | }); 448 | 449 | describe('show', function() { 450 | beforeEach(function() { 451 | DOMinator('#hiddenElement').hide().show(); 452 | }); 453 | 454 | it('shows an element', function() { 455 | assert.isTrue(jQuery('#hiddenElement').is(':visible')); 456 | }); 457 | }); 458 | 459 | describe('hide', function() { 460 | beforeEach(function() { 461 | DOMinator('#hiddenElement').show().hide(); 462 | }); 463 | 464 | it('hides an element', function() { 465 | assert.isFalse(jQuery('#hiddenElement').is(':visible')); 466 | }); 467 | }); 468 | 469 | describe('style to set style', function() { 470 | beforeEach(function() { 471 | DOMinator('body').style('position', 'absolute'); 472 | }); 473 | 474 | afterEach(function() { 475 | DOMinator('body').style('position', 'static'); 476 | }); 477 | 478 | it('sets the style of an element', function() { 479 | assert.equal(jQuery('body')[0].style.position, 'absolute'); 480 | }); 481 | }); 482 | 483 | describe('toArray', function() { 484 | it('converts the DOMinator object to an array', function() { 485 | assert.isArray(DOMinator('body').toArray()); 486 | }); 487 | }); 488 | }); 489 | -------------------------------------------------------------------------------- /src/dominator.js: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | /** 6 | * @class DOMinator 7 | * @author Shane Tomlinson shane@shanetomlinson.com 8 | * @version 0.0.3 9 | */ 10 | // 11 | // jscs: disable 12 | // jshint ignore:start 13 | ;(function(define){define(function(require,exports,module){ 14 | // jshint ignore:end 15 | // jscs: enable 16 | 17 | 'use strict'; 18 | 19 | /*global document*/ 20 | 21 | var DOMinator = { 22 | /** 23 | * Fill the DOMinator object with elements matched by the the selector. 24 | * 25 | * @method fill 26 | * @param {String} selector Selector to match 27 | * @return {Collection} DOMinator collection 28 | */ 29 | fill: function (selector) { 30 | var els = getElements(selector); 31 | 32 | els.forEach(function (item, index) { 33 | this[index] = item; 34 | }, this); 35 | this.length = els.length; 36 | 37 | return this; 38 | }, 39 | 40 | /** 41 | * Get the nth object in the set. 42 | * 43 | * @method nth 44 | * @param {Number} index Item index 45 | * @return {Element} element, if it exists in the set 46 | */ 47 | nth: function (index) { 48 | return this[index]; 49 | }, 50 | 51 | /** 52 | * Get all the children of all the elements in the set. 53 | * 54 | * @method children 55 | * @return {Collection} DOMinator collection 56 | */ 57 | children: function () { 58 | return toDOMinator(flatten(this.toArray().map(function (element) { 59 | return element.childNodes; 60 | }))); 61 | }, 62 | 63 | /** 64 | * Get the nth child of all the children of all the elements in the set. 65 | * 66 | * @method nthChild 67 | * @param {Number} index Item index 68 | * @return {Element} element, if it exists in the set 69 | */ 70 | nthChild: function (index) { 71 | return this.children()[index]; 72 | }, 73 | 74 | /** 75 | * Find descendent elements. 76 | * 77 | * @method find 78 | * @param {String} selector Selector to match 79 | * @return {Collection} DOMinator collection 80 | */ 81 | find: function (selector) { 82 | return toDOMinator(flatten(this.toArray().map(function (element) { 83 | return element.querySelectorAll(selector); 84 | }))); 85 | }, 86 | 87 | /** 88 | * Find descendent elements and include the root if it. 89 | * matches the selector. 90 | * 91 | * @method findIncludeRoot 92 | * @param {String} selector Selector to match 93 | * @return {Collection} DOMinator collection 94 | */ 95 | findIncludeRoot: function (selector) { 96 | var els = [].slice.call(this.find(selector), 0); 97 | 98 | this.forEach(function (element) { 99 | if (toDOMinator(element).is(selector)) { 100 | // TODO, this is going to put elements on the front in reverse order. 101 | els.unshift(element); 102 | } 103 | }); 104 | 105 | return toDOMinator(els); 106 | }, 107 | 108 | /** 109 | * Check if the first element of the set matches the selector. 110 | * 111 | * @method is 112 | * @param {String} type Selector to match 113 | * @return {Boolean} true if element matches the selector, false otw. 114 | */ 115 | is: function (type) { 116 | if (isEmpty(this)) return false; 117 | 118 | var haystack = toDOMinator(type).toArray(); 119 | return haystack.indexOf(this[0]) > -1; 120 | }, 121 | 122 | /** 123 | * Find the closest ancestor of the first element of the set 124 | * that matches the selector. 125 | * 126 | * @method closest 127 | * @param {String} selector Selector to match 128 | * @return {Element} 129 | */ 130 | closest: function (selector) { 131 | var target = this[0]; 132 | 133 | while (target) { 134 | var chained = toDOMinator(target); 135 | if (chained.is(selector)) return chained; 136 | target = target.parentNode; 137 | } 138 | }, 139 | 140 | /** 141 | * Remove the set of elements from the DOM. 142 | * 143 | * @method remove 144 | */ 145 | remove: function () { 146 | return this.forEach(function (element) { 147 | element.parentNode.removeChild(element); 148 | }); 149 | }, 150 | 151 | /** 152 | * Add a DOM event handler to the set of elements. 153 | * 154 | * @method on 155 | * @param {String} eventName DOM event name 156 | * @param {Function} callback Callback to call 157 | * @param {Boolean} bubble Handle during bubble phase 158 | * @return {Collection} DOMinator collection 159 | */ 160 | on: function (eventName, callback, bubble) { 161 | return this.forEach(function (element) { 162 | element.addEventListener(eventName, callback, bubble); 163 | }); 164 | }, 165 | 166 | 167 | /** 168 | * Add a DOM event handler that is run once. 169 | * 170 | * @method once 171 | * @param {String} eventName DOM event name 172 | * @param {Function} callback Callback to call 173 | * @param {Boolean} bubble Handle during bubble phase 174 | * @return {Collection} DOMinator collection 175 | */ 176 | once: function (eventName, callback, bubble) { 177 | return this.forEach(function (element) { 178 | element.addEventListener(eventName, function handler(event) { 179 | element.removeEventListener(eventName, handler, bubble); 180 | callback(event); 181 | }, bubble); 182 | }); 183 | }, 184 | 185 | /** 186 | * Remove a DOM event handler from the set of elements. 187 | * 188 | * @method off 189 | * @param {String} eventName DOM event name 190 | * @param {Function} callback Callback to call 191 | * @param {Boolean} bubble Handle during bubble phase 192 | * @return {Collection} DOMinator collection 193 | */ 194 | off: function (eventName, callback, bubble) { 195 | return this.forEach(function (element) { 196 | element.removeEventListener(eventName, callback, bubble); 197 | }); 198 | }, 199 | 200 | /** 201 | * Fire a synthetic event on the set of elements. 202 | * 203 | * @method trigger 204 | * @param {String} type Type of event to fire 205 | * @return {Collection} DOMinator collection 206 | */ 207 | trigger: function (type) { 208 | return this.forEach(function (element) { 209 | var event = document.createEvent('CustomEvent'); 210 | event.initCustomEvent(type, true, true, undefined); 211 | element.dispatchEvent(event); 212 | }); 213 | }, 214 | 215 | /** 216 | * Get/Set the innerHTML or value of an element. 217 | * 218 | * @method html 219 | * @param {String} value innerHTML or value 220 | * @return {Collection} DOMinator collection 221 | */ 222 | html: function (value) { 223 | if (arguments.length === 0) { 224 | var target = this[0]; 225 | if (! target) return; 226 | 227 | return target.innerHTML; 228 | } 229 | 230 | return this.forEach(function (element) { 231 | element.innerHTML = value; 232 | }); 233 | }, 234 | 235 | /** 236 | * Get/Set the value of an input/textarea 237 | * 238 | * @method val 239 | * @param {String} value 240 | * @return {Collection} DOMinator collection 241 | */ 242 | val: function (value) { 243 | if (arguments.length === 0) { 244 | var target = this[0]; 245 | if (! target) return; 246 | 247 | if (! isValBased(target)) { 248 | throw new Error('cannot get the value of a non-value based element'); 249 | } 250 | 251 | return target.value; 252 | } 253 | 254 | return this.forEach(function (element) { 255 | if (! isValBased(element)) { 256 | throw new Error('cannot set the value of a non-value based element'); 257 | } 258 | 259 | element.value = value; 260 | }); 261 | }, 262 | 263 | /** 264 | * Remove all children from the set of elements. 265 | * 266 | * @method empty 267 | * @return {Collection} DOMinator collection 268 | */ 269 | empty: function () { 270 | return this.forEach(function (element) { 271 | toDOMinator(element).html(''); 272 | }); 273 | }, 274 | 275 | /** 276 | * Get/Set an attribute on the set of elements. 277 | * 278 | * @method attr 279 | * @param {String} attrName Attribute name 280 | * @param {String} value (optional) attribute value 281 | */ 282 | attr: function (attrName, value) { 283 | if (arguments.length === 1) { 284 | var element = this[0]; 285 | if (! element) return; 286 | return element.getAttribute(attrName); 287 | } 288 | 289 | return this.forEach(function (element) { 290 | element.setAttribute(attrName, value); 291 | }); 292 | }, 293 | 294 | /** 295 | * Check if the first element in the set has an attribute. 296 | * 297 | * @method hasAttr 298 | * @param {String} attrName Attribute name 299 | * @return {Boolean} true if first element in set has the attribute. 300 | */ 301 | hasAttr: function (attrName) { 302 | if (isEmpty(this)) return false; 303 | return !! this[0].hasAttribute(attrName); 304 | }, 305 | 306 | /** 307 | * Remove the attribute from all elements in the set. 308 | * 309 | * @method removeAttr 310 | * @param {String} attrName Attribute name 311 | * @return {Collection} DOMinator collection 312 | */ 313 | removeAttr: function (attrName) { 314 | return this.forEach(function (element) { 315 | element.removeAttribute(attrName); 316 | }); 317 | }, 318 | 319 | /** 320 | * Add a class to all elements in the set. 321 | * 322 | * @method addClass 323 | * @param {String} className Class name 324 | * @return {Collection} DOMinator collection 325 | */ 326 | addClass: function (className) { 327 | return this.forEach(function (element) { 328 | element.classList.add(className); 329 | }); 330 | }, 331 | 332 | /** 333 | * Remove a class from all elements in the set. 334 | * 335 | * @method removeClass 336 | * @param {String} className Class name 337 | * @return {Collection} DOMinator collection 338 | */ 339 | removeClass: function (className) { 340 | return this.forEach(function (element) { 341 | element.classList.remove(className); 342 | }); 343 | }, 344 | 345 | /** 346 | * Check if the first element in the set has a class name. 347 | * 348 | * @method hasClass 349 | * @param {String} className Class name 350 | * @return {Boolean} true if first element has the class name, false otw. 351 | */ 352 | hasClass: function (className) { 353 | if (isEmpty(this)) return false; 354 | return this[0].classList.contains(className); 355 | }, 356 | 357 | /** 358 | * Iterate over the elements. 359 | * 360 | * @method forEach 361 | * @param {Function} iterator Iterator function 362 | * @param {Object} context Context to use when calling `iterator` 363 | * @return {Collection} DOMinator collection 364 | */ 365 | forEach: function (iterator, context) { 366 | [].forEach.call(this, iterator, context); 367 | return this; 368 | }, 369 | 370 | /** 371 | * Run map over the set of elements. 372 | * 373 | * @method map 374 | * @param {Function} iterator Iterator function 375 | * @param {Object} context Context to use when calling `iterator` 376 | * @return {Array} map results 377 | */ 378 | map: function (iterator, context) { 379 | return [].map.call(this, iterator, context); 380 | }, 381 | 382 | /** 383 | * Append an element to all elements in the set. 384 | * 385 | * @method append 386 | * @param {String} elementToAppend HTML or element to append 387 | * @return {Collection} DOMinator collection 388 | */ 389 | append: function (elementToAppend) { 390 | return this.forEach(function (parent) { 391 | toDOMinator(elementToAppend).forEach(function (element) { 392 | parent.appendChild(element); 393 | }); 394 | }); 395 | }, 396 | 397 | /** 398 | * Append the current set of elements to another element. 399 | * 400 | * @method appendTo 401 | * @param {String} elementToAppendTo Element to append to 402 | * @return {Collection} DOMinator collection 403 | */ 404 | appendTo: function (elementToAppendTo) { 405 | var parentNode = toDOMinator(elementToAppendTo)[0]; 406 | if (! parentNode) return; 407 | 408 | return this.forEach(function (element) { 409 | parentNode.appendChild(element); 410 | }); 411 | }, 412 | 413 | /** 414 | * Insert the current set of elements after another element. 415 | * 416 | * @method insertAfter 417 | * @param {String} elementToInsertAfter Element to insert after 418 | * @return {Collection} DOMinator collection 419 | */ 420 | insertAfter: function (elementToInsertAfter) { 421 | var insertAfter = toDOMinator(elementToInsertAfter)[0]; 422 | if (! insertAfter) return; 423 | 424 | var insertBefore = insertAfter.nextChild || null; 425 | var parentNode = insertAfter.parentNode; 426 | 427 | return this.forEach(function (element) { 428 | parentNode.insertBefore(element, insertBefore); 429 | }); 430 | }, 431 | 432 | /** 433 | * Insert the current set of elements before another element. 434 | * 435 | * @method insertBefore 436 | * @param {String} elementToInsertBefore Element to insert before 437 | * @return {Collection} DOMinator collection 438 | */ 439 | insertBefore: function (elementToInsertBefore) { 440 | var insertBefore = toDOMinator(elementToInsertBefore)[0]; 441 | if (! insertBefore) return; 442 | 443 | var parentNode = insertBefore.parentNode; 444 | 445 | return this.forEach(function (element) { 446 | parentNode.insertBefore(element, insertBefore); 447 | }); 448 | }, 449 | 450 | /** 451 | * Insert the current set of elements as the Nth child of another element. 452 | * 453 | * @method insertAsNthChild 454 | * @param {String} parent Parent element 455 | * @param {Number} index Index where to insert 456 | * @return {Collection} DOMinator collection 457 | */ 458 | insertAsNthChild: function (parent, index) { 459 | var nthChild = toDOMinator(parent).nthChild(index); 460 | if (! nthChild) return; 461 | 462 | return this.forEach(function (element) { 463 | nthChild.parentElement.insertBefore(element, nthChild); 464 | }); 465 | }, 466 | 467 | /** 468 | * Focus the first element in the set. 469 | * 470 | * @method focus 471 | * @return {Collection} DOMinator collection 472 | */ 473 | focus: function () { 474 | if (isEmpty(this)) return; 475 | 476 | this[0].focus(); 477 | return this; 478 | }, 479 | 480 | /** 481 | * Show all elements in the set by setting 'display: block'. 482 | * 483 | * @method show 484 | * @return {Collection} DOMinator collection 485 | */ 486 | show: function () { 487 | return this.style('display', 'block'); 488 | }, 489 | 490 | /** 491 | * Hide all elements in the set by setting 'display: none'. 492 | * 493 | * @method hide 494 | * @return {Collection} DOMinator collection 495 | */ 496 | hide: function () { 497 | return this.style('display', 'none'); 498 | }, 499 | 500 | /** 501 | * Set a style on all elements in the set. 502 | * 503 | * @method style 504 | * @param {String} name Style name 505 | * @param {String} value Style value 506 | * @return {Collection} DOMinator collection 507 | */ 508 | style: function (name, value) { 509 | return this.forEach(function (element) { 510 | element.style[name] = value; 511 | }); 512 | }, 513 | 514 | /** 515 | * Convert the set to an Array. 516 | * 517 | * @method toArray 518 | * @return {Array} 519 | */ 520 | toArray: function () { 521 | return [].slice.call(this, 0); 522 | } 523 | }; 524 | 525 | function flatten(array) { 526 | return [].reduce.call(array, function (prevValue, currValue) { 527 | return prevValue.concat([].slice.call(currValue, 0)); 528 | }, []); 529 | } 530 | 531 | function isString(itemToCheck) { 532 | return '[object String]' === Object.prototype.toString.apply(itemToCheck); 533 | } 534 | 535 | function getElements(selector) { 536 | if ( ! selector) return []; 537 | 538 | if (isString(selector)) { 539 | selector = selector.trim(); 540 | if (selector[0] === '<') { 541 | // HTML was specified! Create the elements 542 | var element = document.createElement('div'); 543 | element.innerHTML = selector; 544 | return getElements(element.childNodes); 545 | } 546 | 547 | // Just a normal selector 548 | return getElements(document.querySelectorAll(selector)); 549 | } 550 | 551 | // an array or array-like object, make a copy or convert to an array. 552 | if ('length' in selector) 553 | return [].slice.call(selector, 0); 554 | 555 | return [ selector ]; 556 | } 557 | 558 | function isValBased(target) { 559 | var elName = target.nodeName.toLowerCase(); 560 | return elName === 'input' || elName === 'textarea'; 561 | } 562 | 563 | function isEmpty(dominator) { 564 | return !dominator.length; 565 | } 566 | 567 | function toDOMinator(selector) { 568 | var dom = Object.create(DOMinator); 569 | dom.fill(selector); 570 | return dom; 571 | } 572 | 573 | module.exports = toDOMinator; 574 | // jscs: disable 575 | // jshint ignore:start 576 | });})(typeof define=='function'&&define.amd?define 577 | :(function(n,w){'use strict';return typeof module=='object'?function(c){ 578 | c(require,exports,module);}:function(c){var m={exports:{}};c(function(n){ 579 | return w[n];},m.exports,m);w[n]=m.exports;};})('DOMinator',this)); 580 | // jshint ignore:end 581 | // jscs: enable 582 | 583 | 584 | --------------------------------------------------------------------------------