├── .gitignore ├── History.md ├── Makefile ├── Readme.md ├── component.json ├── index.js ├── package.json └── test ├── cases.js ├── index.html └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | components 2 | build 3 | node_modules 4 | -------------------------------------------------------------------------------- /History.md: -------------------------------------------------------------------------------- 1 | 2 | 0.2.3 / 2016-03-04 3 | ================== 4 | 5 | * add package.json 6 | 7 | 0.2.2 / 2014-06-19 8 | ================== 9 | 10 | * uniq(el) should return a string selectable with document.querySelector [olivoil] 11 | 12 | 0.2.1 / 2014-05-23 13 | ================== 14 | 15 | * index: Fix attached elements [stephenmathieson] 16 | * test: Fix icons [stephenmathieson] 17 | 18 | 0.2.0 / 2014-05-22 19 | ================== 20 | 21 | * support svg elements, check arrays with arr.join [olivoil] 22 | * add support for [].map(uniq) [olivoil] 23 | 24 | 0.1.0 / 2014-05-19 25 | ================== 26 | 27 | * use component/trim 28 | * add test cases for classNames with trailing spaces [olivoil] 29 | 30 | 0.0.1 / 2013-07-16 31 | ================== 32 | 33 | * Initial commit 34 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | build: components index.js 3 | @component build --dev 4 | 5 | components: component.json 6 | @component install --dev 7 | 8 | clean: 9 | rm -fr build components template.js 10 | 11 | test: 12 | @open test/index.html 13 | 14 | .PHONY: clean test 15 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | 2 | # uniq-selector 3 | 4 | generate a uniq selector of the given element. 5 | 6 | ## Installation 7 | 8 | Install with [component(1)](http://component.io): 9 | 10 | $ component install yields/uniq-selector 11 | 12 | ## API 13 | 14 | #### uniq(el) 15 | 16 | this will continue recursively through the element parents until 17 | it reaches an id or ``. 18 | 19 | see example below. 20 | 21 | ## Example 22 | 23 | ```html 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | ``` 34 | 35 | ```js 36 | var uniq = require('uniq-selector'); 37 | var el = document.querySelector('.baz'); 38 | uniq(el); 39 | // => i#foo.foo.button:nth-child(1) > i:nth-child(1) > i:nth-child(1) > i.baz:nth-child(1) 40 | ``` 41 | 42 | ## Tests 43 | 44 | ```bash 45 | ~ make test 46 | ``` 47 | 48 | ## notes 49 | 50 | if you are interested in this component, please add more tests cases, it's super easy! 51 | 52 | ## License 53 | 54 | MIT 55 | -------------------------------------------------------------------------------- /component.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "uniq-selector", 3 | "remotes": ["https://raw.githubusercontent.com/"], 4 | "repo": "yields/uniq-selector", 5 | "description": "generate a uniq selector of the given element.", 6 | "version": "0.2.3", 7 | "keywords": ["selector", "uniq", "css", "path"], 8 | "license": "MIT", 9 | "main": "index.js", 10 | "scripts": ["index.js"], 11 | "dependencies": { 12 | "yields/indexof": "*", 13 | "component/trim": "*" 14 | }, 15 | "development": { 16 | "visionmedia/mocha": "*", 17 | "component/assert": "*", 18 | "component/domify": "*" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var index = require('indexof'); 7 | var trim = require('trim'); 8 | 9 | /** 10 | * Export `uniq` 11 | */ 12 | 13 | module.exports = uniq; 14 | 15 | /** 16 | * Generate unique selector of `el`. 17 | * 18 | * @param {Element} el 19 | * @return {String} 20 | * @api public 21 | */ 22 | 23 | function uniq(el, arr){ 24 | arr = arr && arr.join ? arr : []; 25 | if (!el) return arr.join(' > '); 26 | if (9 == el.nodeType) return arr.join(' > '); 27 | if (1 != el.nodeType) return arr.join(' > '); 28 | arr.unshift(selector(el)); 29 | if (el.id) return arr.join(' > '); 30 | return uniq(el.parentNode, arr); 31 | } 32 | 33 | /** 34 | * Generate a selector of the given `el`. 35 | * 36 | * @param {Element} el 37 | * @return {String} 38 | * @api private 39 | */ 40 | 41 | function selector(el){ 42 | var classname = trim(el.className.baseVal ? el.className.baseVal : el.className); 43 | var i = el.parentNode && 9 == el.parentNode.nodeType ? -1 : index(el); 44 | 45 | return el.tagName.toLowerCase() 46 | + (el.id ? '#' + el.id : '') 47 | + (classname ? classname.replace(/^| +/g, '.') : '') 48 | + (~i ? ':nth-child(' + (i + 1) + ')' : ''); 49 | } 50 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "uniq-selector", 3 | "version": "0.2.3", 4 | "description": "generate a uniq selector of the given element.", 5 | "main": "index.js", 6 | "directories": { 7 | "test": "test" 8 | }, 9 | "scripts": { 10 | "test": "make test" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/yields/uniq-selector.git" 15 | }, 16 | "keywords": [ 17 | "selector", 18 | "uniq", 19 | "css", 20 | "path" 21 | ], 22 | "author": "yields", 23 | "license": "MIT", 24 | "bugs": { 25 | "url": "https://github.com/yields/uniq-selector/issues" 26 | }, 27 | "homepage": "https://github.com/yields/uniq-selector#readme", 28 | "dependencies": { 29 | "indexof-element": "1.0.1", 30 | "trim": "0.0.1" 31 | }, 32 | "browser": { 33 | "indexof": "indexof-element" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /test/cases.js: -------------------------------------------------------------------------------- 1 | 2 | // cases 3 | 4 | var cases = []; 5 | 6 | // simple 7 | 8 | cases.push({ 9 | element: '', 10 | of: '

