This app provides monitoring and information features for the common freifunk user and the technical stuff of a freifunk community.
Code base is taken from a TUM Practical Course project and added here to see if Freifunk Altdorf can use it.
https://www.freifunk-altdorf.de
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
194 lines
4.6 KiB
194 lines
4.6 KiB
/* |
|
--- |
|
name : SheetParser.CSS |
|
|
|
authors : Thomas Aylott |
|
copyright : © 2010 Thomas Aylott |
|
license : MIT |
|
|
|
provides : SheetParser.CSS |
|
requires : combineRegExp |
|
... |
|
*/ |
|
;(function(exports){ |
|
|
|
|
|
/*<depend>*/ |
|
var UNDEF = {undefined:1} |
|
if (!exports.SheetParser) exports.SheetParser = {} |
|
|
|
/*<CommonJS>*/ |
|
var combineRegExp = UNDEF[typeof require] |
|
? exports.combineRegExp |
|
: require('./sg-regex-tools').combineRegExp |
|
var SheetParser = exports.SheetParser |
|
/*</CommonJS>*/ |
|
|
|
/*<debug>*/;if (UNDEF[typeof combineRegExp]) throw new Error('Missing required function: "combineRegExp"');/*</debug>*/ |
|
/*</depend>*/ |
|
|
|
|
|
var CSS = SheetParser.CSS = {version: '1.0.2 dev'} |
|
|
|
CSS.trim = trim |
|
function trim(str){ |
|
// http://blog.stevenlevithan.com/archives/faster-trim-javascript |
|
var str = (''+str).replace(/^\s\s*/, ''), |
|
ws = /\s/, |
|
i = str.length; |
|
while (ws.test(str.charAt(--i))); |
|
return str.slice(0, i + 1); |
|
} |
|
|
|
CSS.camelCase = function(string){ |
|
return ('' + string).replace(camelCaseSearch, camelCaseReplace) |
|
} |
|
var camelCaseSearch = /-\D/g |
|
function camelCaseReplace(match){ |
|
return match.charAt(1).toUpperCase() |
|
} |
|
|
|
CSS.parse = function(cssText){ |
|
var found |
|
, rule |
|
, rules = {length:0} |
|
, keyIndex = -1 |
|
, regex = this.parser |
|
, names = CSS.parser.names |
|
, i,r,l |
|
, ruleCount |
|
|
|
rules.cssText = cssText = trim(cssText) |
|
|
|
// strip comments |
|
cssText = cssText.replace(CSS.comment, ''); |
|
|
|
regex.lastIndex = 0 |
|
while ((found = regex.exec(cssText))){ |
|
// avoid an infinite loop on zero-length keys |
|
if (regex.lastIndex == found.index) ++ regex.lastIndex |
|
|
|
// key:value |
|
if (found[names._key]){ |
|
rules[rules.length ++] = found[names._key] |
|
rules[found[names._key]] = found[names._value] |
|
rules[CSS.camelCase(found[names._key])] = found[names._value] |
|
continue |
|
} |
|
|
|
rules[rules.length++] = rule = {} |
|
for (i = 0, l = names.length; i < l; ++i){ |
|
if (!(names[i-1] && found[i])) continue |
|
rule[names[i-1]] = trim(found[i]) |
|
} |
|
} |
|
|
|
var atKey, atRule, atList, atI |
|
for (i = 0, l = rules.length; i < l; ++i){ |
|
if (!rules[i]) continue |
|
|
|
if (rules[i]._style_cssText){ |
|
rules[i].style = CSS.parse(rules[i]._style_cssText) |
|
delete rules[i]._style_cssText |
|
} |
|
|
|
// _atKey/_atValue |
|
if (atKey = rules[i]._atKey){ |
|
atKey = CSS.camelCase(atKey) |
|
atRule = {length:0} |
|
rules[i][atKey] = atRule |
|
atRule["_source"] = |
|
atRule[atKey + "Text"] = rules[i]._atValue |
|
atList = ('' + rules[i]._atValue).split(/,\s*/) |
|
for (atI = 0; atI < atList.length; ++atI){ |
|
atRule[atRule.length ++] = atList[atI] |
|
} |
|
rules[i].length = 1 |
|
rules[i][0] = atKey |
|
delete rules[i]._atKey |
|
delete rules[i]._atValue |
|
} |
|
|
|
if (rules[i].style) |
|
for (ruleCount = -1, r = -1, rule; rule = rules[i].style[++r];){ |
|
if (typeof rule == 'string') continue |
|
rules[i][r] = (rules[i].cssRules || (rules[i].cssRules = {}))[++ ruleCount] = rule |
|
rules[i].cssRules.length = ruleCount + 1 |
|
rules[i].rules = rules[i].cssRules |
|
} |
|
} |
|
|
|
return rules |
|
} |
|
|
|
var x = combineRegExp |
|
var OR = '|' |
|
|
|
;(CSS.at = x(/\s*@([-a-zA-Z0-9]+)\s+(([\w-]+)?[^;{]*)/)) |
|
.names=[ '_atKey', '_atValue', 'name'] |
|
|
|
CSS.atRule = x([CSS.at, ';']) |
|
|
|
;(CSS.keyValue_key = x(/([-a-zA-Z0-9]+)/)) |
|
.names=[ '_key'] |
|
|
|
;(CSS.keyValue_value_end = x(/(?:;|(?=\})|$)/)) |
|
|
|
;(CSS.notString = x(/[^"']+/)) |
|
;(CSS.stringSingle = x(/"(?:[^"]|\\")*"/)) |
|
;(CSS.stringDouble = x(/'(?:[^']|\\')*'/)) |
|
;(CSS.string = x(['(?:',CSS.stringSingle ,OR, CSS.stringDouble,')'])) |
|
;(CSS.propertyValue = x([/[^;}]+/, CSS.keyValue_value_end])) |
|
|
|
var rRound = "(?:[^()]|\\((?:[^()]|\\((?:[^()]|\\((?:[^()]|\\([^()]*\\))*\\))*\\))*\\))" |
|
|
|
;(CSS.keyValue_value = x( |
|
[ |
|
x(['((?:' |
|
, CSS.stringSingle |
|
, OR |
|
, CSS.stringDouble |
|
, OR |
|
, "\\("+rRound+"*\\)" |
|
, OR |
|
, /[^;}()]/ // not a keyValue_value terminator |
|
, ')*)' |
|
]) |
|
, CSS.keyValue_value_end |
|
])).names = ['_value'] |
|
|
|
;(CSS.keyValue = x([CSS.keyValue_key ,/\s*:\s*/, CSS.keyValue_value])) |
|
|
|
;(CSS.comment = x(/\/\*\s*((?:[^*]|\*(?!\/))*)\s*\*\//)) |
|
.names=[ 'comment'] |
|
|
|
;(CSS.selector = x(['(',/\s*(\d+%)\s*/,OR,'(?:',/[^{}'"()]|\([^)]*\)|\[[^\]]*\]/,')+',')'])) |
|
.names=[ 'selectorText','keyText'] |
|
|
|
var rCurly = "(?:[^{}]|\\{(?:[^{}]|\\{(?:[^{}]|\\{(?:[^{}]|\\{[^{}]*\\})*\\})*\\})*\\})" |
|
var rCurlyRound = "(?:[^{}()]+|\\{(?:[^{}()]+|\\{(?:[^{}()]+|\\{(?:[^{}()]+|\\{[^{}()]*\\})*\\})*\\})*\\})" |
|
|
|
;(CSS.block = x("\\{\\s*((?:"+"\\("+rRound+"*\\)|"+rCurly+")*)\\s*\\}")) |
|
.names=[ '_style_cssText'] |
|
|
|
CSS.selectorBlock = x([CSS.selector, CSS.block]) |
|
|
|
CSS.atBlock = x([CSS.at, CSS.block]) |
|
|
|
CSS.parser = x |
|
( |
|
[ x(CSS.comment) |
|
, OR |
|
, x(CSS.atBlock) |
|
, OR |
|
, x(CSS.atRule) |
|
, OR |
|
, x(CSS.selectorBlock) |
|
, OR |
|
, x(CSS.keyValue) |
|
] |
|
, 'cssText' |
|
) |
|
|
|
|
|
})(typeof exports != 'undefined' ? exports : this);
|
|
|