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.
362 lines
7.5 KiB
362 lines
7.5 KiB
//.CommonJS |
|
var CSSOM = { |
|
CSSStyleSheet: require("./CSSStyleSheet").CSSStyleSheet, |
|
CSSStyleRule: require("./CSSStyleRule").CSSStyleRule, |
|
CSSImportRule: require("./CSSImportRule").CSSImportRule, |
|
CSSMediaRule: require("./CSSMediaRule").CSSMediaRule |
|
}; |
|
///CommonJS |
|
|
|
|
|
CSSOM.Parser = function Parser() {}; |
|
|
|
/** |
|
* @param {string} cssText |
|
* @param {Object} options |
|
*/ |
|
CSSOM.Parser.prototype.parseStyleSheet = function(cssText, options) { |
|
options = options || {}; |
|
var i = options.startIndex || 0; |
|
|
|
for (var character; character = token.charAt(i); i++) { |
|
switch (character) { |
|
|
|
case " ": |
|
case "\t": |
|
case "\r": |
|
case "\n": |
|
case "\f": |
|
if (SIGNIFICANT_WHITESPACE[state]) { |
|
buffer += character; |
|
} |
|
break; |
|
} |
|
}; |
|
|
|
CSSOM.Parser.prototype.parse = function(token, options) { |
|
|
|
options = options || {}; |
|
var i = options.startIndex || 0; |
|
|
|
this.styleSheetStart(i); |
|
|
|
/** |
|
"before-selector" or |
|
"selector" or |
|
"atRule" or |
|
"atBlock" or |
|
"before-name" or |
|
"name" or |
|
"before-value" or |
|
"value" |
|
*/ |
|
var state = options.state || "before-selector"; |
|
|
|
var index; |
|
var j = i; |
|
var buffer = ""; |
|
|
|
var SIGNIFICANT_WHITESPACE = { |
|
"selector": true, |
|
"value": true, |
|
"atRule": true, |
|
"importRule-begin": true, |
|
"importRule": true, |
|
"atBlock": true |
|
}; |
|
|
|
var styleSheet = new CSSOM.CSSStyleSheet; |
|
|
|
// @type CSSStyleSheet|CSSMediaRule |
|
var currentScope = styleSheet; |
|
|
|
var selector, name, value, priority="", styleRule, mediaRule, importRule; |
|
|
|
var declarationStarts; |
|
var declarationEnds; |
|
|
|
for (var character; character = token.charAt(i); i++) { |
|
|
|
switch (character) { |
|
|
|
case " ": |
|
case "\t": |
|
case "\r": |
|
case "\n": |
|
case "\f": |
|
if (SIGNIFICANT_WHITESPACE[state]) { |
|
buffer += character; |
|
} |
|
break; |
|
|
|
// String |
|
case '"': |
|
j = i + 1; |
|
index = token.indexOf('"', j) + 1; |
|
if (!index) { |
|
throw '" is missing'; |
|
} |
|
buffer += token.slice(i, index); |
|
i = index - 1; |
|
if (state == 'before-value') { |
|
state = 'value'; |
|
} |
|
break; |
|
|
|
case "'": |
|
j = i + 1; |
|
index = token.indexOf("'", j) + 1; |
|
if (!index) { |
|
throw "' is missing"; |
|
} |
|
buffer += token.slice(i, index); |
|
i = index - 1; |
|
switch (state) { |
|
case 'before-value': |
|
state = 'value'; |
|
break; |
|
case 'importRule-begin': |
|
state = 'importRule'; |
|
break; |
|
} |
|
break; |
|
|
|
// Comment |
|
case "/": |
|
if (token.charAt(i + 1) == "*") { |
|
i += 2; |
|
index = token.indexOf("*/", i); |
|
if (index == -1) { |
|
throw SyntaxError("Missing */"); |
|
} else { |
|
i = index + 1; |
|
} |
|
} else { |
|
buffer += character; |
|
} |
|
if (state == "importRule-begin") { |
|
buffer += " "; |
|
state = "importRule"; |
|
} |
|
break; |
|
|
|
// At-rule |
|
case "@": |
|
if (token.indexOf("@media", i) == i) { |
|
state = "atBlock"; |
|
mediaRule = new CSSOM.CSSMediaRule; |
|
mediaRule.__starts = i; |
|
i += "media".length; |
|
buffer = ""; |
|
break; |
|
} else if (token.indexOf("@import", i) == i) { |
|
state = "importRule-begin"; |
|
i += "import".length; |
|
buffer += "@import"; |
|
break; |
|
} else if (state == "selector") { |
|
state = "atRule"; |
|
} |
|
buffer += character; |
|
break; |
|
|
|
case "{": |
|
if (state == "selector" || state == "atRule") { |
|
this.selectorEnd(i, buffer); |
|
buffer = ""; |
|
state = "before-name"; |
|
} else if (state == "atBlock") { |
|
mediaRule.media.mediaText = buffer.trim(); |
|
currentScope = mediaRule; |
|
buffer = ""; |
|
state = "before-selector"; |
|
} |
|
break; |
|
|
|
case ":": |
|
if (state == "name") { |
|
name = buffer; |
|
buffer = ""; |
|
state = "before-value"; |
|
} else { |
|
buffer += character; |
|
} |
|
break; |
|
|
|
case '(': |
|
if (state == 'value') { |
|
index = token.indexOf(')', i + 1); |
|
if (index == -1) { |
|
throw i + ': unclosed "("'; |
|
} |
|
buffer += token.slice(i, index + 1); |
|
i = index; |
|
} else { |
|
buffer += character; |
|
} |
|
break; |
|
|
|
case "!": |
|
if (state == "value" && token.indexOf("!important", i) === i) { |
|
priority = "important"; |
|
i += "important".length; |
|
} else { |
|
buffer += character; |
|
} |
|
break; |
|
|
|
case ";": |
|
switch (state) { |
|
case "value": |
|
this.declarationEnd(i, name, buffer, priority); |
|
priority = ""; |
|
buffer = ""; |
|
state = "before-name"; |
|
break; |
|
case "atRule": |
|
buffer = ""; |
|
state = "before-selector"; |
|
break; |
|
case "importRule": |
|
importRule = new CSSOM.CSSImportRule; |
|
importRule.cssText = buffer + character; |
|
currentScope.cssRules.push(importRule); |
|
buffer = ""; |
|
state = "before-selector"; |
|
break; |
|
default: |
|
buffer += character; |
|
break; |
|
} |
|
break; |
|
|
|
case "}": |
|
switch (state) { |
|
case "value": |
|
this.declarationEnd(i, name, buffer, priority); |
|
// fall down |
|
case "before-name": |
|
this.styleRuleEnd(i); |
|
buffer = ""; |
|
break; |
|
case "name": |
|
throw i + ": Oops"; |
|
break; |
|
case "before-selector": |
|
case "selector": |
|
// End of media rule. |
|
// Nesting rules aren't supported yet |
|
if (!mediaRule) { |
|
throw "unexpected }"; |
|
} |
|
mediaRule.__ends = i + 1; |
|
styleSheet.cssRules.push(mediaRule); |
|
currentScope = styleSheet; |
|
buffer = ""; |
|
break; |
|
} |
|
state = "before-selector"; |
|
break; |
|
|
|
default: |
|
switch (state) { |
|
case "before-selector": |
|
this.styleRuleStart(i); |
|
state = "selector"; |
|
break; |
|
case "before-name": |
|
state = "name"; |
|
break; |
|
case "before-value": |
|
state = "value"; |
|
break; |
|
case "importRule-begin": |
|
state = "importRule"; |
|
break; |
|
} |
|
buffer += character; |
|
break; |
|
} |
|
} |
|
|
|
return styleSheet; |
|
}; |
|
|
|
CSSOM.Parser.prototype.compile = function() { |
|
var handlers = { |
|
styleSheetStart: this.styleSheetStart, |
|
styleRuleStart: this.styleRuleStart, |
|
selectorEnd: this.selectorEnd, |
|
declarationEnd: this.declarationEnd, |
|
styleRuleEnd: this.styleRuleEnd, |
|
styleSheetEnd: this.styleSheetEnd |
|
}; |
|
var parser = this.parse.toString(); |
|
for (var key in handlers) { |
|
if (!handlers.hasOwnProperty(key)) { |
|
continue; |
|
} |
|
parser = parser.replace(new RegExp('^.*' + key + '.*$', 'gm'), handlers[key].toString() |
|
.replace(/^function.+$/m, '') |
|
.replace(/^}/m, '')) |
|
.replace(/this\.?/g, ''); |
|
} |
|
return parser; |
|
}; |
|
|
|
CSSOM.Parser.prototype.styleSheetStart = function(i) { |
|
console.log('styleSheetStart', i); |
|
this.styleSheet = new CSSOM.CSSStyleSheet; |
|
this.scopeRules = this.styleSheet.cssRules; |
|
}; |
|
|
|
CSSOM.Parser.prototype.styleRuleStart = function(i) { |
|
console.log('styleRuleStart', i); |
|
this.styleRule = new CSSOM.CSSStyleRule; |
|
this.styleRule._start = i; |
|
}; |
|
|
|
CSSOM.Parser.prototype.selectorEnd = function(i, buffer) { |
|
this.styleRule.selectorText = buffer.trimRight(); |
|
this.styleRule.style._start = i; |
|
}; |
|
|
|
CSSOM.Parser.prototype.declarationEnd = function(name, value, priority, startIndex, endIndex) { |
|
console.log('declarationEnd', name, value, priority, startIndex, endIndex); |
|
}; |
|
|
|
CSSOM.Parser.prototype.styleRuleEnd = function(i) { |
|
this.styleRule._end = i; |
|
this.scopeRules.push(this.styleRule); |
|
}; |
|
|
|
|
|
CSSOM.Parser.prototype.styleSheetEnd = function(i) { |
|
return this.styleSheet; |
|
}; |
|
|
|
/* |
|
Parser.prototype.nameStart = function(i) { |
|
this.nameStartIndex = i; |
|
}; |
|
|
|
Parser.prototype.nameEnd = function(i, buffer) { |
|
this.name = buffer.trimRight(); |
|
this.nameEndIndex = this.nameStartIndex + this.name.length; |
|
}; |
|
|
|
|
|
Parser.prototype.valueStart = function(i) { |
|
this.valueStartIndex = i; |
|
}; |
|
|
|
Parser.prototype.valueEnd = function(i, buffer) { |
|
var value = buffer.trimRight(); |
|
this.styleRule.style.add(this.name, value, this.nameStartIndex, this.nameEndIndex, this.valueStartIndex, this.valueStartIndex + value.length); |
|
}; |
|
*/ |
|
|
|
|
|
//.CommonJS |
|
exports.Parser = CSSOM.Parser; |
|
///CommonJS
|