', 11 | expect: 'p > i:nth-child(1)', 12 | selector: 'i' 13 | }); 14 | 15 | // list 16 | 17 | cases.push({ 18 | element: '
  • ', 19 | of: '', 20 | expect: 'ul > li:nth-child(2)', 21 | selector: 'li:nth-child(2)' 22 | }); 23 | 24 | // complex 25 | 26 | cases.push({ 27 | element: '', 28 | of: '', 29 | expect: 'i#foo.foo.button:nth-child(1) > i:nth-child(1) > i:nth-child(1) > i.baz:nth-child(1)', 30 | selector: '.baz' 31 | }); 32 | 33 | // with trailing space in className 34 | 35 | cases.push({ 36 | element: '', 37 | of: '

    ', 38 | expect: 'p.foo.bar > i:nth-child(1)', 39 | selector: 'i' 40 | }); 41 | 42 | // works on svg elements 43 | 44 | cases.push({ 45 | element: '', 46 | of: '

    ', 47 | expect: 'div > svg.foo.bar:nth-child(1)', 48 | selector: 'svg' 49 | }); 50 | -------------------------------------------------------------------------------- /test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | uniq-selector 6 | 7 | 8 | 9 | 10 | 11 | 12 |
    13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | 2 | var domify = require('domify') 3 | var uniq = require('uniq-selector'); 4 | var assert = require('assert'); 5 | 6 | cases.forEach(function(test){ 7 | describe('uniq(' + test.element + ')', function(){ 8 | it('should return "' + test.expect + '" of "' + test.of + '"', function(){ 9 | var html = domify(test.of); 10 | var el = html.querySelector(test.selector); 11 | var ret = uniq(el); 12 | assert(test.expect == ret, 'expected "' + test.expect + '" got "' + ret + '"'); 13 | assert(el == html.querySelector(ret), 'expected "' + ret + '" to get "' + test.element + '"'); 14 | }) 15 | }) 16 | 17 | describe('[' + test.element + '].map(uniq)', function(){ 18 | it('should return "' + test.expect + '" of "' + test.of + '"', function(){ 19 | var html = domify(test.of); 20 | var els = [].slice.call(html.querySelectorAll(test.selector)); 21 | var ret = els.map(uniq)[0]; 22 | assert(test.expect == ret, 'expected "' + test.expect + '" got "' + ret + '"'); 23 | assert(els[0] == html.querySelector(ret), 'expected "' + ret + '" to get "' + test.element + '"'); 24 | }) 25 | }); 26 | }) 27 | 28 | describe('uniq(attached element)', function(){ 29 | it('should work', function(){ 30 | var el = document.createElement('div'); 31 | document.body.appendChild(el); 32 | uniq(el); 33 | }) 34 | }); 35 | 36 | describe('document.querySelector(uniq(el))', function(){ 37 | it('should return a selectable string', function(){ 38 | var el = document.createElement('div'); 39 | document.body.appendChild(el); 40 | var found = document.querySelector(uniq(el)); 41 | assert(found, 'document.querySelector(uniq(el)) did not return `el`.'); 42 | el.parentNode.removeChild(el); 43 | }) 44 | }); 45 | --------------------------------------------------------------------------------