forked from RadLikeWhoa/Countable
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathCountable.js
More file actions
112 lines (93 loc) · 3.36 KB
/
Copy pathCountable.js
File metadata and controls
112 lines (93 loc) · 3.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/**
* Countable is a script to allow for live paragraph-, word- and character-
* counting on an HTML element. Usage is recommended on `input` and `textarea`
* elements.
*
* @author Sacha Schmid (http://github.com/RadLikeWhoa)
* @version 1.1.1
* @license MIT
*/
;(function () {
'use strict';
/**
* String.trim() polyfill for non-supporting browsers.
*
* @return {String} The original string with leading and trailing
* whitespace removed.
*/
if (typeof String.prototype.trim !== 'function') {
String.prototype.trim = function () {
return this.replace(/^\s+|\s+$/g, '');
};
}
/**
* Create a new Countable instance on an HTML element.
*
* @constructor
*
* @param {HTMLElement} element The element to be used for the
* counting.
* @param {Function} [callback] The callback to receive and process
* the result. The callback should
* accept only one parameter. (default:
* logs to console)
* @param {Boolean} [hard] Sets whether to use hard returns (2
* line breaks) or not. (default: false)
*
* @example new Countable(elem, function (counter) {
* alert(counter.paragraphs, counter.words, counter.characters);
* });
*
* @return {Countable} An instance of the Countable class.
*/
var _ = window.Countable = function (element, callback, hard) {
/**
* Expect a valid HTMLElement. If no element or an invalid value is given,
* Countable returns nothing.
*/
if (!element || element.nodeType !== 1) return;
this.element = element;
this.callback = typeof callback === 'function' ? callback : function (counter) {
if (typeof console !== 'undefined') console.log(counter);
};
this.hard = hard;
this.init();
return this;
};
_.prototype = {
/**
* Trim leading and trailing whitespace and count paragraphs, words and
* characters.
*
* @return {Object} The object containing the number of paragraphs, words
* and characters, all accessible by their names.
*/
count: function () {
var orig = (this.element.value || this.element.innerText || this.element.textContent || ''),
str = orig.trim();
return {
paragraphs: str ? (str.match(this.hard ? /\n{2,}/g : /\n+/g) || []).length + 1 : 0,
words: str ? (str.replace(/\s['";:,.?¿\-!¡]/g, '').match(/\s+/g) || []).length + 1 : 0,
characters: str ? str.replace(/\s/g, '').length : 0,
all: orig.replace(/[\n\r]/g, '').length
};
},
/**
* Initiate the Countable object by calling the `count()` function and
* adding the `input` event listener to the given element.
*/
init: function () {
var self = this;
self.callback(self.count());
if (typeof self.element.addEventListener !== 'undefined') {
self.element.addEventListener('input', function () {
self.callback(self.count());
});
} else if (typeof self.element.attachEvent !== 'undefined') {
self.element.attachEvent('onkeydown', function () {
self.callback(self.count());
});
}
}
};
}());