ember-introjs
Version:
An Ember Component for intro.js
197 lines (178 loc) • 4.95 kB
JavaScript
var Attributes = {
display: {
reset : 0,
bright : 1,
dim : 2,
underscore : 4,
blink : 5,
reverse : 7,
hidden : 8
}
, foreground: {
black : 30,
red : 31,
green : 32,
yellow : 33,
blue : 34,
magenta : 35,
cyan : 36,
white : 37
}
, background: {
black : 40,
red : 41,
green : 42,
yellow : 43,
blue : 44,
magenta : 45,
cyan : 46,
white : 47
}
}
function StyledString(str, attrs, children){
if (this.constructor !== StyledString){
return new StyledString(str, attrs, children)
}
this.str = str
this.children = children
this.length = str != null ? str.length : this.childrenLength()
this.attrs = attrs || {}
}
StyledString.prototype.substring = function(){
if (this.str != null){
var str = this.str.substring.apply(this.str, arguments)
return new StyledString(str, this.attrs)
}else{
var startIdx = arguments[0]
var endIdx = arguments[1]
var retval = StyledString('')
var currIdx = 0
this.children.forEach(function(child){
var part
if (startIdx < currIdx + child.length){
part = child.substring(startIdx - currIdx)
}
if (endIdx !== undefined && endIdx < currIdx + child.length){
part = (part || child).substring(0, endIdx - currIdx)
}
if (part){
retval = retval.concat(part)
}
currIdx += child.length
})
return retval
}
}
StyledString.prototype.childrenLength = function(){
return this.children.reduce(function(curr, child){
return curr + child.length
}, 0)
}
StyledString.prototype.substr = StyledString.prototype.substring
StyledString.prototype.match = function(){
return this.str.match.apply(this.str, arguments)
}
StyledString.prototype.concat = function(){
var args = Array.prototype.slice.apply(arguments)
if (this.children){
return StyledString(null, null, this.children.concat(args))
}else{
var children = [this].concat(Array.prototype.slice.apply(args)
.filter(function(s){
return s.length > 0
})
)
return StyledString(null, null, children)
}
}
function copy(src){
var dst = {}
for (var key in src)
dst[key] = src[key]
return dst
}
StyledString.prototype.split = function(){
var args = arguments
if (this.str != null){
var attrs = copy(this.attrs)
return this.str.split.apply(this.str, args).map(function(s){
return StyledString(s, attrs)
})
}else{
return this.children.reduce(function(curr, child){
var results = child.split.apply(child, args)
if (curr.length > 0 && results.length > 0){
var last = curr[curr.length - 1]
curr[curr.length - 1] = last.concat(results[0])
results = results.slice(1)
}
return curr.concat(results)
}, [])
}
}
StyledString.prototype.unstyled = function(){
if (this.str != null){
return this.str
}else{
return this.children.map(function(child){
return child.unstyled()
}).join('')
}
}
StyledString.prototype.applyAttrs = function(str){
for (var key in this.attrs){
if (Attributes[key]){
var code = Attributes[key][this.attrs[key]]
if (code){
str = '\033[' + code + 'm' + str + '\033[0m'
}
}
}
return str
}
StyledString.prototype.toString = function(){
var str
if (this.str != null){
str = this.str
}else{
str = this.children.reduce(function(curr, child){
if (child.length > 0)
return curr + child.toString()
else
return curr
}, '')
}
return this.applyAttrs(str)
}
// Non-string-like methods
StyledString.prototype.append = function(another){
if (this.str != null){
this.children = [StyledString(this.str, this.attrs), another]
this.str = null
this.attrs = {}
this.length = this.childrenLength()
}else{
this.children.push(another)
}
return this
}
StyledString.prototype.attr = function(attrs){
for (var key in attrs){
this.attrs[key] = attrs[key]
}
return this
}
StyledString.prototype.foreground = function(color){
this.attr({foreground: color})
return this
}
StyledString.prototype.background = function(color){
this.attr({background: color})
return this
}
StyledString.prototype.display = function(value){
this.attr({display: value})
return this
}
StyledString.Attributes = Attributes
module.exports = StyledString