"no use strict"; !(function(window) { if (typeof window.window != "undefined" && window.document) return; if (window.require && window.define) return; if (!window.console) { window.console = function() { var msgs = Array.prototype.slice.call(arguments, 0); postMessage({type: "log", data: msgs}); }; window.console.error = window.console.warn = window.console.log = window.console.trace = window.console; } window.window = window; window.ace = window; window.onerror = function(message, file, line, col, err) { postMessage({type: "error", data: { message: message, data: err && err.data, file: file, line: line, col: col, stack: err && err.stack }}); }; window.normalizeModule = function(parentId, moduleName) { // normalize plugin requires if (moduleName.indexOf("!") !== -1) { var chunks = moduleName.split("!"); return window.normalizeModule(parentId, chunks[0]) + "!" + window.normalizeModule(parentId, chunks[1]); } // normalize relative requires if (moduleName.charAt(0) == ".") { var base = parentId.split("/").slice(0, -1).join("/"); moduleName = (base ? base + "/" : "") + moduleName; while (moduleName.indexOf(".") !== -1 && previous != moduleName) { var previous = moduleName; moduleName = moduleName.replace(/^\.\//, "").replace(/\/\.\//, "/").replace(/[^\/]+\/\.\.\//, ""); } } return moduleName; }; window.require = function require(parentId, id) { if (!id) { id = parentId; parentId = null; } if (!id.charAt) throw new Error("worker.js require() accepts only (parentId, id) as arguments"); id = window.normalizeModule(parentId, id); var module = window.require.modules[id]; if (module) { if (!module.initialized) { module.initialized = true; module.exports = module.factory().exports; } return module.exports; } if (!window.require.tlns) return console.log("unable to load " + id); var path = resolveModuleId(id, window.require.tlns); if (path.slice(-3) != ".js") path += ".js"; window.require.id = id; window.require.modules[id] = {}; // prevent infinite loop on broken modules importScripts(path); return window.require(parentId, id); }; function resolveModuleId(id, paths) { var testPath = id, tail = ""; while (testPath) { var alias = paths[testPath]; if (typeof alias == "string") { return alias + tail; } else if (alias) { return alias.location.replace(/\/*$/, "/") + (tail || alias.main || alias.name); } else if (alias === false) { return ""; } var i = testPath.lastIndexOf("/"); if (i === -1) break; tail = testPath.substr(i) + tail; testPath = testPath.slice(0, i); } return id; } window.require.modules = {}; window.require.tlns = {}; window.define = function(id, deps, factory) { if (arguments.length == 2) { factory = deps; if (typeof id != "string") { deps = id; id = window.require.id; } } else if (arguments.length == 1) { factory = id; deps = []; id = window.require.id; } if (typeof factory != "function") { window.require.modules[id] = { exports: factory, initialized: true }; return; } if (!deps.length) // If there is no dependencies, we inject "require", "exports" and // "module" as dependencies, to provide CommonJS compatibility. deps = ["require", "exports", "module"]; var req = function(childId) { return window.require(id, childId); }; window.require.modules[id] = { exports: {}, factory: function() { var module = this; var returnExports = factory.apply(this, deps.slice(0, factory.length).map(function(dep) { switch (dep) { // Because "require", "exports" and "module" aren't actual // dependencies, we must handle them seperately. case "require": return req; case "exports": return module.exports; case "module": return module; // But for all other dependencies, we can just go ahead and // require them. default: return req(dep); } })); if (returnExports) module.exports = returnExports; return module; } }; }; window.define.amd = {}; window.require.tlns = {}; window.initBaseUrls = function initBaseUrls(topLevelNamespaces) { for (var i in topLevelNamespaces) this.require.tlns[i] = topLevelNamespaces[i]; }; window.initSender = function initSender() { var EventEmitter = window.require("ace/lib/event_emitter").EventEmitter; var oop = window.require("ace/lib/oop"); var Sender = function() {}; (function() { oop.implement(this, EventEmitter); this.callback = function(data, callbackId) { postMessage({ type: "call", id: callbackId, data: data }); }; this.emit = function(name, data) { postMessage({ type: "event", name: name, data: data }); }; }).call(Sender.prototype); return new Sender(); }; var main = window.main = null; var sender = window.sender = null; window.onmessage = function(e) { var msg = e.data; if (msg.event && sender) { sender._signal(msg.event, msg.data); } else if (msg.command) { if (main[msg.command]) main[msg.command].apply(main, msg.args); else if (window[msg.command]) window[msg.command].apply(window, msg.args); else throw new Error("Unknown command:" + msg.command); } else if (msg.init) { window.initBaseUrls(msg.tlns); sender = window.sender = window.initSender(); var clazz = this.require(msg.module)[msg.classname]; main = window.main = new clazz(sender); } }; })(this); define("ace/lib/oop",[], function(require, exports, module){"use strict"; exports.inherits = function (ctor, superCtor) { ctor.super_ = superCtor; ctor.prototype = Object.create(superCtor.prototype, { constructor: { value: ctor, enumerable: false, writable: true, configurable: true } }); }; exports.mixin = function (obj, mixin) { for (var key in mixin) { obj[key] = mixin[key]; } return obj; }; exports.implement = function (proto, mixin) { exports.mixin(proto, mixin); }; }); define("ace/lib/deep_copy",[], function(require, exports, module){exports.deepCopy = function deepCopy(obj) { if (typeof obj !== "object" || !obj) return obj; var copy; if (Array.isArray(obj)) { copy = []; for (var key = 0; key < obj.length; key++) { copy[key] = deepCopy(obj[key]); } return copy; } if (Object.prototype.toString.call(obj) !== "[object Object]") return obj; copy = {}; for (var key in obj) copy[key] = deepCopy(obj[key]); return copy; }; }); define("ace/lib/lang",[], function(require, exports, module){"use strict"; exports.last = function (a) { return a[a.length - 1]; }; exports.stringReverse = function (string) { return string.split("").reverse().join(""); }; exports.stringRepeat = function (string, count) { var result = ''; while (count > 0) { if (count & 1) result += string; if (count >>= 1) string += string; } return result; }; var trimBeginRegexp = /^\s\s*/; var trimEndRegexp = /\s\s*$/; exports.stringTrimLeft = function (string) { return string.replace(trimBeginRegexp, ''); }; exports.stringTrimRight = function (string) { return string.replace(trimEndRegexp, ''); }; exports.copyObject = function (obj) { var copy = {}; for (var key in obj) { copy[key] = obj[key]; } return copy; }; exports.copyArray = function (array) { var copy = []; for (var i = 0, l = array.length; i < l; i++) { if (array[i] && typeof array[i] == "object") copy[i] = this.copyObject(array[i]); else copy[i] = array[i]; } return copy; }; exports.deepCopy = require("./deep_copy").deepCopy; exports.arrayToMap = function (arr) { var map = {}; for (var i = 0; i < arr.length; i++) { map[arr[i]] = 1; } return map; }; exports.createMap = function (props) { var map = Object.create(null); for (var i in props) { map[i] = props[i]; } return map; }; exports.arrayRemove = function (array, value) { for (var i = 0; i <= array.length; i++) { if (value === array[i]) { array.splice(i, 1); } } }; exports.escapeRegExp = function (str) { return str.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1'); }; exports.escapeHTML = function (str) { return ("" + str).replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'").replace(/</g, "<"); }; exports.getMatchOffsets = function (string, regExp) { var matches = []; string.replace(regExp, function (str) { matches.push({ offset: arguments[arguments.length - 2], length: str.length }); }); return matches; }; exports.deferredCall = function (fcn) { var timer = null; var callback = function () { timer = null; fcn(); }; var deferred = function (timeout) { deferred.cancel(); timer = setTimeout(callback, timeout || 0); return deferred; }; deferred.schedule = deferred; deferred.call = function () { this.cancel(); fcn(); return deferred; }; deferred.cancel = function () { clearTimeout(timer); timer = null; return deferred; }; deferred.isPending = function () { return timer; }; return deferred; }; exports.delayedCall = function (fcn, defaultTimeout) { var timer = null; var callback = function () { timer = null; fcn(); }; var _self = function (timeout) { if (timer == null) timer = setTimeout(callback, timeout || defaultTimeout); }; _self.delay = function (timeout) { timer && clearTimeout(timer); timer = setTimeout(callback, timeout || defaultTimeout); }; _self.schedule = _self; _self.call = function () { this.cancel(); fcn(); }; _self.cancel = function () { timer && clearTimeout(timer); timer = null; }; _self.isPending = function () { return timer; }; return _self; }; exports.supportsLookbehind = function () { try { new RegExp('(?<=.)'); } catch (e) { return false; } return true; }; exports.skipEmptyMatch = function (line, last, supportsUnicodeFlag) { return supportsUnicodeFlag && line.codePointAt(last) > 0xffff ? 2 : 1; }; }); define("ace/apply_delta",[], function(require, exports, module){"use strict"; function throwDeltaError(delta, errorText) { console.log("Invalid Delta:", delta); throw "Invalid Delta: " + errorText; } function positionInDocument(docLines, position) { return position.row >= 0 && position.row < docLines.length && position.column >= 0 && position.column <= docLines[position.row].length; } function validateDelta(docLines, delta) { if (delta.action != "insert" && delta.action != "remove") throwDeltaError(delta, "delta.action must be 'insert' or 'remove'"); if (!(delta.lines instanceof Array)) throwDeltaError(delta, "delta.lines must be an Array"); if (!delta.start || !delta.end) throwDeltaError(delta, "delta.start/end must be an present"); var start = delta.start; if (!positionInDocument(docLines, delta.start)) throwDeltaError(delta, "delta.start must be contained in document"); var end = delta.end; if (delta.action == "remove" && !positionInDocument(docLines, end)) throwDeltaError(delta, "delta.end must contained in document for 'remove' actions"); var numRangeRows = end.row - start.row; var numRangeLastLineChars = (end.column - (numRangeRows == 0 ? start.column : 0)); if (numRangeRows != delta.lines.length - 1 || delta.lines[numRangeRows].length != numRangeLastLineChars) throwDeltaError(delta, "delta.range must match delta lines"); } exports.applyDelta = function (docLines, delta, doNotValidate) { var row = delta.start.row; var startColumn = delta.start.column; var line = docLines[row] || ""; switch (delta.action) { case "insert": var lines = delta.lines; if (lines.length === 1) { docLines[row] = line.substring(0, startColumn) + delta.lines[0] + line.substring(startColumn); } else { var args = [row, 1].concat(delta.lines); docLines.splice.apply(docLines, args); docLines[row] = line.substring(0, startColumn) + docLines[row]; docLines[row + delta.lines.length - 1] += line.substring(startColumn); } break; case "remove": var endColumn = delta.end.column; var endRow = delta.end.row; if (row === endRow) { docLines[row] = line.substring(0, startColumn) + line.substring(endColumn); } else { docLines.splice(row, endRow - row + 1, line.substring(0, startColumn) + docLines[endRow].substring(endColumn)); } break; } }; }); define("ace/lib/event_emitter",[], function(require, exports, module){"use strict"; var EventEmitter = {}; var stopPropagation = function () { this.propagationStopped = true; }; var preventDefault = function () { this.defaultPrevented = true; }; EventEmitter._emit = EventEmitter._dispatchEvent = function (eventName, e) { this._eventRegistry || (this._eventRegistry = {}); this._defaultHandlers || (this._defaultHandlers = {}); var listeners = this._eventRegistry[eventName] || []; var defaultHandler = this._defaultHandlers[eventName]; if (!listeners.length && !defaultHandler) return; if (typeof e != "object" || !e) e = {}; if (!e.type) e.type = eventName; if (!e.stopPropagation) e.stopPropagation = stopPropagation; if (!e.preventDefault) e.preventDefault = preventDefault; listeners = listeners.slice(); for (var i = 0; i < listeners.length; i++) { listeners[i](e, this); if (e.propagationStopped) break; } if (defaultHandler && !e.defaultPrevented) return defaultHandler(e, this); }; EventEmitter._signal = function (eventName, e) { var listeners = (this._eventRegistry || {})[eventName]; if (!listeners) return; listeners = listeners.slice(); for (var i = 0; i < listeners.length; i++) listeners[i](e, this); }; EventEmitter.once = function (eventName, callback) { var _self = this; this.on(eventName, function newCallback() { _self.off(eventName, newCallback); callback.apply(null, arguments); }); if (!callback) { return new Promise(function (resolve) { callback = resolve; }); } }; EventEmitter.setDefaultHandler = function (eventName, callback) { var handlers = this._defaultHandlers; if (!handlers) handlers = this._defaultHandlers = { _disabled_: {} }; if (handlers[eventName]) { var old = handlers[eventName]; var disabled = handlers._disabled_[eventName]; if (!disabled) handlers._disabled_[eventName] = disabled = []; disabled.push(old); var i = disabled.indexOf(callback); if (i != -1) disabled.splice(i, 1); } handlers[eventName] = callback; }; EventEmitter.removeDefaultHandler = function (eventName, callback) { var handlers = this._defaultHandlers; if (!handlers) return; var disabled = handlers._disabled_[eventName]; if (handlers[eventName] == callback) { if (disabled) this.setDefaultHandler(eventName, disabled.pop()); } else if (disabled) { var i = disabled.indexOf(callback); if (i != -1) disabled.splice(i, 1); } }; EventEmitter.on = EventEmitter.addEventListener = function (eventName, callback, capturing) { this._eventRegistry = this._eventRegistry || {}; var listeners = this._eventRegistry[eventName]; if (!listeners) listeners = this._eventRegistry[eventName] = []; if (listeners.indexOf(callback) == -1) listeners[capturing ? "unshift" : "push"](callback); return callback; }; EventEmitter.off = EventEmitter.removeListener = EventEmitter.removeEventListener = function (eventName, callback) { this._eventRegistry = this._eventRegistry || {}; var listeners = this._eventRegistry[eventName]; if (!listeners) return; var index = listeners.indexOf(callback); if (index !== -1) listeners.splice(index, 1); }; EventEmitter.removeAllListeners = function (eventName) { if (!eventName) this._eventRegistry = this._defaultHandlers = undefined; if (this._eventRegistry) this._eventRegistry[eventName] = undefined; if (this._defaultHandlers) this._defaultHandlers[eventName] = undefined; }; exports.EventEmitter = EventEmitter; }); define("ace/range",[], function(require, exports, module){"use strict"; var Range = /** @class */ (function () { function Range(startRow, startColumn, endRow, endColumn) { this.start = { row: startRow, column: startColumn }; this.end = { row: endRow, column: endColumn }; } Range.prototype.isEqual = function (range) { return this.start.row === range.start.row && this.end.row === range.end.row && this.start.column === range.start.column && this.end.column === range.end.column; }; Range.prototype.toString = function () { return ("Range: [" + this.start.row + "/" + this.start.column + "] -> [" + this.end.row + "/" + this.end.column + "]"); }; Range.prototype.contains = function (row, column) { return this.compare(row, column) == 0; }; Range.prototype.compareRange = function (range) { var cmp, end = range.end, start = range.start; cmp = this.compare(end.row, end.column); if (cmp == 1) { cmp = this.compare(start.row, start.column); if (cmp == 1) { return 2; } else if (cmp == 0) { return 1; } else { return 0; } } else if (cmp == -1) { return -2; } else { cmp = this.compare(start.row, start.column); if (cmp == -1) { return -1; } else if (cmp == 1) { return 42; } else { return 0; } } }; Range.prototype.comparePoint = function (p) { return this.compare(p.row, p.column); }; Range.prototype.containsRange = function (range) { return this.comparePoint(range.start) == 0 && this.comparePoint(range.end) == 0; }; Range.prototype.intersects = function (range) { var cmp = this.compareRange(range); return (cmp == -1 || cmp == 0 || cmp == 1); }; Range.prototype.isEnd = function (row, column) { return this.end.row == row && this.end.column == column; }; Range.prototype.isStart = function (row, column) { return this.start.row == row && this.start.column == column; }; Range.prototype.setStart = function (row, column) { if (typeof row == "object") { this.start.column = row.column; this.start.row = row.row; } else { this.start.row = row; this.start.column = column; } }; Range.prototype.setEnd = function (row, column) { if (typeof row == "object") { this.end.column = row.column; this.end.row = row.row; } else { this.end.row = row; this.end.column = column; } }; Range.prototype.inside = function (row, column) { if (this.compare(row, column) == 0) { if (this.isEnd(row, column) || this.isStart(row, column)) { return false; } else { return true; } } return false; }; Range.prototype.insideStart = function (row, column) { if (this.compare(row, column) == 0) { if (this.isEnd(row, column)) { return false; } else { return true; } } return false; }; Range.prototype.insideEnd = function (row, column) { if (this.compare(row, column) == 0) { if (this.isStart(row, column)) { return false; } else { return true; } } return false; }; Range.prototype.compare = function (row, column) { if (!this.isMultiLine()) { if (row === this.start.row) { return column < this.start.column ? -1 : (column > this.end.column ? 1 : 0); } } if (row < this.start.row) return -1; if (row > this.end.row) return 1; if (this.start.row === row) return column >= this.start.column ? 0 : -1; if (this.end.row === row) return column <= this.end.column ? 0 : 1; return 0; }; Range.prototype.compareStart = function (row, column) { if (this.start.row == row && this.start.column == column) { return -1; } else { return this.compare(row, column); } }; Range.prototype.compareEnd = function (row, column) { if (this.end.row == row && this.end.column == column) { return 1; } else { return this.compare(row, column); } }; Range.prototype.compareInside = function (row, column) { if (this.end.row == row && this.end.column == column) { return 1; } else if (this.start.row == row && this.start.column == column) { return -1; } else { return this.compare(row, column); } }; Range.prototype.clipRows = function (firstRow, lastRow) { if (this.end.row > lastRow) var end = { row: lastRow + 1, column: 0 }; else if (this.end.row < firstRow) var end = { row: firstRow, column: 0 }; if (this.start.row > lastRow) var start = { row: lastRow + 1, column: 0 }; else if (this.start.row < firstRow) var start = { row: firstRow, column: 0 }; return Range.fromPoints(start || this.start, end || this.end); }; Range.prototype.extend = function (row, column) { var cmp = this.compare(row, column); if (cmp == 0) return this; else if (cmp == -1) var start = { row: row, column: column }; else var end = { row: row, column: column }; return Range.fromPoints(start || this.start, end || this.end); }; Range.prototype.isEmpty = function () { return (this.start.row === this.end.row && this.start.column === this.end.column); }; Range.prototype.isMultiLine = function () { return (this.start.row !== this.end.row); }; Range.prototype.clone = function () { return Range.fromPoints(this.start, this.end); }; Range.prototype.collapseRows = function () { if (this.end.column == 0) return new Range(this.start.row, 0, Math.max(this.start.row, this.end.row - 1), 0); else return new Range(this.start.row, 0, this.end.row, 0); }; Range.prototype.toScreenRange = function (session) { var screenPosStart = session.documentToScreenPosition(this.start); var screenPosEnd = session.documentToScreenPosition(this.end); return new Range(screenPosStart.row, screenPosStart.column, screenPosEnd.row, screenPosEnd.column); }; Range.prototype.moveBy = function (row, column) { this.start.row += row; this.start.column += column; this.end.row += row; this.end.column += column; }; return Range; }()); Range.fromPoints = function (start, end) { return new Range(start.row, start.column, end.row, end.column); }; Range.comparePoints = function (p1, p2) { return p1.row - p2.row || p1.column - p2.column; }; exports.Range = Range; }); define("ace/anchor",[], function(require, exports, module){"use strict"; var oop = require("./lib/oop"); var EventEmitter = require("./lib/event_emitter").EventEmitter; var Anchor = /** @class */ (function () { function Anchor(doc, row, column) { this.$onChange = this.onChange.bind(this); this.attach(doc); if (typeof row != "number") this.setPosition(row.row, row.column); else this.setPosition(row, column); } Anchor.prototype.getPosition = function () { return this.$clipPositionToDocument(this.row, this.column); }; Anchor.prototype.getDocument = function () { return this.document; }; Anchor.prototype.onChange = function (delta) { if (delta.start.row == delta.end.row && delta.start.row != this.row) return; if (delta.start.row > this.row) return; var point = $getTransformedPoint(delta, { row: this.row, column: this.column }, this.$insertRight); this.setPosition(point.row, point.column, true); }; Anchor.prototype.setPosition = function (row, column, noClip) { var pos; if (noClip) { pos = { row: row, column: column }; } else { pos = this.$clipPositionToDocument(row, column); } if (this.row == pos.row && this.column == pos.column) return; var old = { row: this.row, column: this.column }; this.row = pos.row; this.column = pos.column; this._signal("change", { old: old, value: pos }); }; Anchor.prototype.detach = function () { this.document.off("change", this.$onChange); }; Anchor.prototype.attach = function (doc) { this.document = doc || this.document; this.document.on("change", this.$onChange); }; Anchor.prototype.$clipPositionToDocument = function (row, column) { var pos = {}; if (row >= this.document.getLength()) { pos.row = Math.max(0, this.document.getLength() - 1); pos.column = this.document.getLine(pos.row).length; } else if (row < 0) { pos.row = 0; pos.column = 0; } else { pos.row = row; pos.column = Math.min(this.document.getLine(pos.row).length, Math.max(0, column)); } if (column < 0) pos.column = 0; return pos; }; return Anchor; }()); Anchor.prototype.$insertRight = false; oop.implement(Anchor.prototype, EventEmitter); function $pointsInOrder(point1, point2, equalPointsInOrder) { var bColIsAfter = equalPointsInOrder ? point1.column <= point2.column : point1.column < point2.column; return (point1.row < point2.row) || (point1.row == point2.row && bColIsAfter); } function $getTransformedPoint(delta, point, moveIfEqual) { var deltaIsInsert = delta.action == "insert"; var deltaRowShift = (deltaIsInsert ? 1 : -1) * (delta.end.row - delta.start.row); var deltaColShift = (deltaIsInsert ? 1 : -1) * (delta.end.column - delta.start.column); var deltaStart = delta.start; var deltaEnd = deltaIsInsert ? deltaStart : delta.end; // Collapse insert range. if ($pointsInOrder(point, deltaStart, moveIfEqual)) { return { row: point.row, column: point.column }; } if ($pointsInOrder(deltaEnd, point, !moveIfEqual)) { return { row: point.row + deltaRowShift, column: point.column + (point.row == deltaEnd.row ? deltaColShift : 0) }; } return { row: deltaStart.row, column: deltaStart.column }; } exports.Anchor = Anchor; }); define("ace/document",[], function(require, exports, module){"use strict"; var oop = require("./lib/oop"); var applyDelta = require("./apply_delta").applyDelta; var EventEmitter = require("./lib/event_emitter").EventEmitter; var Range = require("./range").Range; var Anchor = require("./anchor").Anchor; var Document = /** @class */ (function () { function Document(textOrLines) { this.$lines = [""]; if (textOrLines.length === 0) { this.$lines = [""]; } else if (Array.isArray(textOrLines)) { this.insertMergedLines({ row: 0, column: 0 }, textOrLines); } else { this.insert({ row: 0, column: 0 }, textOrLines); } } Document.prototype.setValue = function (text) { var len = this.getLength() - 1; this.remove(new Range(0, 0, len, this.getLine(len).length)); this.insert({ row: 0, column: 0 }, text || ""); }; Document.prototype.getValue = function () { return this.getAllLines().join(this.getNewLineCharacter()); }; Document.prototype.createAnchor = function (row, column) { return new Anchor(this, row, column); }; Document.prototype.$detectNewLine = function (text) { var match = text.match(/^.*?(\r\n|\r|\n)/m); this.$autoNewLine = match ? match[1] : "\n"; this._signal("changeNewLineMode"); }; Document.prototype.getNewLineCharacter = function () { switch (this.$newLineMode) { case "windows": return "\r\n"; case "unix": return "\n"; default: return this.$autoNewLine || "\n"; } }; Document.prototype.setNewLineMode = function (newLineMode) { if (this.$newLineMode === newLineMode) return; this.$newLineMode = newLineMode; this._signal("changeNewLineMode"); }; Document.prototype.getNewLineMode = function () { return this.$newLineMode; }; Document.prototype.isNewLine = function (text) { return (text == "\r\n" || text == "\r" || text == "\n"); }; Document.prototype.getLine = function (row) { return this.$lines[row] || ""; }; Document.prototype.getLines = function (firstRow, lastRow) { return this.$lines.slice(firstRow, lastRow + 1); }; Document.prototype.getAllLines = function () { return this.getLines(0, this.getLength()); }; Document.prototype.getLength = function () { return this.$lines.length; }; Document.prototype.getTextRange = function (range) { return this.getLinesForRange(range).join(this.getNewLineCharacter()); }; Document.prototype.getLinesForRange = function (range) { var lines; if (range.start.row === range.end.row) { lines = [this.getLine(range.start.row).substring(range.start.column, range.end.column)]; } else { lines = this.getLines(range.start.row, range.end.row); lines[0] = (lines[0] || "").substring(range.start.column); var l = lines.length - 1; if (range.end.row - range.start.row == l) lines[l] = lines[l].substring(0, range.end.column); } return lines; }; Document.prototype.insertLines = function (row, lines) { console.warn("Use of document.insertLines is deprecated. Use the insertFullLines method instead."); return this.insertFullLines(row, lines); }; Document.prototype.removeLines = function (firstRow, lastRow) { console.warn("Use of document.removeLines is deprecated. Use the removeFullLines method instead."); return this.removeFullLines(firstRow, lastRow); }; Document.prototype.insertNewLine = function (position) { console.warn("Use of document.insertNewLine is deprecated. Use insertMergedLines(position, ['', '']) instead."); return this.insertMergedLines(position, ["", ""]); }; Document.prototype.insert = function (position, text) { if (this.getLength() <= 1) this.$detectNewLine(text); return this.insertMergedLines(position, this.$split(text)); }; Document.prototype.insertInLine = function (position, text) { var start = this.clippedPos(position.row, position.column); var end = this.pos(position.row, position.column + text.length); this.applyDelta({ start: start, end: end, action: "insert", lines: [text] }, true); return this.clonePos(end); }; Document.prototype.clippedPos = function (row, column) { var length = this.getLength(); if (row === undefined) { row = length; } else if (row < 0) { row = 0; } else if (row >= length) { row = length - 1; column = undefined; } var line = this.getLine(row); if (column == undefined) column = line.length; column = Math.min(Math.max(column, 0), line.length); return { row: row, column: column }; }; Document.prototype.clonePos = function (pos) { return { row: pos.row, column: pos.column }; }; Document.prototype.pos = function (row, column) { return { row: row, column: column }; }; Document.prototype.$clipPosition = function (position) { var length = this.getLength(); if (position.row >= length) { position.row = Math.max(0, length - 1); position.column = this.getLine(length - 1).length; } else { position.row = Math.max(0, position.row); position.column = Math.min(Math.max(position.column, 0), this.getLine(position.row).length); } return position; }; Document.prototype.insertFullLines = function (row, lines) { row = Math.min(Math.max(row, 0), this.getLength()); var column = 0; if (row < this.getLength()) { lines = lines.concat([""]); column = 0; } else { lines = [""].concat(lines); row--; column = this.$lines[row].length; } this.insertMergedLines({ row: row, column: column }, lines); }; Document.prototype.insertMergedLines = function (position, lines) { var start = this.clippedPos(position.row, position.column); var end = { row: start.row + lines.length - 1, column: (lines.length == 1 ? start.column : 0) + lines[lines.length - 1].length }; this.applyDelta({ start: start, end: end, action: "insert", lines: lines }); return this.clonePos(end); }; Document.prototype.remove = function (range) { var start = this.clippedPos(range.start.row, range.start.column); var end = this.clippedPos(range.end.row, range.end.column); this.applyDelta({ start: start, end: end, action: "remove", lines: this.getLinesForRange({ start: start, end: end }) }); return this.clonePos(start); }; Document.prototype.removeInLine = function (row, startColumn, endColumn) { var start = this.clippedPos(row, startColumn); var end = this.clippedPos(row, endColumn); this.applyDelta({ start: start, end: end, action: "remove", lines: this.getLinesForRange({ start: start, end: end }) }, true); return this.clonePos(start); }; Document.prototype.removeFullLines = function (firstRow, lastRow) { firstRow = Math.min(Math.max(0, firstRow), this.getLength() - 1); lastRow = Math.min(Math.max(0, lastRow), this.getLength() - 1); var deleteFirstNewLine = lastRow == this.getLength() - 1 && firstRow > 0; var deleteLastNewLine = lastRow < this.getLength() - 1; var startRow = (deleteFirstNewLine ? firstRow - 1 : firstRow); var startCol = (deleteFirstNewLine ? this.getLine(startRow).length : 0); var endRow = (deleteLastNewLine ? lastRow + 1 : lastRow); var endCol = (deleteLastNewLine ? 0 : this.getLine(endRow).length); var range = new Range(startRow, startCol, endRow, endCol); var deletedLines = this.$lines.slice(firstRow, lastRow + 1); this.applyDelta({ start: range.start, end: range.end, action: "remove", lines: this.getLinesForRange(range) }); return deletedLines; }; Document.prototype.removeNewLine = function (row) { if (row < this.getLength() - 1 && row >= 0) { this.applyDelta({ start: this.pos(row, this.getLine(row).length), end: this.pos(row + 1, 0), action: "remove", lines: ["", ""] }); } }; Document.prototype.replace = function (range, text) { if (!(range instanceof Range)) range = Range.fromPoints(range.start, range.end); if (text.length === 0 && range.isEmpty()) return range.start; if (text == this.getTextRange(range)) return range.end; this.remove(range); var end; if (text) { end = this.insert(range.start, text); } else { end = range.start; } return end; }; Document.prototype.applyDeltas = function (deltas) { for (var i = 0; i < deltas.length; i++) { this.applyDelta(deltas[i]); } }; Document.prototype.revertDeltas = function (deltas) { for (var i = deltas.length - 1; i >= 0; i--) { this.revertDelta(deltas[i]); } }; Document.prototype.applyDelta = function (delta, doNotValidate) { var isInsert = delta.action == "insert"; if (isInsert ? delta.lines.length <= 1 && !delta.lines[0] : !Range.comparePoints(delta.start, delta.end)) { return; } if (isInsert && delta.lines.length > 20000) { this.$splitAndapplyLargeDelta(delta, 20000); } else { applyDelta(this.$lines, delta, doNotValidate); this._signal("change", delta); } }; Document.prototype.$safeApplyDelta = function (delta) { var docLength = this.$lines.length; if (delta.action == "remove" && delta.start.row < docLength && delta.end.row < docLength || delta.action == "insert" && delta.start.row <= docLength) { this.applyDelta(delta); } }; Document.prototype.$splitAndapplyLargeDelta = function (delta, MAX) { var lines = delta.lines; var l = lines.length - MAX + 1; var row = delta.start.row; var column = delta.start.column; for (var from = 0, to = 0; from < l; from = to) { to += MAX - 1; var chunk = lines.slice(from, to); chunk.push(""); this.applyDelta({ start: this.pos(row + from, column), end: this.pos(row + to, column = 0), action: delta.action, lines: chunk }, true); } delta.lines = lines.slice(from); delta.start.row = row + from; delta.start.column = column; this.applyDelta(delta, true); }; Document.prototype.revertDelta = function (delta) { this.$safeApplyDelta({ start: this.clonePos(delta.start), end: this.clonePos(delta.end), action: (delta.action == "insert" ? "remove" : "insert"), lines: delta.lines.slice() }); }; Document.prototype.indexToPosition = function (index, startRow) { var lines = this.$lines || this.getAllLines(); var newlineLength = this.getNewLineCharacter().length; for (var i = startRow || 0, l = lines.length; i < l; i++) { index -= lines[i].length + newlineLength; if (index < 0) return { row: i, column: index + lines[i].length + newlineLength }; } return { row: l - 1, column: index + lines[l - 1].length + newlineLength }; }; Document.prototype.positionToIndex = function (pos, startRow) { var lines = this.$lines || this.getAllLines(); var newlineLength = this.getNewLineCharacter().length; var index = 0; var row = Math.min(pos.row, lines.length); for (var i = startRow || 0; i < row; ++i) index += lines[i].length + newlineLength; return index + pos.column; }; Document.prototype.$split = function (text) { return text.split(/\r\n|\r|\n/); }; return Document; }()); Document.prototype.$autoNewLine = ""; Document.prototype.$newLineMode = "auto"; oop.implement(Document.prototype, EventEmitter); exports.Document = Document; }); define("ace/worker/mirror",[], function(require, exports, module) { "use strict"; var Document = require("../document").Document; var lang = require("../lib/lang"); var Mirror = exports.Mirror = function(sender) { this.sender = sender; var doc = this.doc = new Document(""); var deferredUpdate = this.deferredUpdate = lang.delayedCall(this.onUpdate.bind(this)); var _self = this; sender.on("change", function(e) { var data = e.data; if (data[0].start) { doc.applyDeltas(data); } else { for (var i = 0; i < data.length; i += 2) { var d, err; if (Array.isArray(data[i+1])) { d = {action: "insert", start: data[i], lines: data[i+1]}; } else { d = {action: "remove", start: data[i], end: data[i+1]}; } if ((d.action == "insert" ? d.start : d.end).row >= doc.$lines.length) { err = new Error("Invalid delta"); err.data = { path: _self.$path, linesLength: doc.$lines.length, start: d.start, end: d.end }; throw err; } doc.applyDelta(d, true); } } if (_self.$timeout) return deferredUpdate.schedule(_self.$timeout); _self.onUpdate(); }); }; (function() { this.$timeout = 500; this.setTimeout = function(timeout) { this.$timeout = timeout; }; this.setValue = function(value) { this.doc.setValue(value); this.deferredUpdate.schedule(this.$timeout); }; this.getValue = function(callbackId) { this.sender.callback(this.doc.getValue(), callbackId); }; this.onUpdate = function() { }; this.isPending = function() { return this.deferredUpdate.isPending(); }; }).call(Mirror.prototype); }); define("ace/mode/css/csslint",[], function(require, exports, module) { var CSSLint = (function(){ var module = module || {}, exports = exports || {}; var parserlib = (function () { var require; require=(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ "use strict"; var Colors = module.exports = { __proto__ : null, aliceblue : "#f0f8ff", antiquewhite : "#faebd7", aqua : "#00ffff", aquamarine : "#7fffd4", azure : "#f0ffff", beige : "#f5f5dc", bisque : "#ffe4c4", black : "#000000", blanchedalmond : "#ffebcd", blue : "#0000ff", blueviolet : "#8a2be2", brown : "#a52a2a", burlywood : "#deb887", cadetblue : "#5f9ea0", chartreuse : "#7fff00", chocolate : "#d2691e", coral : "#ff7f50", cornflowerblue : "#6495ed", cornsilk : "#fff8dc", crimson : "#dc143c", cyan : "#00ffff", darkblue : "#00008b", darkcyan : "#008b8b", darkgoldenrod : "#b8860b", darkgray : "#a9a9a9", darkgreen : "#006400", darkgrey : "#a9a9a9", darkkhaki : "#bdb76b", darkmagenta : "#8b008b", darkolivegreen : "#556b2f", darkorange : "#ff8c00", darkorchid : "#9932cc", darkred : "#8b0000", darksalmon : "#e9967a", darkseagreen : "#8fbc8f", darkslateblue : "#483d8b", darkslategray : "#2f4f4f", darkslategrey : "#2f4f4f", darkturquoise : "#00ced1", darkviolet : "#9400d3", deeppink : "#ff1493", deepskyblue : "#00bfff", dimgray : "#696969", dimgrey : "#696969", dodgerblue : "#1e90ff", firebrick : "#b22222", floralwhite : "#fffaf0", forestgreen : "#228b22", fuchsia : "#ff00ff", gainsboro : "#dcdcdc", ghostwhite : "#f8f8ff", gold : "#ffd700", goldenrod : "#daa520", gray : "#808080", green : "#008000", greenyellow : "#adff2f", grey : "#808080", honeydew : "#f0fff0", hotpink : "#ff69b4", indianred : "#cd5c5c", indigo : "#4b0082", ivory : "#fffff0", khaki : "#f0e68c", lavender : "#e6e6fa", lavenderblush : "#fff0f5", lawngreen : "#7cfc00", lemonchiffon : "#fffacd", lightblue : "#add8e6", lightcoral : "#f08080", lightcyan : "#e0ffff", lightgoldenrodyellow : "#fafad2", lightgray : "#d3d3d3", lightgreen : "#90ee90", lightgrey : "#d3d3d3", lightpink : "#ffb6c1", lightsalmon : "#ffa07a", lightseagreen : "#20b2aa", lightskyblue : "#87cefa", lightslategray : "#778899", lightslategrey : "#778899", lightsteelblue : "#b0c4de", lightyellow : "#ffffe0", lime : "#00ff00", limegreen : "#32cd32", linen : "#faf0e6", magenta : "#ff00ff", maroon : "#800000", mediumaquamarine : "#66cdaa", mediumblue : "#0000cd", mediumorchid : "#ba55d3", mediumpurple : "#9370db", mediumseagreen : "#3cb371", mediumslateblue : "#7b68ee", mediumspringgreen : "#00fa9a", mediumturquoise : "#48d1cc", mediumvioletred : "#c71585", midnightblue : "#191970", mintcream : "#f5fffa", mistyrose : "#ffe4e1", moccasin : "#ffe4b5", navajowhite : "#ffdead", navy : "#000080", oldlace : "#fdf5e6", olive : "#808000", olivedrab : "#6b8e23", orange : "#ffa500", orangered : "#ff4500", orchid : "#da70d6", palegoldenrod : "#eee8aa", palegreen : "#98fb98", paleturquoise : "#afeeee", palevioletred : "#db7093", papayawhip : "#ffefd5", peachpuff : "#ffdab9", peru : "#cd853f", pink : "#ffc0cb", plum : "#dda0dd", powderblue : "#b0e0e6", purple : "#800080", rebeccapurple : "#663399", red : "#ff0000", rosybrown : "#bc8f8f", royalblue : "#4169e1", saddlebrown : "#8b4513", salmon : "#fa8072", sandybrown : "#f4a460", seagreen : "#2e8b57", seashell : "#fff5ee", sienna : "#a0522d", silver : "#c0c0c0", skyblue : "#87ceeb", slateblue : "#6a5acd", slategray : "#708090", slategrey : "#708090", snow : "#fffafa", springgreen : "#00ff7f", steelblue : "#4682b4", tan : "#d2b48c", teal : "#008080", thistle : "#d8bfd8", tomato : "#ff6347", turquoise : "#40e0d0", violet : "#ee82ee", wheat : "#f5deb3", white : "#ffffff", whitesmoke : "#f5f5f5", yellow : "#ffff00", yellowgreen : "#9acd32", currentColor : "The value of the 'color' property.", activeborder : "Active window border.", activecaption : "Active window caption.", appworkspace : "Background color of multiple document interface.", background : "Desktop background.", buttonface : "The face background color for 3-D elements that appear 3-D due to one layer of surrounding border.", buttonhighlight : "The color of the border facing the light source for 3-D elements that appear 3-D due to one layer of surrounding border.", buttonshadow : "The color of the border away from the light source for 3-D elements that appear 3-D due to one layer of surrounding border.", buttontext : "Text on push buttons.", captiontext : "Text in caption, size box, and scrollbar arrow box.", graytext : "Grayed (disabled) text. This color is set to #000 if the current display driver does not support a solid gray color.", greytext : "Greyed (disabled) text. This color is set to #000 if the current display driver does not support a solid grey color.", highlight : "Item(s) selected in a control.", highlighttext : "Text of item(s) selected in a control.", inactiveborder : "Inactive window border.", inactivecaption : "Inactive window caption.", inactivecaptiontext : "Color of text in an inactive caption.", infobackground : "Background color for tooltip controls.", infotext : "Text color for tooltip controls.", menu : "Menu background.", menutext : "Text in menus.", scrollbar : "Scroll bar gray area.", threeddarkshadow : "The color of the darker (generally outer) of the two borders away from the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.", threedface : "The face background color for 3-D elements that appear 3-D due to two concentric layers of surrounding border.", threedhighlight : "The color of the lighter (generally outer) of the two borders facing the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.", threedlightshadow : "The color of the darker (generally inner) of the two borders facing the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.", threedshadow : "The color of the lighter (generally inner) of the two borders away from the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.", window : "Window background.", windowframe : "Window frame.", windowtext : "Text in windows." }; },{}],2:[function(require,module,exports){ "use strict"; module.exports = Combinator; var SyntaxUnit = require("../util/SyntaxUnit"); var Parser = require("./Parser"); function Combinator(text, line, col) { SyntaxUnit.call(this, text, line, col, Parser.COMBINATOR_TYPE); this.type = "unknown"; if (/^\s+$/.test(text)) { this.type = "descendant"; } else if (text === ">") { this.type = "child"; } else if (text === "+") { this.type = "adjacent-sibling"; } else if (text === "~") { this.type = "sibling"; } } Combinator.prototype = new SyntaxUnit(); Combinator.prototype.constructor = Combinator; },{"../util/SyntaxUnit":26,"./Parser":6}],3:[function(require,module,exports){ "use strict"; module.exports = Matcher; var StringReader = require("../util/StringReader"); var SyntaxError = require("../util/SyntaxError"); function Matcher(matchFunc, toString) { this.match = function(expression) { var result; expression.mark(); result = matchFunc(expression); if (result) { expression.drop(); } else { expression.restore(); } return result; }; this.toString = typeof toString === "function" ? toString : function() { return toString; }; } Matcher.prec = { MOD: 5, SEQ: 4, ANDAND: 3, OROR: 2, ALT: 1 }; Matcher.parse = function(str) { var reader, eat, expr, oror, andand, seq, mod, term, result; reader = new StringReader(str); eat = function(matcher) { var result = reader.readMatch(matcher); if (result === null) { throw new SyntaxError( "Expected " + matcher, reader.getLine(), reader.getCol()); } return result; }; expr = function() { var m = [ oror() ]; while (reader.readMatch(" | ") !== null) { m.push(oror()); } return m.length === 1 ? m[0] : Matcher.alt.apply(Matcher, m); }; oror = function() { var m = [ andand() ]; while (reader.readMatch(" || ") !== null) { m.push(andand()); } return m.length === 1 ? m[0] : Matcher.oror.apply(Matcher, m); }; andand = function() { var m = [ seq() ]; while (reader.readMatch(" && ") !== null) { m.push(seq()); } return m.length === 1 ? m[0] : Matcher.andand.apply(Matcher, m); }; seq = function() { var m = [ mod() ]; while (reader.readMatch(/^ (?![&|\]])/) !== null) { m.push(mod()); } return m.length === 1 ? m[0] : Matcher.seq.apply(Matcher, m); }; mod = function() { var m = term(); if (reader.readMatch("?") !== null) { return m.question(); } else if (reader.readMatch("*") !== null) { return m.star(); } else if (reader.readMatch("+") !== null) { return m.plus(); } else if (reader.readMatch("#") !== null) { return m.hash(); } else if (reader.readMatch(/^\{\s*/) !== null) { var min = eat(/^\d+/); eat(/^\s*,\s*/); var max = eat(/^\d+/); eat(/^\s*\}/); return m.braces(Number(min), Number(max)); } return m; }; term = function() { if (reader.readMatch("[ ") !== null) { var m = expr(); eat(" ]"); return m; } return Matcher.fromType(eat(/^[^ ?*+#{]+/)); }; result = expr(); if (!reader.eof()) { throw new SyntaxError( "Expected end of string", reader.getLine(), reader.getCol()); } return result; }; Matcher.cast = function(m) { if (m instanceof Matcher) { return m; } return Matcher.parse(m); }; Matcher.fromType = function(type) { var ValidationTypes = require("./ValidationTypes"); return new Matcher(function(expression) { return expression.hasNext() && ValidationTypes.isType(expression, type); }, type); }; Matcher.seq = function() { var ms = Array.prototype.slice.call(arguments).map(Matcher.cast); if (ms.length === 1) { return ms[0]; } return new Matcher(function(expression) { var i, result = true; for (i = 0; result && i < ms.length; i++) { result = ms[i].match(expression); } return result; }, function(prec) { var p = Matcher.prec.SEQ; var s = ms.map(function(m) { return m.toString(p); }).join(" "); if (prec > p) { s = "[ " + s + " ]"; } return s; }); }; Matcher.alt = function() { var ms = Array.prototype.slice.call(arguments).map(Matcher.cast); if (ms.length === 1) { return ms[0]; } return new Matcher(function(expression) { var i, result = false; for (i = 0; !result && i < ms.length; i++) { result = ms[i].match(expression); } return result; }, function(prec) { var p = Matcher.prec.ALT; var s = ms.map(function(m) { return m.toString(p); }).join(" | "); if (prec > p) { s = "[ " + s + " ]"; } return s; }); }; Matcher.many = function(required) { var ms = Array.prototype.slice.call(arguments, 1).reduce(function(acc, v) { if (v.expand) { var ValidationTypes = require("./ValidationTypes"); acc.push.apply(acc, ValidationTypes.complex[v.expand].options); } else { acc.push(Matcher.cast(v)); } return acc; }, []); if (required === true) { required = ms.map(function() { return true; }); } var result = new Matcher(function(expression) { var seen = [], max = 0, pass = 0; var success = function(matchCount) { if (pass === 0) { max = Math.max(matchCount, max); return matchCount === ms.length; } else { return matchCount === max; } }; var tryMatch = function(matchCount) { for (var i = 0; i < ms.length; i++) { if (seen[i]) { continue; } expression.mark(); if (ms[i].match(expression)) { seen[i] = true; if (tryMatch(matchCount + (required === false || required[i] ? 1 : 0))) { expression.drop(); return true; } expression.restore(); seen[i] = false; } else { expression.drop(); } } return success(matchCount); }; if (!tryMatch(0)) { pass++; tryMatch(0); } if (required === false) { return max > 0; } for (var i = 0; i < ms.length; i++) { if (required[i] && !seen[i]) { return false; } } return true; }, function(prec) { var p = required === false ? Matcher.prec.OROR : Matcher.prec.ANDAND; var s = ms.map(function(m, i) { if (required !== false && !required[i]) { return m.toString(Matcher.prec.MOD) + "?"; } return m.toString(p); }).join(required === false ? " || " : " && "); if (prec > p) { s = "[ " + s + " ]"; } return s; }); result.options = ms; return result; }; Matcher.andand = function() { var args = Array.prototype.slice.call(arguments); args.unshift(true); return Matcher.many.apply(Matcher, args); }; Matcher.oror = function() { var args = Array.prototype.slice.call(arguments); args.unshift(false); return Matcher.many.apply(Matcher, args); }; Matcher.prototype = { constructor: Matcher, match: function() { throw new Error("unimplemented"); }, toString: function() { throw new Error("unimplemented"); }, func: function() { return this.match.bind(this); }, then: function(m) { return Matcher.seq(this, m); }, or: function(m) { return Matcher.alt(this, m); }, andand: function(m) { return Matcher.many(true, this, m); }, oror: function(m) { return Matcher.many(false, this, m); }, star: function() { return this.braces(0, Infinity, "*"); }, plus: function() { return this.braces(1, Infinity, "+"); }, question: function() { return this.braces(0, 1, "?"); }, hash: function() { return this.braces(1, Infinity, "#", Matcher.cast(",")); }, braces: function(min, max, marker, optSep) { var m1 = this, m2 = optSep ? optSep.then(this) : this; if (!marker) { marker = "{" + min + "," + max + "}"; } return new Matcher(function(expression) { var result = true, i; for (i = 0; i < max; i++) { if (i > 0 && optSep) { result = m2.match(expression); } else { result = m1.match(expression); } if (!result) { break; } } return i >= min; }, function() { return m1.toString(Matcher.prec.MOD) + marker; }); } }; },{"../util/StringReader":24,"../util/SyntaxError":25,"./ValidationTypes":21}],4:[function(require,module,exports){ "use strict"; module.exports = MediaFeature; var SyntaxUnit = require("../util/SyntaxUnit"); var Parser = require("./Parser"); function MediaFeature(name, value) { SyntaxUnit.call(this, "(" + name + (value !== null ? ":" + value : "") + ")", name.startLine, name.startCol, Parser.MEDIA_FEATURE_TYPE); this.name = name; this.value = value; } MediaFeature.prototype = new SyntaxUnit(); MediaFeature.prototype.constructor = MediaFeature; },{"../util/SyntaxUnit":26,"./Parser":6}],5:[function(require,module,exports){ "use strict"; module.exports = MediaQuery; var SyntaxUnit = require("../util/SyntaxUnit"); var Parser = require("./Parser"); function MediaQuery(modifier, mediaType, features, line, col) { SyntaxUnit.call(this, (modifier ? modifier + " " : "") + (mediaType ? mediaType : "") + (mediaType && features.length > 0 ? " and " : "") + features.join(" and "), line, col, Parser.MEDIA_QUERY_TYPE); this.modifier = modifier; this.mediaType = mediaType; this.features = features; } MediaQuery.prototype = new SyntaxUnit(); MediaQuery.prototype.constructor = MediaQuery; },{"../util/SyntaxUnit":26,"./Parser":6}],6:[function(require,module,exports){ "use strict"; module.exports = Parser; var EventTarget = require("../util/EventTarget"); var SyntaxError = require("../util/SyntaxError"); var SyntaxUnit = require("../util/SyntaxUnit"); var Combinator = require("./Combinator"); var MediaFeature = require("./MediaFeature"); var MediaQuery = require("./MediaQuery"); var PropertyName = require("./PropertyName"); var PropertyValue = require("./PropertyValue"); var PropertyValuePart = require("./PropertyValuePart"); var Selector = require("./Selector"); var SelectorPart = require("./SelectorPart"); var SelectorSubPart = require("./SelectorSubPart"); var TokenStream = require("./TokenStream"); var Tokens = require("./Tokens"); var Validation = require("./Validation"); function Parser(options) { EventTarget.call(this); this.options = options || {}; this._tokenStream = null; } Parser.DEFAULT_TYPE = 0; Parser.COMBINATOR_TYPE = 1; Parser.MEDIA_FEATURE_TYPE = 2; Parser.MEDIA_QUERY_TYPE = 3; Parser.PROPERTY_NAME_TYPE = 4; Parser.PROPERTY_VALUE_TYPE = 5; Parser.PROPERTY_VALUE_PART_TYPE = 6; Parser.SELECTOR_TYPE = 7; Parser.SELECTOR_PART_TYPE = 8; Parser.SELECTOR_SUB_PART_TYPE = 9; Parser.prototype = function() { var proto = new EventTarget(), // new prototype prop, additions = { __proto__: null, constructor: Parser, DEFAULT_TYPE : 0, COMBINATOR_TYPE : 1, MEDIA_FEATURE_TYPE : 2, MEDIA_QUERY_TYPE : 3, PROPERTY_NAME_TYPE : 4, PROPERTY_VALUE_TYPE : 5, PROPERTY_VALUE_PART_TYPE : 6, SELECTOR_TYPE : 7, SELECTOR_PART_TYPE : 8, SELECTOR_SUB_PART_TYPE : 9, _stylesheet: function() { var tokenStream = this._tokenStream, count, token, tt; this.fire("startstylesheet"); this._charset(); this._skipCruft(); while (tokenStream.peek() === Tokens.IMPORT_SYM) { this._import(); this._skipCruft(); } while (tokenStream.peek() === Tokens.NAMESPACE_SYM) { this._namespace(); this._skipCruft(); } tt = tokenStream.peek(); while (tt > Tokens.EOF) { try { switch (tt) { case Tokens.MEDIA_SYM: this._media(); this._skipCruft(); break; case Tokens.PAGE_SYM: this._page(); this._skipCruft(); break; case Tokens.FONT_FACE_SYM: this._font_face(); this._skipCruft(); break; case Tokens.KEYFRAMES_SYM: this._keyframes(); this._skipCruft(); break; case Tokens.VIEWPORT_SYM: this._viewport(); this._skipCruft(); break; case Tokens.DOCUMENT_SYM: this._document(); this._skipCruft(); break; case Tokens.SUPPORTS_SYM: this._supports(); this._skipCruft(); break; case Tokens.UNKNOWN_SYM: // unknown @ rule tokenStream.get(); if (!this.options.strict) { this.fire({ type: "error", error: null, message: "Unknown @ rule: " + tokenStream.LT(0).value + ".", line: tokenStream.LT(0).startLine, col: tokenStream.LT(0).startCol }); count = 0; while (tokenStream.advance([Tokens.LBRACE, Tokens.RBRACE]) === Tokens.LBRACE) { count++; // keep track of nesting depth } while (count) { tokenStream.advance([Tokens.RBRACE]); count--; } } else { throw new SyntaxError("Unknown @ rule.", tokenStream.LT(0).startLine, tokenStream.LT(0).startCol); } break; case Tokens.S: this._readWhitespace(); break; default: if (!this._ruleset()) { switch (tt) { case Tokens.CHARSET_SYM: token = tokenStream.LT(1); this._charset(false); throw new SyntaxError("@charset not allowed here.", token.startLine, token.startCol); case Tokens.IMPORT_SYM: token = tokenStream.LT(1); this._import(false); throw new SyntaxError("@import not allowed here.", token.startLine, token.startCol); case Tokens.NAMESPACE_SYM: token = tokenStream.LT(1); this._namespace(false); throw new SyntaxError("@namespace not allowed here.", token.startLine, token.startCol); default: tokenStream.get(); // get the last token this._unexpectedToken(tokenStream.token()); } } } } catch (ex) { if (ex instanceof SyntaxError && !this.options.strict) { this.fire({ type: "error", error: ex, message: ex.message, line: ex.line, col: ex.col }); } else { throw ex; } } tt = tokenStream.peek(); } if (tt !== Tokens.EOF) { this._unexpectedToken(tokenStream.token()); } this.fire("endstylesheet"); }, _charset: function(emit) { var tokenStream = this._tokenStream, charset, token, line, col; if (tokenStream.match(Tokens.CHARSET_SYM)) { line = tokenStream.token().startLine; col = tokenStream.token().startCol; this._readWhitespace(); tokenStream.mustMatch(Tokens.STRING); token = tokenStream.token(); charset = token.value; this._readWhitespace(); tokenStream.mustMatch(Tokens.SEMICOLON); if (emit !== false) { this.fire({ type: "charset", charset:charset, line: line, col: col }); } } }, _import: function(emit) { var tokenStream = this._tokenStream, uri, importToken, mediaList = []; tokenStream.mustMatch(Tokens.IMPORT_SYM); importToken = tokenStream.token(); this._readWhitespace(); tokenStream.mustMatch([Tokens.STRING, Tokens.URI]); uri = tokenStream.token().value.replace(/^(?:url\()?["']?([^"']+?)["']?\)?$/, "$1"); this._readWhitespace(); mediaList = this._media_query_list(); tokenStream.mustMatch(Tokens.SEMICOLON); this._readWhitespace(); if (emit !== false) { this.fire({ type: "import", uri: uri, media: mediaList, line: importToken.startLine, col: importToken.startCol }); } }, _namespace: function(emit) { var tokenStream = this._tokenStream, line, col, prefix, uri; tokenStream.mustMatch(Tokens.NAMESPACE_SYM); line = tokenStream.token().startLine; col = tokenStream.token().startCol; this._readWhitespace(); if (tokenStream.match(Tokens.IDENT)) { prefix = tokenStream.token().value; this._readWhitespace(); } tokenStream.mustMatch([Tokens.STRING, Tokens.URI]); uri = tokenStream.token().value.replace(/(?:url\()?["']([^"']+)["']\)?/, "$1"); this._readWhitespace(); tokenStream.mustMatch(Tokens.SEMICOLON); this._readWhitespace(); if (emit !== false) { this.fire({ type: "namespace", prefix: prefix, uri: uri, line: line, col: col }); } }, _supports: function(emit) { var tokenStream = this._tokenStream, line, col; if (tokenStream.match(Tokens.SUPPORTS_SYM)) { line = tokenStream.token().startLine; col = tokenStream.token().startCol; this._readWhitespace(); this._supports_condition(); this._readWhitespace(); tokenStream.mustMatch(Tokens.LBRACE); this._readWhitespace(); if (emit !== false) { this.fire({ type: "startsupports", line: line, col: col }); } while (true) { if (!this._ruleset()) { break; } } tokenStream.mustMatch(Tokens.RBRACE); this._readWhitespace(); this.fire({ type: "endsupports", line: line, col: col }); } }, _supports_condition: function() { var tokenStream = this._tokenStream, ident; if (tokenStream.match(Tokens.IDENT)) { ident = tokenStream.token().value.toLowerCase(); if (ident === "not") { tokenStream.mustMatch(Tokens.S); this._supports_condition_in_parens(); } else { tokenStream.unget(); } } else { this._supports_condition_in_parens(); this._readWhitespace(); while (tokenStream.peek() === Tokens.IDENT) { ident = tokenStream.LT(1).value.toLowerCase(); if (ident === "and" || ident === "or") { tokenStream.mustMatch(Tokens.IDENT); this._readWhitespace(); this._supports_condition_in_parens(); this._readWhitespace(); } } } }, _supports_condition_in_parens: function() { var tokenStream = this._tokenStream, ident; if (tokenStream.match(Tokens.LPAREN)) { this._readWhitespace(); if (tokenStream.match(Tokens.IDENT)) { ident = tokenStream.token().value.toLowerCase(); if (ident === "not") { this._readWhitespace(); this._supports_condition(); this._readWhitespace(); tokenStream.mustMatch(Tokens.RPAREN); } else { tokenStream.unget(); this._supports_declaration_condition(false); } } else { this._supports_condition(); this._readWhitespace(); tokenStream.mustMatch(Tokens.RPAREN); } } else { this._supports_declaration_condition(); } }, _supports_declaration_condition: function(requireStartParen) { var tokenStream = this._tokenStream; if (requireStartParen !== false) { tokenStream.mustMatch(Tokens.LPAREN); } this._readWhitespace(); this._declaration(); tokenStream.mustMatch(Tokens.RPAREN); }, _media: function() { var tokenStream = this._tokenStream, line, col, mediaList; // = []; tokenStream.mustMatch(Tokens.MEDIA_SYM); line = tokenStream.token().startLine; col = tokenStream.token().startCol; this._readWhitespace(); mediaList = this._media_query_list(); tokenStream.mustMatch(Tokens.LBRACE); this._readWhitespace(); this.fire({ type: "startmedia", media: mediaList, line: line, col: col }); while (true) { if (tokenStream.peek() === Tokens.PAGE_SYM) { this._page(); } else if (tokenStream.peek() === Tokens.FONT_FACE_SYM) { this._font_face(); } else if (tokenStream.peek() === Tokens.VIEWPORT_SYM) { this._viewport(); } else if (tokenStream.peek() === Tokens.DOCUMENT_SYM) { this._document(); } else if (tokenStream.peek() === Tokens.SUPPORTS_SYM) { this._supports(); } else if (tokenStream.peek() === Tokens.MEDIA_SYM) { this._media(); } else if (!this._ruleset()) { break; } } tokenStream.mustMatch(Tokens.RBRACE); this._readWhitespace(); this.fire({ type: "endmedia", media: mediaList, line: line, col: col }); }, _media_query_list: function() { var tokenStream = this._tokenStream, mediaList = []; this._readWhitespace(); if (tokenStream.peek() === Tokens.IDENT || tokenStream.peek() === Tokens.LPAREN) { mediaList.push(this._media_query()); } while (tokenStream.match(Tokens.COMMA)) { this._readWhitespace(); mediaList.push(this._media_query()); } return mediaList; }, _media_query: function() { var tokenStream = this._tokenStream, type = null, ident = null, token = null, expressions = []; if (tokenStream.match(Tokens.IDENT)) { ident = tokenStream.token().value.toLowerCase(); if (ident !== "only" && ident !== "not") { tokenStream.unget(); ident = null; } else { token = tokenStream.token(); } } this._readWhitespace(); if (tokenStream.peek() === Tokens.IDENT) { type = this._media_type(); if (token === null) { token = tokenStream.token(); } } else if (tokenStream.peek() === Tokens.LPAREN) { if (token === null) { token = tokenStream.LT(1); } expressions.push(this._media_expression()); } if (type === null && expressions.length === 0) { return null; } else { this._readWhitespace(); while (tokenStream.match(Tokens.IDENT)) { if (tokenStream.token().value.toLowerCase() !== "and") { this._unexpectedToken(tokenStream.token()); } this._readWhitespace(); expressions.push(this._media_expression()); } } return new MediaQuery(ident, type, expressions, token.startLine, token.startCol); }, _media_type: function() { return this._media_feature(); }, _media_expression: function() { var tokenStream = this._tokenStream, feature = null, token, expression = null; tokenStream.mustMatch(Tokens.LPAREN); this._readWhitespace(); feature = this._media_feature(); this._readWhitespace(); if (tokenStream.match(Tokens.COLON)) { this._readWhitespace(); token = tokenStream.LT(1); expression = this._expression(); } tokenStream.mustMatch(Tokens.RPAREN); this._readWhitespace(); return new MediaFeature(feature, expression ? new SyntaxUnit(expression, token.startLine, token.startCol) : null); }, _media_feature: function() { var tokenStream = this._tokenStream; this._readWhitespace(); tokenStream.mustMatch(Tokens.IDENT); return SyntaxUnit.fromToken(tokenStream.token()); }, _page: function() { var tokenStream = this._tokenStream, line, col, identifier = null, pseudoPage = null; tokenStream.mustMatch(Tokens.PAGE_SYM); line = tokenStream.token().startLine; col = tokenStream.token().startCol; this._readWhitespace(); if (tokenStream.match(Tokens.IDENT)) { identifier = tokenStream.token().value; if (identifier.toLowerCase() === "auto") { this._unexpectedToken(tokenStream.token()); } } if (tokenStream.peek() === Tokens.COLON) { pseudoPage = this._pseudo_page(); } this._readWhitespace(); this.fire({ type: "startpage", id: identifier, pseudo: pseudoPage, line: line, col: col }); this._readDeclarations(true, true); this.fire({ type: "endpage", id: identifier, pseudo: pseudoPage, line: line, col: col }); }, _margin: function() { var tokenStream = this._tokenStream, line, col, marginSym = this._margin_sym(); if (marginSym) { line = tokenStream.token().startLine; col = tokenStream.token().startCol; this.fire({ type: "startpagemargin", margin: marginSym, line: line, col: col }); this._readDeclarations(true); this.fire({ type: "endpagemargin", margin: marginSym, line: line, col: col }); return true; } else { return false; } }, _margin_sym: function() { var tokenStream = this._tokenStream; if (tokenStream.match([Tokens.TOPLEFTCORNER_SYM, Tokens.TOPLEFT_SYM, Tokens.TOPCENTER_SYM, Tokens.TOPRIGHT_SYM, Tokens.TOPRIGHTCORNER_SYM, Tokens.BOTTOMLEFTCORNER_SYM, Tokens.BOTTOMLEFT_SYM, Tokens.BOTTOMCENTER_SYM, Tokens.BOTTOMRIGHT_SYM, Tokens.BOTTOMRIGHTCORNER_SYM, Tokens.LEFTTOP_SYM, Tokens.LEFTMIDDLE_SYM, Tokens.LEFTBOTTOM_SYM, Tokens.RIGHTTOP_SYM, Tokens.RIGHTMIDDLE_SYM, Tokens.RIGHTBOTTOM_SYM])) { return SyntaxUnit.fromToken(tokenStream.token()); } else { return null; } }, _pseudo_page: function() { var tokenStream = this._tokenStream; tokenStream.mustMatch(Tokens.COLON); tokenStream.mustMatch(Tokens.IDENT); return tokenStream.token().value; }, _font_face: function() { var tokenStream = this._tokenStream, line, col; tokenStream.mustMatch(Tokens.FONT_FACE_SYM); line = tokenStream.token().startLine; col = tokenStream.token().startCol; this._readWhitespace(); this.fire({ type: "startfontface", line: line, col: col }); this._readDeclarations(true); this.fire({ type: "endfontface", line: line, col: col }); }, _viewport: function() { var tokenStream = this._tokenStream, line, col; tokenStream.mustMatch(Tokens.VIEWPORT_SYM); line = tokenStream.token().startLine; col = tokenStream.token().startCol; this._readWhitespace(); this.fire({ type: "startviewport", line: line, col: col }); this._readDeclarations(true); this.fire({ type: "endviewport", line: line, col: col }); }, _document: function() { var tokenStream = this._tokenStream, token, functions = [], prefix = ""; tokenStream.mustMatch(Tokens.DOCUMENT_SYM); token = tokenStream.token(); if (/^@-([^-]+)-/.test(token.value)) { prefix = RegExp.$1; } this._readWhitespace(); functions.push(this._document_function()); while (tokenStream.match(Tokens.COMMA)) { this._readWhitespace(); functions.push(this._document_function()); } tokenStream.mustMatch(Tokens.LBRACE); this._readWhitespace(); this.fire({ type: "startdocument", functions: functions, prefix: prefix, line: token.startLine, col: token.startCol }); var ok = true; while (ok) { switch (tokenStream.peek()) { case Tokens.PAGE_SYM: this._page(); break; case Tokens.FONT_FACE_SYM: this._font_face(); break; case Tokens.VIEWPORT_SYM: this._viewport(); break; case Tokens.MEDIA_SYM: this._media(); break; case Tokens.KEYFRAMES_SYM: this._keyframes(); break; case Tokens.DOCUMENT_SYM: this._document(); break; default: ok = Boolean(this._ruleset()); } } tokenStream.mustMatch(Tokens.RBRACE); token = tokenStream.token(); this._readWhitespace(); this.fire({ type: "enddocument", functions: functions, prefix: prefix, line: token.startLine, col: token.startCol }); }, _document_function: function() { var tokenStream = this._tokenStream, value; if (tokenStream.match(Tokens.URI)) { value = tokenStream.token().value; this._readWhitespace(); } else { value = this._function(); } return value; }, _operator: function(inFunction) { var tokenStream = this._tokenStream, token = null; if (tokenStream.match([Tokens.SLASH, Tokens.COMMA]) || inFunction && tokenStream.match([Tokens.PLUS, Tokens.STAR, Tokens.MINUS])) { token = tokenStream.token(); this._readWhitespace(); } return token ? PropertyValuePart.fromToken(token) : null; }, _combinator: function() { var tokenStream = this._tokenStream, value = null, token; if (tokenStream.match([Tokens.PLUS, Tokens.GREATER, Tokens.TILDE])) { token = tokenStream.token(); value = new Combinator(token.value, token.startLine, token.startCol); this._readWhitespace(); } return value; }, _unary_operator: function() { var tokenStream = this._tokenStream; if (tokenStream.match([Tokens.MINUS, Tokens.PLUS])) { return tokenStream.token().value; } else { return null; } }, _property: function() { var tokenStream = this._tokenStream, value = null, hack = null, propertyName = "", token, line, col; if (tokenStream.peek() === Tokens.STAR && this.options.starHack) { tokenStream.get(); token = tokenStream.token(); hack = token.value; line = token.startLine; col = token.startCol; } if (tokenStream.peek() === Tokens.MINUS) { tokenStream.get(); token = tokenStream.token(); propertyName = token.value; line = token.startLine; col = token.startCol; } if (tokenStream.match(Tokens.IDENT)) { token = tokenStream.token(); propertyName += token.value; if (propertyName.charAt(0) === "_" && this.options.underscoreHack) { hack = "_"; propertyName = propertyName.substring(1); } value = new PropertyName(propertyName, hack, line || token.startLine, col || token.startCol); this._readWhitespace(); } else { var tt = tokenStream.peek(); if (tt !== Tokens.EOF && tt !== Tokens.RBRACE) { this._unexpectedToken(tokenStream.LT(1)); } } return value; }, _ruleset: function() { var tokenStream = this._tokenStream, tt, selectors; try { selectors = this._selectors_group(); } catch (ex) { if (ex instanceof SyntaxError && !this.options.strict) { this.fire({ type: "error", error: ex, message: ex.message, line: ex.line, col: ex.col }); tt = tokenStream.advance([Tokens.RBRACE]); if (tt === Tokens.RBRACE) { } else { throw ex; } } else { throw ex; } return true; } if (selectors) { this.fire({ type: "startrule", selectors: selectors, line: selectors[0].line, col: selectors[0].col }); this._readDeclarations(true); this.fire({ type: "endrule", selectors: selectors, line: selectors[0].line, col: selectors[0].col }); } return selectors; }, _selectors_group: function() { var tokenStream = this._tokenStream, selectors = [], selector; selector = this._selector(); if (selector !== null) { selectors.push(selector); while (tokenStream.match(Tokens.COMMA)) { this._readWhitespace(); selector = this._selector(); if (selector !== null) { selectors.push(selector); } else { this._unexpectedToken(tokenStream.LT(1)); } } } return selectors.length ? selectors : null; }, _selector: function() { var tokenStream = this._tokenStream, selector = [], nextSelector = null, combinator = null, ws = null; nextSelector = this._simple_selector_sequence(); if (nextSelector === null) { return null; } selector.push(nextSelector); do { combinator = this._combinator(); if (combinator !== null) { selector.push(combinator); nextSelector = this._simple_selector_sequence(); if (nextSelector === null) { this._unexpectedToken(tokenStream.LT(1)); } else { selector.push(nextSelector); } } else { if (this._readWhitespace()) { ws = new Combinator(tokenStream.token().value, tokenStream.token().startLine, tokenStream.token().startCol); combinator = this._combinator(); nextSelector = this._simple_selector_sequence(); if (nextSelector === null) { if (combinator !== null) { this._unexpectedToken(tokenStream.LT(1)); } } else { if (combinator !== null) { selector.push(combinator); } else { selector.push(ws); } selector.push(nextSelector); } } else { break; } } } while (true); return new Selector(selector, selector[0].line, selector[0].col); }, _simple_selector_sequence: function() { var tokenStream = this._tokenStream, elementName = null, modifiers = [], selectorText = "", components = [ function() { return tokenStream.match(Tokens.HASH) ? new SelectorSubPart(tokenStream.token().value, "id", tokenStream.token().startLine, tokenStream.token().startCol) : null; }, this._class, this._attrib, this._pseudo, this._negation ], i = 0, len = components.length, component = null, line, col; line = tokenStream.LT(1).startLine; col = tokenStream.LT(1).startCol; elementName = this._type_selector(); if (!elementName) { elementName = this._universal(); } if (elementName !== null) { selectorText += elementName; } while (true) { if (tokenStream.peek() === Tokens.S) { break; } while (i < len && component === null) { component = components[i++].call(this); } if (component === null) { if (selectorText === "") { return null; } else { break; } } else { i = 0; modifiers.push(component); selectorText += component.toString(); component = null; } } return selectorText !== "" ? new SelectorPart(elementName, modifiers, selectorText, line, col) : null; }, _type_selector: function() { var tokenStream = this._tokenStream, ns = this._namespace_prefix(), elementName = this._element_name(); if (!elementName) { if (ns) { tokenStream.unget(); if (ns.length > 1) { tokenStream.unget(); } } return null; } else { if (ns) { elementName.text = ns + elementName.text; elementName.col -= ns.length; } return elementName; } }, _class: function() { var tokenStream = this._tokenStream, token; if (tokenStream.match(Tokens.DOT)) { tokenStream.mustMatch(Tokens.IDENT); token = tokenStream.token(); return new SelectorSubPart("." + token.value, "class", token.startLine, token.startCol - 1); } else { return null; } }, _element_name: function() { var tokenStream = this._tokenStream, token; if (tokenStream.match(Tokens.IDENT)) { token = tokenStream.token(); return new SelectorSubPart(token.value, "elementName", token.startLine, token.startCol); } else { return null; } }, _namespace_prefix: function() { var tokenStream = this._tokenStream, value = ""; if (tokenStream.LA(1) === Tokens.PIPE || tokenStream.LA(2) === Tokens.PIPE) { if (tokenStream.match([Tokens.IDENT, Tokens.STAR])) { value += tokenStream.token().value; } tokenStream.mustMatch(Tokens.PIPE); value += "|"; } return value.length ? value : null; }, _universal: function() { var tokenStream = this._tokenStream, value = "", ns; ns = this._namespace_prefix(); if (ns) { value += ns; } if (tokenStream.match(Tokens.STAR)) { value += "*"; } return value.length ? value : null; }, _attrib: function() { var tokenStream = this._tokenStream, value = null, ns, token; if (tokenStream.match(Tokens.LBRACKET)) { token = tokenStream.token(); value = token.value; value += this._readWhitespace(); ns = this._namespace_prefix(); if (ns) { value += ns; } tokenStream.mustMatch(Tokens.IDENT); value += tokenStream.token().value; value += this._readWhitespace(); if (tokenStream.match([Tokens.PREFIXMATCH, Tokens.SUFFIXMATCH, Tokens.SUBSTRINGMATCH, Tokens.EQUALS, Tokens.INCLUDES, Tokens.DASHMATCH])) { value += tokenStream.token().value; value += this._readWhitespace(); tokenStream.mustMatch([Tokens.IDENT, Tokens.STRING]); value += tokenStream.token().value; value += this._readWhitespace(); } tokenStream.mustMatch(Tokens.RBRACKET); return new SelectorSubPart(value + "]", "attribute", token.startLine, token.startCol); } else { return null; } }, _pseudo: function() { var tokenStream = this._tokenStream, pseudo = null, colons = ":", line, col; if (tokenStream.match(Tokens.COLON)) { if (tokenStream.match(Tokens.COLON)) { colons += ":"; } if (tokenStream.match(Tokens.IDENT)) { pseudo = tokenStream.token().value; line = tokenStream.token().startLine; col = tokenStream.token().startCol - colons.length; } else if (tokenStream.peek() === Tokens.FUNCTION) { line = tokenStream.LT(1).startLine; col = tokenStream.LT(1).startCol - colons.length; pseudo = this._functional_pseudo(); } if (pseudo) { pseudo = new SelectorSubPart(colons + pseudo, "pseudo", line, col); } else { var startLine = tokenStream.LT(1).startLine, startCol = tokenStream.LT(0).startCol; throw new SyntaxError("Expected a `FUNCTION` or `IDENT` after colon at line " + startLine + ", col " + startCol + ".", startLine, startCol); } } return pseudo; }, _functional_pseudo: function() { var tokenStream = this._tokenStream, value = null; if (tokenStream.match(Tokens.FUNCTION)) { value = tokenStream.token().value; value += this._readWhitespace(); value += this._expression(); tokenStream.mustMatch(Tokens.RPAREN); value += ")"; } return value; }, _expression: function() { var tokenStream = this._tokenStream, value = ""; while (tokenStream.match([Tokens.PLUS, Tokens.MINUS, Tokens.DIMENSION, Tokens.NUMBER, Tokens.STRING, Tokens.IDENT, Tokens.LENGTH, Tokens.FREQ, Tokens.ANGLE, Tokens.TIME, Tokens.RESOLUTION, Tokens.SLASH])) { value += tokenStream.token().value; value += this._readWhitespace(); } return value.length ? value : null; }, _negation: function() { var tokenStream = this._tokenStream, line, col, value = "", arg, subpart = null; if (tokenStream.match(Tokens.NOT)) { value = tokenStream.token().value; line = tokenStream.token().startLine; col = tokenStream.token().startCol; value += this._readWhitespace(); arg = this._negation_arg(); value += arg; value += this._readWhitespace(); tokenStream.match(Tokens.RPAREN); value += tokenStream.token().value; subpart = new SelectorSubPart(value, "not", line, col); subpart.args.push(arg); } return subpart; }, _negation_arg: function() { var tokenStream = this._tokenStream, args = [ this._type_selector, this._universal, function() { return tokenStream.match(Tokens.HASH) ? new SelectorSubPart(tokenStream.token().value, "id", tokenStream.token().startLine, tokenStream.token().startCol) : null; }, this._class, this._attrib, this._pseudo ], arg = null, i = 0, len = args.length, line, col, part; line = tokenStream.LT(1).startLine; col = tokenStream.LT(1).startCol; while (i < len && arg === null) { arg = args[i].call(this); i++; } if (arg === null) { this._unexpectedToken(tokenStream.LT(1)); } if (arg.type === "elementName") { part = new SelectorPart(arg, [], arg.toString(), line, col); } else { part = new SelectorPart(null, [arg], arg.toString(), line, col); } return part; }, _declaration: function() { var tokenStream = this._tokenStream, property = null, expr = null, prio = null, invalid = null, propertyName = ""; property = this._property(); if (property !== null) { tokenStream.mustMatch(Tokens.COLON); this._readWhitespace(); expr = this._expr(); if (!expr || expr.length === 0) { this._unexpectedToken(tokenStream.LT(1)); } prio = this._prio(); propertyName = property.toString(); if (this.options.starHack && property.hack === "*" || this.options.underscoreHack && property.hack === "_") { propertyName = property.text; } try { this._validateProperty(propertyName, expr); } catch (ex) { invalid = ex; } this.fire({ type: "property", property: property, value: expr, important: prio, line: property.line, col: property.col, invalid: invalid }); return true; } else { return false; } }, _prio: function() { var tokenStream = this._tokenStream, result = tokenStream.match(Tokens.IMPORTANT_SYM); this._readWhitespace(); return result; }, _expr: function(inFunction) { var values = [], value = null, operator = null; value = this._term(inFunction); if (value !== null) { values.push(value); do { operator = this._operator(inFunction); if (operator) { values.push(operator); } /*else { values.push(new PropertyValue(valueParts, valueParts[0].line, valueParts[0].col)); valueParts = []; }*/ value = this._term(inFunction); if (value === null) { break; } else { values.push(value); } } while (true); } return values.length > 0 ? new PropertyValue(values, values[0].line, values[0].col) : null; }, _term: function(inFunction) { var tokenStream = this._tokenStream, unary = null, value = null, endChar = null, part = null, token, line, col; unary = this._unary_operator(); if (unary !== null) { line = tokenStream.token().startLine; col = tokenStream.token().startCol; } if (tokenStream.peek() === Tokens.IE_FUNCTION && this.options.ieFilters) { value = this._ie_function(); if (unary === null) { line = tokenStream.token().startLine; col = tokenStream.token().startCol; } } else if (inFunction && tokenStream.match([Tokens.LPAREN, Tokens.LBRACE, Tokens.LBRACKET])) { token = tokenStream.token(); endChar = token.endChar; value = token.value + this._expr(inFunction).text; if (unary === null) { line = tokenStream.token().startLine; col = tokenStream.token().startCol; } tokenStream.mustMatch(Tokens.type(endChar)); value += endChar; this._readWhitespace(); } else if (tokenStream.match([Tokens.NUMBER, Tokens.PERCENTAGE, Tokens.LENGTH, Tokens.ANGLE, Tokens.TIME, Tokens.FREQ, Tokens.STRING, Tokens.IDENT, Tokens.URI, Tokens.UNICODE_RANGE])) { value = tokenStream.token().value; if (unary === null) { line = tokenStream.token().startLine; col = tokenStream.token().startCol; part = PropertyValuePart.fromToken(tokenStream.token()); } this._readWhitespace(); } else { token = this._hexcolor(); if (token === null) { if (unary === null) { line = tokenStream.LT(1).startLine; col = tokenStream.LT(1).startCol; } if (value === null) { if (tokenStream.LA(3) === Tokens.EQUALS && this.options.ieFilters) { value = this._ie_function(); } else { value = this._function(); } } } else { value = token.value; if (unary === null) { line = token.startLine; col = token.startCol; } } } return part !== null ? part : value !== null ? new PropertyValuePart(unary !== null ? unary + value : value, line, col) : null; }, _function: function() { var tokenStream = this._tokenStream, functionText = null, expr = null, lt; if (tokenStream.match(Tokens.FUNCTION)) { functionText = tokenStream.token().value; this._readWhitespace(); expr = this._expr(true); functionText += expr; if (this.options.ieFilters && tokenStream.peek() === Tokens.EQUALS) { do { if (this._readWhitespace()) { functionText += tokenStream.token().value; } if (tokenStream.LA(0) === Tokens.COMMA) { functionText += tokenStream.token().value; } tokenStream.match(Tokens.IDENT); functionText += tokenStream.token().value; tokenStream.match(Tokens.EQUALS); functionText += tokenStream.token().value; lt = tokenStream.peek(); while (lt !== Tokens.COMMA && lt !== Tokens.S && lt !== Tokens.RPAREN) { tokenStream.get(); functionText += tokenStream.token().value; lt = tokenStream.peek(); } } while (tokenStream.match([Tokens.COMMA, Tokens.S])); } tokenStream.match(Tokens.RPAREN); functionText += ")"; this._readWhitespace(); } return functionText; }, _ie_function: function() { var tokenStream = this._tokenStream, functionText = null, lt; if (tokenStream.match([Tokens.IE_FUNCTION, Tokens.FUNCTION])) { functionText = tokenStream.token().value; do { if (this._readWhitespace()) { functionText += tokenStream.token().value; } if (tokenStream.LA(0) === Tokens.COMMA) { functionText += tokenStream.token().value; } tokenStream.match(Tokens.IDENT); functionText += tokenStream.token().value; tokenStream.match(Tokens.EQUALS); functionText += tokenStream.token().value; lt = tokenStream.peek(); while (lt !== Tokens.COMMA && lt !== Tokens.S && lt !== Tokens.RPAREN) { tokenStream.get(); functionText += tokenStream.token().value; lt = tokenStream.peek(); } } while (tokenStream.match([Tokens.COMMA, Tokens.S])); tokenStream.match(Tokens.RPAREN); functionText += ")"; this._readWhitespace(); } return functionText; }, _hexcolor: function() { var tokenStream = this._tokenStream, token = null, color; if (tokenStream.match(Tokens.HASH)) { token = tokenStream.token(); color = token.value; if (!/#[a-f0-9]{3,6}/i.test(color)) { throw new SyntaxError("Expected a hex color but found '" + color + "' at line " + token.startLine + ", col " + token.startCol + ".", token.startLine, token.startCol); } this._readWhitespace(); } return token; }, _keyframes: function() { var tokenStream = this._tokenStream, token, tt, name, prefix = ""; tokenStream.mustMatch(Tokens.KEYFRAMES_SYM); token = tokenStream.token(); if (/^@-([^-]+)-/.test(token.value)) { prefix = RegExp.$1; } this._readWhitespace(); name = this._keyframe_name(); this._readWhitespace(); tokenStream.mustMatch(Tokens.LBRACE); this.fire({ type: "startkeyframes", name: name, prefix: prefix, line: token.startLine, col: token.startCol }); this._readWhitespace(); tt = tokenStream.peek(); while (tt === Tokens.IDENT || tt === Tokens.PERCENTAGE) { this._keyframe_rule(); this._readWhitespace(); tt = tokenStream.peek(); } this.fire({ type: "endkeyframes", name: name, prefix: prefix, line: token.startLine, col: token.startCol }); this._readWhitespace(); tokenStream.mustMatch(Tokens.RBRACE); this._readWhitespace(); }, _keyframe_name: function() { var tokenStream = this._tokenStream; tokenStream.mustMatch([Tokens.IDENT, Tokens.STRING]); return SyntaxUnit.fromToken(tokenStream.token()); }, _keyframe_rule: function() { var keyList = this._key_list(); this.fire({ type: "startkeyframerule", keys: keyList, line: keyList[0].line, col: keyList[0].col }); this._readDeclarations(true); this.fire({ type: "endkeyframerule", keys: keyList, line: keyList[0].line, col: keyList[0].col }); }, _key_list: function() { var tokenStream = this._tokenStream, keyList = []; keyList.push(this._key()); this._readWhitespace(); while (tokenStream.match(Tokens.COMMA)) { this._readWhitespace(); keyList.push(this._key()); this._readWhitespace(); } return keyList; }, _key: function() { var tokenStream = this._tokenStream, token; if (tokenStream.match(Tokens.PERCENTAGE)) { return SyntaxUnit.fromToken(tokenStream.token()); } else if (tokenStream.match(Tokens.IDENT)) { token = tokenStream.token(); if (/from|to/i.test(token.value)) { return SyntaxUnit.fromToken(token); } tokenStream.unget(); } this._unexpectedToken(tokenStream.LT(1)); }, _skipCruft: function() { while (this._tokenStream.match([Tokens.S, Tokens.CDO, Tokens.CDC])) { } }, _readDeclarations: function(checkStart, readMargins) { var tokenStream = this._tokenStream, tt; this._readWhitespace(); if (checkStart) { tokenStream.mustMatch(Tokens.LBRACE); } this._readWhitespace(); try { while (true) { if (tokenStream.match(Tokens.SEMICOLON) || (readMargins && this._margin())) { } else if (this._declaration()) { if (!tokenStream.match(Tokens.SEMICOLON)) { break; } } else { break; } this._readWhitespace(); } tokenStream.mustMatch(Tokens.RBRACE); this._readWhitespace(); } catch (ex) { if (ex instanceof SyntaxError && !this.options.strict) { this.fire({ type: "error", error: ex, message: ex.message, line: ex.line, col: ex.col }); tt = tokenStream.advance([Tokens.SEMICOLON, Tokens.RBRACE]); if (tt === Tokens.SEMICOLON) { this._readDeclarations(false, readMargins); } else if (tt !== Tokens.EOF && tt !== Tokens.RBRACE) { throw ex; } } else { throw ex; } } }, _readWhitespace: function() { var tokenStream = this._tokenStream, ws = ""; while (tokenStream.match(Tokens.S)) { ws += tokenStream.token().value; } return ws; }, _unexpectedToken: function(token) { throw new SyntaxError("Unexpected token '" + token.value + "' at line " + token.startLine + ", col " + token.startCol + ".", token.startLine, token.startCol); }, _verifyEnd: function() { if (this._tokenStream.LA(1) !== Tokens.EOF) { this._unexpectedToken(this._tokenStream.LT(1)); } }, _validateProperty: function(property, value) { Validation.validate(property, value); }, parse: function(input) { this._tokenStream = new TokenStream(input, Tokens); this._stylesheet(); }, parseStyleSheet: function(input) { return this.parse(input); }, parseMediaQuery: function(input) { this._tokenStream = new TokenStream(input, Tokens); var result = this._media_query(); this._verifyEnd(); return result; }, parsePropertyValue: function(input) { this._tokenStream = new TokenStream(input, Tokens); this._readWhitespace(); var result = this._expr(); this._readWhitespace(); this._verifyEnd(); return result; }, parseRule: function(input) { this._tokenStream = new TokenStream(input, Tokens); this._readWhitespace(); var result = this._ruleset(); this._readWhitespace(); this._verifyEnd(); return result; }, parseSelector: function(input) { this._tokenStream = new TokenStream(input, Tokens); this._readWhitespace(); var result = this._selector(); this._readWhitespace(); this._verifyEnd(); return result; }, parseStyleAttribute: function(input) { input += "}"; // for error recovery in _readDeclarations() this._tokenStream = new TokenStream(input, Tokens); this._readDeclarations(); } }; for (prop in additions) { if (Object.prototype.hasOwnProperty.call(additions, prop)) { proto[prop] = additions[prop]; } } return proto; }(); },{"../util/EventTarget":23,"../util/SyntaxError":25,"../util/SyntaxUnit":26,"./Combinator":2,"./MediaFeature":4,"./MediaQuery":5,"./PropertyName":8,"./PropertyValue":9,"./PropertyValuePart":11,"./Selector":13,"./SelectorPart":14,"./SelectorSubPart":15,"./TokenStream":17,"./Tokens":18,"./Validation":19}],7:[function(require,module,exports){ "use strict"; var Properties = module.exports = { __proto__: null, "align-items" : "flex-start | flex-end | center | baseline | stretch", "align-content" : "flex-start | flex-end | center | space-between | space-around | stretch", "align-self" : "auto | flex-start | flex-end | center | baseline | stretch", "all" : "initial | inherit | unset", "-webkit-align-items" : "flex-start | flex-end | center | baseline | stretch", "-webkit-align-content" : "flex-start | flex-end | center | space-between | space-around | stretch", "-webkit-align-self" : "auto | flex-start | flex-end | center | baseline | stretch", "alignment-adjust" : "auto | baseline | before-edge | text-before-edge | middle | central | after-edge | text-after-edge | ideographic | alphabetic | hanging | mathematical | <percentage> | <length>", "alignment-baseline" : "auto | baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical", "animation" : 1, "animation-delay" : "<time>#", "animation-direction" : "<single-animation-direction>#", "animation-duration" : "<time>#", "animation-fill-mode" : "[ none | forwards | backwards | both ]#", "animation-iteration-count" : "[ <number> | infinite ]#", "animation-name" : "[ none | <single-animation-name> ]#", "animation-play-state" : "[ running | paused ]#", "animation-timing-function" : 1, "-moz-animation-delay" : "<time>#", "-moz-animation-direction" : "[ normal | alternate ]#", "-moz-animation-duration" : "<time>#", "-moz-animation-iteration-count" : "[ <number> | infinite ]#", "-moz-animation-name" : "[ none | <single-animation-name> ]#", "-moz-animation-play-state" : "[ running | paused ]#", "-ms-animation-delay" : "<time>#", "-ms-animation-direction" : "[ normal | alternate ]#", "-ms-animation-duration" : "<time>#", "-ms-animation-iteration-count" : "[ <number> | infinite ]#", "-ms-animation-name" : "[ none | <single-animation-name> ]#", "-ms-animation-play-state" : "[ running | paused ]#", "-webkit-animation-delay" : "<time>#", "-webkit-animation-direction" : "[ normal | alternate ]#", "-webkit-animation-duration" : "<time>#", "-webkit-animation-fill-mode" : "[ none | forwards | backwards | both ]#", "-webkit-animation-iteration-count" : "[ <number> | infinite ]#", "-webkit-animation-name" : "[ none | <single-animation-name> ]#", "-webkit-animation-play-state" : "[ running | paused ]#", "-o-animation-delay" : "<time>#", "-o-animation-direction" : "[ normal | alternate ]#", "-o-animation-duration" : "<time>#", "-o-animation-iteration-count" : "[ <number> | infinite ]#", "-o-animation-name" : "[ none | <single-animation-name> ]#", "-o-animation-play-state" : "[ running | paused ]#", "appearance" : "none | auto", "-moz-appearance" : "none | button | button-arrow-down | button-arrow-next | button-arrow-previous | button-arrow-up | button-bevel | button-focus | caret | checkbox | checkbox-container | checkbox-label | checkmenuitem | dualbutton | groupbox | listbox | listitem | menuarrow | menubar | menucheckbox | menuimage | menuitem | menuitemtext | menulist | menulist-button | menulist-text | menulist-textfield | menupopup | menuradio | menuseparator | meterbar | meterchunk | progressbar | progressbar-vertical | progresschunk | progresschunk-vertical | radio | radio-container | radio-label | radiomenuitem | range | range-thumb | resizer | resizerpanel | scale-horizontal | scalethumbend | scalethumb-horizontal | scalethumbstart | scalethumbtick | scalethumb-vertical | scale-vertical | scrollbarbutton-down | scrollbarbutton-left | scrollbarbutton-right | scrollbarbutton-up | scrollbarthumb-horizontal | scrollbarthumb-vertical | scrollbartrack-horizontal | scrollbartrack-vertical | searchfield | separator | sheet | spinner | spinner-downbutton | spinner-textfield | spinner-upbutton | splitter | statusbar | statusbarpanel | tab | tabpanel | tabpanels | tab-scroll-arrow-back | tab-scroll-arrow-forward | textfield | textfield-multiline | toolbar | toolbarbutton | toolbarbutton-dropdown | toolbargripper | toolbox | tooltip | treeheader | treeheadercell | treeheadersortarrow | treeitem | treeline | treetwisty | treetwistyopen | treeview | -moz-mac-unified-toolbar | -moz-win-borderless-glass | -moz-win-browsertabbar-toolbox | -moz-win-communicationstext | -moz-win-communications-toolbox | -moz-win-exclude-glass | -moz-win-glass | -moz-win-mediatext | -moz-win-media-toolbox | -moz-window-button-box | -moz-window-button-box-maximized | -moz-window-button-close | -moz-window-button-maximize | -moz-window-button-minimize | -moz-window-button-restore | -moz-window-frame-bottom | -moz-window-frame-left | -moz-window-frame-right | -moz-window-titlebar | -moz-window-titlebar-maximized", "-ms-appearance" : "none | icon | window | desktop | workspace | document | tooltip | dialog | button | push-button | hyperlink | radio | radio-button | checkbox | menu-item | tab | menu | menubar | pull-down-menu | pop-up-menu | list-menu | radio-group | checkbox-group | outline-tree | range | field | combo-box | signature | password | normal", "-webkit-appearance" : "none | button | button-bevel | caps-lock-indicator | caret | checkbox | default-button | listbox | listitem | media-fullscreen-button | media-mute-button | media-play-button | media-seek-back-button | media-seek-forward-button | media-slider | media-sliderthumb | menulist | menulist-button | menulist-text | menulist-textfield | push-button | radio | searchfield | searchfield-cancel-button | searchfield-decoration | searchfield-results-button | searchfield-results-decoration | slider-horizontal | slider-vertical | sliderthumb-horizontal | sliderthumb-vertical | square-button | textarea | textfield | scrollbarbutton-down | scrollbarbutton-left | scrollbarbutton-right | scrollbarbutton-up | scrollbargripper-horizontal | scrollbargripper-vertical | scrollbarthumb-horizontal | scrollbarthumb-vertical | scrollbartrack-horizontal | scrollbartrack-vertical", "-o-appearance" : "none | window | desktop | workspace | document | tooltip | dialog | button | push-button | hyperlink | radio | radio-button | checkbox | menu-item | tab | menu | menubar | pull-down-menu | pop-up-menu | list-menu | radio-group | checkbox-group | outline-tree | range | field | combo-box | signature | password | normal", "azimuth" : "<azimuth>", "backface-visibility" : "visible | hidden", "background" : 1, "background-attachment" : "<attachment>#", "background-clip" : "<box>#", "background-color" : "<color>", "background-image" : "<bg-image>#", "background-origin" : "<box>#", "background-position" : "<bg-position>", "background-repeat" : "<repeat-style>#", "background-size" : "<bg-size>#", "baseline-shift" : "baseline | sub | super | <percentage> | <length>", "behavior" : 1, "binding" : 1, "bleed" : "<length>", "bookmark-label" : "<content> | <attr> | <string>", "bookmark-level" : "none | <integer>", "bookmark-state" : "open | closed", "bookmark-target" : "none | <uri> | <attr>", "border" : "<border-width> || <border-style> || <color>", "border-bottom" : "<border-width> || <border-style> || <color>", "border-bottom-color" : "<color>", "border-bottom-left-radius" : "<x-one-radius>", "border-bottom-right-radius" : "<x-one-radius>", "border-bottom-style" : "<border-style>", "border-bottom-width" : "<border-width>", "border-collapse" : "collapse | separate", "border-color" : "<color>{1,4}", "border-image" : 1, "border-image-outset" : "[ <length> | <number> ]{1,4}", "border-image-repeat" : "[ stretch | repeat | round | space ]{1,2}", "border-image-slice" : "<border-image-slice>", "border-image-source" : "<image> | none", "border-image-width" : "[ <length> | <percentage> | <number> | auto ]{1,4}", "border-left" : "<border-width> || <border-style> || <color>", "border-left-color" : "<color>", "border-left-style" : "<border-style>", "border-left-width" : "<border-width>", "border-radius" : "<border-radius>", "border-right" : "<border-width> || <border-style> || <color>", "border-right-color" : "<color>", "border-right-style" : "<border-style>", "border-right-width" : "<border-width>", "border-spacing" : "<length>{1,2}", "border-style" : "<border-style>{1,4}", "border-top" : "<border-width> || <border-style> || <color>", "border-top-color" : "<color>", "border-top-left-radius" : "<x-one-radius>", "border-top-right-radius" : "<x-one-radius>", "border-top-style" : "<border-style>", "border-top-width" : "<border-width>", "border-width" : "<border-width>{1,4}", "bottom" : "<margin-width>", "-moz-box-align" : "start | end | center | baseline | stretch", "-moz-box-decoration-break" : "slice | clone", "-moz-box-direction" : "normal | reverse", "-moz-box-flex" : "<number>", "-moz-box-flex-group" : "<integer>", "-moz-box-lines" : "single | multiple", "-moz-box-ordinal-group" : "<integer>", "-moz-box-orient" : "horizontal | vertical | inline-axis | block-axis", "-moz-box-pack" : "start | end | center | justify", "-o-box-decoration-break" : "slice | clone", "-webkit-box-align" : "start | end | center | baseline | stretch", "-webkit-box-decoration-break" : "slice | clone", "-webkit-box-direction" : "normal | reverse", "-webkit-box-flex" : "<number>", "-webkit-box-flex-group" : "<integer>", "-webkit-box-lines" : "single | multiple", "-webkit-box-ordinal-group" : "<integer>", "-webkit-box-orient" : "horizontal | vertical | inline-axis | block-axis", "-webkit-box-pack" : "start | end | center | justify", "box-decoration-break" : "slice | clone", "box-shadow" : "<box-shadow>", "box-sizing" : "content-box | border-box", "break-after" : "auto | always | avoid | left | right | page | column | avoid-page | avoid-column", "break-before" : "auto | always | avoid | left | right | page | column | avoid-page | avoid-column", "break-inside" : "auto | avoid | avoid-page | avoid-column", "caption-side" : "top | bottom", "clear" : "none | right | left | both", "clip" : "<shape> | auto", "-webkit-clip-path" : "<clip-source> | <clip-path> | none", "clip-path" : "<clip-source> | <clip-path> | none", "clip-rule" : "nonzero | evenodd", "color" : "<color>", "color-interpolation" : "auto | sRGB | linearRGB", "color-interpolation-filters" : "auto | sRGB | linearRGB", "color-profile" : 1, "color-rendering" : "auto | optimizeSpeed | optimizeQuality", "column-count" : "<integer> | auto", // https ://www.w3.org/TR/css3-multicol/ "column-fill" : "auto | balance", "column-gap" : "<length> | normal", "column-rule" : "<border-width> || <border-style> || <color>", "column-rule-color" : "<color>", "column-rule-style" : "<border-style>", "column-rule-width" : "<border-width>", "column-span" : "none | all", "column-width" : "<length> | auto", "columns" : 1, "content" : 1, "counter-increment" : 1, "counter-reset" : 1, "crop" : "<shape> | auto", "cue" : "cue-after | cue-before", "cue-after" : 1, "cue-before" : 1, "cursor" : 1, "direction" : "ltr | rtl", "display" : "inline | block | list-item | inline-block | table | inline-table | table-row-group | table-header-group | table-footer-group | table-row | table-column-group | table-column | table-cell | table-caption | grid | inline-grid | run-in | ruby | ruby-base | ruby-text | ruby-base-container | ruby-text-container | contents | none | -moz-box | -moz-inline-block | -moz-inline-box | -moz-inline-grid | -moz-inline-stack | -moz-inline-table | -moz-grid | -moz-grid-group | -moz-grid-line | -moz-groupbox | -moz-deck | -moz-popup | -moz-stack | -moz-marker | -webkit-box | -webkit-inline-box | -ms-flexbox | -ms-inline-flexbox | flex | -webkit-flex | inline-flex | -webkit-inline-flex", "dominant-baseline" : "auto | use-script | no-change | reset-size | ideographic | alphabetic | hanging | mathematical | central | middle | text-after-edge | text-before-edge", "drop-initial-after-adjust" : "central | middle | after-edge | text-after-edge | ideographic | alphabetic | mathematical | <percentage> | <length>", "drop-initial-after-align" : "baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical", "drop-initial-before-adjust" : "before-edge | text-before-edge | central | middle | hanging | mathematical | <percentage> | <length>", "drop-initial-before-align" : "caps-height | baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical", "drop-initial-size" : "auto | line | <length> | <percentage>", "drop-initial-value" : "<integer>", "elevation" : "<angle> | below | level | above | higher | lower", "empty-cells" : "show | hide", "enable-background" : 1, "fill" : "<paint>", "fill-opacity" : "<opacity-value>", "fill-rule" : "nonzero | evenodd", "filter" : "<filter-function-list> | none", "fit" : "fill | hidden | meet | slice", "fit-position" : 1, "flex" : "<flex>", "flex-basis" : "<width>", "flex-direction" : "row | row-reverse | column | column-reverse", "flex-flow" : "<flex-direction> || <flex-wrap>", "flex-grow" : "<number>", "flex-shrink" : "<number>", "flex-wrap" : "nowrap | wrap | wrap-reverse", "-webkit-flex" : "<flex>", "-webkit-flex-basis" : "<width>", "-webkit-flex-direction" : "row | row-reverse | column | column-reverse", "-webkit-flex-flow" : "<flex-direction> || <flex-wrap>", "-webkit-flex-grow" : "<number>", "-webkit-flex-shrink" : "<number>", "-webkit-flex-wrap" : "nowrap | wrap | wrap-reverse", "-ms-flex" : "<flex>", "-ms-flex-align" : "start | end | center | stretch | baseline", "-ms-flex-direction" : "row | row-reverse | column | column-reverse", "-ms-flex-order" : "<number>", "-ms-flex-pack" : "start | end | center | justify | distribute", "-ms-flex-wrap" : "nowrap | wrap | wrap-reverse", "float" : "left | right | none", "float-offset" : 1, "flood-color" : 1, "flood-opacity" : "<opacity-value>", "font" : "<font-shorthand> | caption | icon | menu | message-box | small-caption | status-bar", "font-family" : "<font-family>", "font-feature-settings" : "<feature-tag-value> | normal", "font-kerning" : "auto | normal | none", "font-size" : "<font-size>", "font-size-adjust" : "<number> | none", "font-stretch" : "<font-stretch>", "font-style" : "<font-style>", "font-variant" : "<font-variant> | normal | none", "font-variant-alternates" : "<font-variant-alternates> | normal", "font-variant-caps" : "<font-variant-caps> | normal", "font-variant-east-asian" : "<font-variant-east-asian> | normal", "font-variant-ligatures" : "<font-variant-ligatures> | normal | none", "font-variant-numeric" : "<font-variant-numeric> | normal", "font-variant-position" : "normal | sub | super", "font-weight" : "<font-weight>", "gap" : "[ <length> | <percentage> ]{1,2}", "glyph-orientation-horizontal" : "<glyph-angle>", "glyph-orientation-vertical" : "auto | <glyph-angle>", "grid" : 1, "grid-area" : 1, "grid-auto-columns" : 1, "grid-auto-flow" : 1, "grid-auto-position" : 1, "grid-auto-rows" : 1, "grid-cell-stacking" : "columns | rows | layer", "grid-column" : 1, "grid-columns" : 1, "grid-column-align" : "start | end | center | stretch", "grid-column-sizing" : 1, "grid-column-start" : 1, "grid-column-end" : 1, "grid-column-span" : "<integer>", "grid-flow" : "none | rows | columns", "grid-gap" : "[ <length> | <percentage> ]{1,2}", "grid-layer" : "<integer>", "grid-row" : 1, "grid-rows" : 1, "grid-row-align" : "start | end | center | stretch", "grid-row-gap" : 1, "grid-row-start" : 1, "grid-row-end" : 1, "grid-row-span" : "<integer>", "grid-row-sizing" : 1, "grid-template" : 1, "grid-template-areas" : 1, "grid-template-columns" : 1, "grid-template-rows" : 1, "hanging-punctuation" : 1, "height" : "<margin-width> | <content-sizing>", "hyphenate-after" : "<integer> | auto", "hyphenate-before" : "<integer> | auto", "hyphenate-character" : "<string> | auto", "hyphenate-lines" : "no-limit | <integer>", "hyphenate-resource" : 1, "hyphens" : "none | manual | auto", "icon" : 1, "image-orientation" : "angle | auto", "image-rendering" : "auto | optimizeSpeed | optimizeQuality", "image-resolution" : 1, "ime-mode" : "auto | normal | active | inactive | disabled", "inline-box-align" : "last | <integer>", "justify-content" : "flex-start | flex-end | center | space-between | space-around | space-evenly | stretch", "-webkit-justify-content" : "flex-start | flex-end | center | space-between | space-around | space-evenly | stretch", "kerning" : "auto | <length>", "left" : "<margin-width>", "letter-spacing" : "<length> | normal", "line-height" : "<line-height>", "line-break" : "auto | loose | normal | strict", "line-stacking" : 1, "line-stacking-ruby" : "exclude-ruby | include-ruby", "line-stacking-shift" : "consider-shifts | disregard-shifts", "line-stacking-strategy" : "inline-line-height | block-line-height | max-height | grid-height", "list-style" : 1, "list-style-image" : "<uri> | none", "list-style-position" : "inside | outside", "list-style-type" : "disc | circle | square | decimal | decimal-leading-zero | lower-roman | upper-roman | lower-greek | lower-latin | upper-latin | armenian | georgian | lower-alpha | upper-alpha | none", "margin" : "<margin-width>{1,4}", "margin-bottom" : "<margin-width>", "margin-left" : "<margin-width>", "margin-right" : "<margin-width>", "margin-top" : "<margin-width>", "mark" : 1, "mark-after" : 1, "mark-before" : 1, "marker" : 1, "marker-end" : 1, "marker-mid" : 1, "marker-start" : 1, "marks" : 1, "marquee-direction" : 1, "marquee-play-count" : 1, "marquee-speed" : 1, "marquee-style" : 1, "mask" : 1, "max-height" : "<length> | <percentage> | <content-sizing> | none", "max-width" : "<length> | <percentage> | <content-sizing> | none", "min-height" : "<length> | <percentage> | <content-sizing> | contain-floats | -moz-contain-floats | -webkit-contain-floats", "min-width" : "<length> | <percentage> | <content-sizing> | contain-floats | -moz-contain-floats | -webkit-contain-floats", "mix-blend-mode" : "<blend-mode>", "move-to" : 1, "nav-down" : 1, "nav-index" : 1, "nav-left" : 1, "nav-right" : 1, "nav-up" : 1, "object-fit" : "fill | contain | cover | none | scale-down", "object-position" : "<position>", "opacity" : "<opacity-value>", "order" : "<integer>", "-webkit-order" : "<integer>", "orphans" : "<integer>", "outline" : 1, "outline-color" : "<color> | invert", "outline-offset" : 1, "outline-style" : "<border-style>", "outline-width" : "<border-width>", "overflow" : "visible | hidden | scroll | auto", "overflow-style" : 1, "overflow-wrap" : "normal | break-word", "overflow-x" : 1, "overflow-y" : 1, "padding" : "<padding-width>{1,4}", "padding-bottom" : "<padding-width>", "padding-left" : "<padding-width>", "padding-right" : "<padding-width>", "padding-top" : "<padding-width>", "page" : 1, "page-break-after" : "auto | always | avoid | left | right", "page-break-before" : "auto | always | avoid | left | right", "page-break-inside" : "auto | avoid", "page-policy" : 1, "pause" : 1, "pause-after" : 1, "pause-before" : 1, "perspective" : 1, "perspective-origin" : 1, "phonemes" : 1, "pitch" : 1, "pitch-range" : 1, "play-during" : 1, "pointer-events" : "auto | none | visiblePainted | visibleFill | visibleStroke | visible | painted | fill | stroke | all", "position" : "static | relative | absolute | fixed | sticky | -webkit-sticky", "presentation-level" : 1, "punctuation-trim" : 1, "quotes" : 1, "rendering-intent" : 1, "resize" : 1, "rest" : 1, "rest-after" : 1, "rest-before" : 1, "richness" : 1, "right" : "<margin-width>", "rotation" : 1, "rotation-point" : 1, "ruby-align" : 1, "ruby-overhang" : 1, "ruby-position" : 1, "ruby-span" : 1, "shape-rendering" : "auto | optimizeSpeed | crispEdges | geometricPrecision", "size" : 1, "speak" : "normal | none | spell-out", "speak-header" : "once | always", "speak-numeral" : "digits | continuous", "speak-punctuation" : "code | none", "speech-rate" : 1, "src" : 1, "stop-color" : 1, "stop-opacity" : "<opacity-value>", "stress" : 1, "string-set" : 1, "stroke" : "<paint>", "stroke-dasharray" : "none | <dasharray>", "stroke-dashoffset" : "<percentage> | <length>", "stroke-linecap" : "butt | round | square", "stroke-linejoin" : "miter | round | bevel", "stroke-miterlimit" : "<miterlimit>", "stroke-opacity" : "<opacity-value>", "stroke-width" : "<percentage> | <length>", "table-layout" : "auto | fixed", "tab-size" : "<integer> | <length>", "target" : 1, "target-name" : 1, "target-new" : 1, "target-position" : 1, "text-align" : "left | right | center | justify | match-parent | start | end", "text-align-last" : 1, "text-anchor" : "start | middle | end", "text-decoration" : "<text-decoration-line> || <text-decoration-style> || <text-decoration-color>", "text-decoration-color" : "<text-decoration-color>", "text-decoration-line" : "<text-decoration-line>", "text-decoration-style" : "<text-decoration-style>", "text-decoration-skip" : "none | [ objects || spaces || ink || edges || box-decoration ]", "-webkit-text-decoration-skip" : "none | [ objects || spaces || ink || edges || box-decoration ]", "text-underline-position" : "auto | [ under || [ left | right ] ]", "text-emphasis" : 1, "text-height" : 1, "text-indent" : "<length> | <percentage>", "text-justify" : "auto | none | inter-word | inter-ideograph | inter-cluster | distribute | kashida", "text-outline" : 1, "text-overflow" : 1, "text-rendering" : "auto | optimizeSpeed | optimizeLegibility | geometricPrecision", "text-shadow" : 1, "text-transform" : "capitalize | uppercase | lowercase | none", "text-wrap" : "normal | none | avoid", "top" : "<margin-width>", "-ms-touch-action" : "auto | none | pan-x | pan-y | pan-left | pan-right | pan-up | pan-down | manipulation", "touch-action" : "auto | none | pan-x | pan-y | pan-left | pan-right | pan-up | pan-down | manipulation", "transform" : 1, "transform-origin" : 1, "transform-style" : 1, "transition" : 1, "transition-delay" : 1, "transition-duration" : 1, "transition-property" : 1, "transition-timing-function" : 1, "unicode-bidi" : "normal | embed | isolate | bidi-override | isolate-override | plaintext", "user-modify" : "read-only | read-write | write-only", "user-select" : "auto | text | none | contain | all", "vertical-align" : "auto | use-script | baseline | sub | super | top | text-top | central | middle | bottom | text-bottom | <percentage> | <length>", "visibility" : "visible | hidden | collapse", "voice-balance" : 1, "voice-duration" : 1, "voice-family" : 1, "voice-pitch" : 1, "voice-pitch-range" : 1, "voice-rate" : 1, "voice-stress" : 1, "voice-volume" : 1, "volume" : 1, "white-space" : "normal | pre | nowrap | pre-wrap | pre-line | -pre-wrap | -o-pre-wrap | -moz-pre-wrap | -hp-pre-wrap", // https ://perishablepress.com/wrapping-content/ "white-space-collapse" : 1, "widows" : "<integer>", "width" : "<length> | <percentage> | <content-sizing> | auto", "will-change" : "<will-change>", "word-break" : "normal | keep-all | break-all | break-word", "word-spacing" : "<length> | normal", "word-wrap" : "normal | break-word", "writing-mode" : "horizontal-tb | vertical-rl | vertical-lr | lr-tb | rl-tb | tb-rl | bt-rl | tb-lr | bt-lr | lr-bt | rl-bt | lr | rl | tb", "z-index" : "<integer> | auto", "zoom" : "<number> | <percentage> | normal" }; },{}],8:[function(require,module,exports){ "use strict"; module.exports = PropertyName; var SyntaxUnit = require("../util/SyntaxUnit"); var Parser = require("./Parser"); function PropertyName(text, hack, line, col) { SyntaxUnit.call(this, text, line, col, Parser.PROPERTY_NAME_TYPE); this.hack = hack; } PropertyName.prototype = new SyntaxUnit(); PropertyName.prototype.constructor = PropertyName; PropertyName.prototype.toString = function() { return (this.hack ? this.hack : "") + this.text; }; },{"../util/SyntaxUnit":26,"./Parser":6}],9:[function(require,module,exports){ "use strict"; module.exports = PropertyValue; var SyntaxUnit = require("../util/SyntaxUnit"); var Parser = require("./Parser"); function PropertyValue(parts, line, col) { SyntaxUnit.call(this, parts.join(" "), line, col, Parser.PROPERTY_VALUE_TYPE); this.parts = parts; } PropertyValue.prototype = new SyntaxUnit(); PropertyValue.prototype.constructor = PropertyValue; },{"../util/SyntaxUnit":26,"./Parser":6}],10:[function(require,module,exports){ "use strict"; module.exports = PropertyValueIterator; function PropertyValueIterator(value) { this._i = 0; this._parts = value.parts; this._marks = []; this.value = value; } PropertyValueIterator.prototype.count = function() { return this._parts.length; }; PropertyValueIterator.prototype.isFirst = function() { return this._i === 0; }; PropertyValueIterator.prototype.hasNext = function() { return this._i < this._parts.length; }; PropertyValueIterator.prototype.mark = function() { this._marks.push(this._i); }; PropertyValueIterator.prototype.peek = function(count) { return this.hasNext() ? this._parts[this._i + (count || 0)] : null; }; PropertyValueIterator.prototype.next = function() { return this.hasNext() ? this._parts[this._i++] : null; }; PropertyValueIterator.prototype.previous = function() { return this._i > 0 ? this._parts[--this._i] : null; }; PropertyValueIterator.prototype.restore = function() { if (this._marks.length) { this._i = this._marks.pop(); } }; PropertyValueIterator.prototype.drop = function() { this._marks.pop(); }; },{}],11:[function(require,module,exports){ "use strict"; module.exports = PropertyValuePart; var SyntaxUnit = require("../util/SyntaxUnit"); var Colors = require("./Colors"); var Parser = require("./Parser"); var Tokens = require("./Tokens"); function PropertyValuePart(text, line, col, optionalHint) { var hint = optionalHint || {}; SyntaxUnit.call(this, text, line, col, Parser.PROPERTY_VALUE_PART_TYPE); this.type = "unknown"; var temp; if (/^([+-]?[\d.]+)([a-z]+)$/i.test(text)) { // dimension this.type = "dimension"; this.value = Number(RegExp.$1); this.units = RegExp.$2; switch (this.units.toLowerCase()) { case "em": case "rem": case "ex": case "px": case "cm": case "mm": case "in": case "pt": case "pc": case "ch": case "vh": case "vw": case "vmax": case "vmin": this.type = "length"; break; case "fr": this.type = "grid"; break; case "deg": case "rad": case "grad": case "turn": this.type = "angle"; break; case "ms": case "s": this.type = "time"; break; case "hz": case "khz": this.type = "frequency"; break; case "dpi": case "dpcm": this.type = "resolution"; break; } } else if (/^([+-]?[\d.]+)%$/i.test(text)) { // percentage this.type = "percentage"; this.value = Number(RegExp.$1); } else if (/^([+-]?\d+)$/i.test(text)) { // integer this.type = "integer"; this.value = Number(RegExp.$1); } else if (/^([+-]?[\d.]+)$/i.test(text)) { // number this.type = "number"; this.value = Number(RegExp.$1); } else if (/^#([a-f0-9]{3,6})/i.test(text)) { // hexcolor this.type = "color"; temp = RegExp.$1; if (temp.length === 3) { this.red = parseInt(temp.charAt(0) + temp.charAt(0), 16); this.green = parseInt(temp.charAt(1) + temp.charAt(1), 16); this.blue = parseInt(temp.charAt(2) + temp.charAt(2), 16); } else { this.red = parseInt(temp.substring(0, 2), 16); this.green = parseInt(temp.substring(2, 4), 16); this.blue = parseInt(temp.substring(4, 6), 16); } } else if (/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/i.test(text)) { // rgb() color with absolute numbers this.type = "color"; this.red = Number(RegExp.$1); this.green = Number(RegExp.$2); this.blue = Number(RegExp.$3); } else if (/^rgb\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)/i.test(text)) { // rgb() color with percentages this.type = "color"; this.red = Number(RegExp.$1) * 255 / 100; this.green = Number(RegExp.$2) * 255 / 100; this.blue = Number(RegExp.$3) * 255 / 100; } else if (/^rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d.]+)\s*\)/i.test(text)) { // rgba() color with absolute numbers this.type = "color"; this.red = Number(RegExp.$1); this.green = Number(RegExp.$2); this.blue = Number(RegExp.$3); this.alpha = Number(RegExp.$4); } else if (/^rgba\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*,\s*([\d.]+)\s*\)/i.test(text)) { // rgba() color with percentages this.type = "color"; this.red = Number(RegExp.$1) * 255 / 100; this.green = Number(RegExp.$2) * 255 / 100; this.blue = Number(RegExp.$3) * 255 / 100; this.alpha = Number(RegExp.$4); } else if (/^hsl\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)/i.test(text)) { // hsl() this.type = "color"; this.hue = Number(RegExp.$1); this.saturation = Number(RegExp.$2) / 100; this.lightness = Number(RegExp.$3) / 100; } else if (/^hsla\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*,\s*([\d.]+)\s*\)/i.test(text)) { // hsla() color with percentages this.type = "color"; this.hue = Number(RegExp.$1); this.saturation = Number(RegExp.$2) / 100; this.lightness = Number(RegExp.$3) / 100; this.alpha = Number(RegExp.$4); } else if (/^url\(("([^\\"]|\.)*")\)/i.test(text)) { // URI this.type = "uri"; this.uri = PropertyValuePart.parseString(RegExp.$1); } else if (/^([^(]+)\(/i.test(text)) { this.type = "function"; this.name = RegExp.$1; this.value = text; } else if (/^"([^\n\r\f\\"]|\\\r\n|\\[^\r0-9a-f]|\\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?)*"/i.test(text)) { // double-quoted string this.type = "string"; this.value = PropertyValuePart.parseString(text); } else if (/^'([^\n\r\f\\']|\\\r\n|\\[^\r0-9a-f]|\\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?)*'/i.test(text)) { // single-quoted string this.type = "string"; this.value = PropertyValuePart.parseString(text); } else if (Colors[text.toLowerCase()]) { // named color this.type = "color"; temp = Colors[text.toLowerCase()].substring(1); this.red = parseInt(temp.substring(0, 2), 16); this.green = parseInt(temp.substring(2, 4), 16); this.blue = parseInt(temp.substring(4, 6), 16); } else if (/^[,/]$/.test(text)) { this.type = "operator"; this.value = text; } else if (/^-?[a-z_\u00A0-\uFFFF][a-z0-9\-_\u00A0-\uFFFF]*$/i.test(text)) { this.type = "identifier"; this.value = text; } this.wasIdent = Boolean(hint.ident); } PropertyValuePart.prototype = new SyntaxUnit(); PropertyValuePart.prototype.constructor = PropertyValuePart; PropertyValuePart.parseString = function(str) { str = str.slice(1, -1); // Strip surrounding single/double quotes var replacer = function(match, esc) { if (/^(\n|\r\n|\r|\f)$/.test(esc)) { return ""; } var m = /^[0-9a-f]{1,6}/i.exec(esc); if (m) { var codePoint = parseInt(m[0], 16); if (String.fromCodePoint) { return String.fromCodePoint(codePoint); } else { return String.fromCharCode(codePoint); } } return esc; }; return str.replace(/\\(\r\n|[^\r0-9a-f]|[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?)/ig, replacer); }; PropertyValuePart.serializeString = function(value) { var replacer = function(match, c) { if (c === "\"") { return "\\" + c; } var cp = String.codePointAt ? String.codePointAt(0) : String.charCodeAt(0); return "\\" + cp.toString(16) + " "; }; return "\"" + value.replace(/["\r\n\f]/g, replacer) + "\""; }; PropertyValuePart.fromToken = function(token) { var part = new PropertyValuePart(token.value, token.startLine, token.startCol, { ident: token.type === Tokens.IDENT }); return part; }; },{"../util/SyntaxUnit":26,"./Colors":1,"./Parser":6,"./Tokens":18}],12:[function(require,module,exports){ "use strict"; var Pseudos = module.exports = { __proto__: null, ":first-letter": 1, ":first-line": 1, ":before": 1, ":after": 1 }; Pseudos.ELEMENT = 1; Pseudos.CLASS = 2; Pseudos.isElement = function(pseudo) { return pseudo.indexOf("::") === 0 || Pseudos[pseudo.toLowerCase()] === Pseudos.ELEMENT; }; },{}],13:[function(require,module,exports){ "use strict"; module.exports = Selector; var SyntaxUnit = require("../util/SyntaxUnit"); var Parser = require("./Parser"); var Specificity = require("./Specificity"); function Selector(parts, line, col) { SyntaxUnit.call(this, parts.join(" "), line, col, Parser.SELECTOR_TYPE); this.parts = parts; this.specificity = Specificity.calculate(this); } Selector.prototype = new SyntaxUnit(); Selector.prototype.constructor = Selector; },{"../util/SyntaxUnit":26,"./Parser":6,"./Specificity":16}],14:[function(require,module,exports){ "use strict"; module.exports = SelectorPart; var SyntaxUnit = require("../util/SyntaxUnit"); var Parser = require("./Parser"); function SelectorPart(elementName, modifiers, text, line, col) { SyntaxUnit.call(this, text, line, col, Parser.SELECTOR_PART_TYPE); this.elementName = elementName; this.modifiers = modifiers; } SelectorPart.prototype = new SyntaxUnit(); SelectorPart.prototype.constructor = SelectorPart; },{"../util/SyntaxUnit":26,"./Parser":6}],15:[function(require,module,exports){ "use strict"; module.exports = SelectorSubPart; var SyntaxUnit = require("../util/SyntaxUnit"); var Parser = require("./Parser"); function SelectorSubPart(text, type, line, col) { SyntaxUnit.call(this, text, line, col, Parser.SELECTOR_SUB_PART_TYPE); this.type = type; this.args = []; } SelectorSubPart.prototype = new SyntaxUnit(); SelectorSubPart.prototype.constructor = SelectorSubPart; },{"../util/SyntaxUnit":26,"./Parser":6}],16:[function(require,module,exports){ "use strict"; module.exports = Specificity; var Pseudos = require("./Pseudos"); var SelectorPart = require("./SelectorPart"); function Specificity(a, b, c, d) { this.a = a; this.b = b; this.c = c; this.d = d; } Specificity.prototype = { constructor: Specificity, compare: function(other) { var comps = ["a", "b", "c", "d"], i, len; for (i = 0, len = comps.length; i < len; i++) { if (this[comps[i]] < other[comps[i]]) { return -1; } else if (this[comps[i]] > other[comps[i]]) { return 1; } } return 0; }, valueOf: function() { return (this.a * 1000) + (this.b * 100) + (this.c * 10) + this.d; }, toString: function() { return this.a + "," + this.b + "," + this.c + "," + this.d; } }; Specificity.calculate = function(selector) { var i, len, part, b = 0, c = 0, d = 0; function updateValues(part) { var i, j, len, num, elementName = part.elementName ? part.elementName.text : "", modifier; if (elementName && elementName.charAt(elementName.length - 1) !== "*") { d++; } for (i = 0, len = part.modifiers.length; i < len; i++) { modifier = part.modifiers[i]; switch (modifier.type) { case "class": case "attribute": c++; break; case "id": b++; break; case "pseudo": if (Pseudos.isElement(modifier.text)) { d++; } else { c++; } break; case "not": for (j = 0, num = modifier.args.length; j < num; j++) { updateValues(modifier.args[j]); } } } } for (i = 0, len = selector.parts.length; i < len; i++) { part = selector.parts[i]; if (part instanceof SelectorPart) { updateValues(part); } } return new Specificity(0, b, c, d); }; },{"./Pseudos":12,"./SelectorPart":14}],17:[function(require,module,exports){ "use strict"; module.exports = TokenStream; var TokenStreamBase = require("../util/TokenStreamBase"); var PropertyValuePart = require("./PropertyValuePart"); var Tokens = require("./Tokens"); var h = /^[0-9a-fA-F]$/, nonascii = /^[\u00A0-\uFFFF]$/, nl = /\n|\r\n|\r|\f/, whitespace = /\u0009|\u000a|\u000c|\u000d|\u0020/; function isHexDigit(c) { return c != null && h.test(c); } function isDigit(c) { return c != null && /\d/.test(c); } function isWhitespace(c) { return c != null && whitespace.test(c); } function isNewLine(c) { return c != null && nl.test(c); } function isNameStart(c) { return c != null && /[a-z_\u00A0-\uFFFF\\]/i.test(c); } function isNameChar(c) { return c != null && (isNameStart(c) || /[0-9\-\\]/.test(c)); } function isIdentStart(c) { return c != null && (isNameStart(c) || /-\\/.test(c)); } function mix(receiver, supplier) { for (var prop in supplier) { if (Object.prototype.hasOwnProperty.call(supplier, prop)) { receiver[prop] = supplier[prop]; } } return receiver; } function wouldStartIdent(twoCodePoints) { return typeof twoCodePoints === "string" && (twoCodePoints[0] === "-" && isNameStart(twoCodePoints[1]) || isNameStart(twoCodePoints[0])); } function wouldStartUnsignedNumber(twoCodePoints) { return typeof twoCodePoints === "string" && (isDigit(twoCodePoints[0]) || (twoCodePoints[0] === "." && isDigit(twoCodePoints[1]))); } function TokenStream(input) { TokenStreamBase.call(this, input, Tokens); } TokenStream.prototype = mix(new TokenStreamBase(), { _getToken: function() { var c, reader = this._reader, token = null, startLine = reader.getLine(), startCol = reader.getCol(); c = reader.read(); while (c) { switch (c) { case "/": if (reader.peek() === "*") { token = this.commentToken(c, startLine, startCol); } else { token = this.charToken(c, startLine, startCol); } break; case "|": case "~": case "^": case "$": case "*": if (reader.peek() === "=") { token = this.comparisonToken(c, startLine, startCol); } else { token = this.charToken(c, startLine, startCol); } break; case "\"": case "'": token = this.stringToken(c, startLine, startCol); break; case "#": if (isNameChar(reader.peek())) { token = this.hashToken(c, startLine, startCol); } else { token = this.charToken(c, startLine, startCol); } break; case ".": if (isDigit(reader.peek())) { token = this.numberToken(c, startLine, startCol); } else { token = this.charToken(c, startLine, startCol); } break; case "-": if (wouldStartUnsignedNumber(reader.peekCount(2))) { token = this.numberToken(c, startLine, startCol); break; } else if (reader.peekCount(2) === "->") { token = this.htmlCommentEndToken(c, startLine, startCol); } else { token = this._getDefaultToken(c, startLine, startCol); } break; case "+": if (wouldStartUnsignedNumber(reader.peekCount(2))) { token = this.numberToken(c, startLine, startCol); } else { token = this.charToken(c, startLine, startCol); } break; case "!": token = this.importantToken(c, startLine, startCol); break; case "@": token = this.atRuleToken(c, startLine, startCol); break; case ":": token = this.notToken(c, startLine, startCol); break; case "<": token = this.htmlCommentStartToken(c, startLine, startCol); break; case "\\": if (/[^\r\n\f]/.test(reader.peek())) { token = this.identOrFunctionToken(this.readEscape(c, true), startLine, startCol); } else { token = this.charToken(c, startLine, startCol); } break; case "U": case "u": if (reader.peek() === "+") { token = this.unicodeRangeToken(c, startLine, startCol); } else { token = this._getDefaultToken(c, startLine, startCol); } break; default: token = this._getDefaultToken(c, startLine, startCol); } break; } if (!token && c === null) { token = this.createToken(Tokens.EOF, null, startLine, startCol); } return token; }, _getDefaultToken: function(c, startLine, startCol) { var reader = this._reader, token = null; if (isDigit(c)) { token = this.numberToken(c, startLine, startCol); } else if (isWhitespace(c)) { token = this.whitespaceToken(c, startLine, startCol); } else if (wouldStartIdent(c + reader.peekCount(1))) { token = this.identOrFunctionToken(c, startLine, startCol); } else { token = this.charToken(c, startLine, startCol); } return token; }, createToken: function(tt, value, startLine, startCol, options) { var reader = this._reader; options = options || {}; return { value: value, type: tt, channel: options.channel, endChar: options.endChar, hide: options.hide || false, startLine: startLine, startCol: startCol, endLine: reader.getLine(), endCol: reader.getCol() }; }, atRuleToken: function(first, startLine, startCol) { var rule = first, reader = this._reader, tt = Tokens.CHAR, ident; reader.mark(); ident = this.readName(); rule = first + ident; tt = Tokens.type(rule.toLowerCase()); if (tt === Tokens.CHAR || tt === Tokens.UNKNOWN) { if (rule.length > 1) { tt = Tokens.UNKNOWN_SYM; } else { tt = Tokens.CHAR; rule = first; reader.reset(); } } return this.createToken(tt, rule, startLine, startCol); }, charToken: function(c, startLine, startCol) { var tt = Tokens.type(c); var opts = {}; if (tt === -1) { tt = Tokens.CHAR; } else { opts.endChar = Tokens[tt].endChar; } return this.createToken(tt, c, startLine, startCol, opts); }, commentToken: function(first, startLine, startCol) { var comment = this.readComment(first); return this.createToken(Tokens.COMMENT, comment, startLine, startCol); }, comparisonToken: function(c, startLine, startCol) { var reader = this._reader, comparison = c + reader.read(), tt = Tokens.type(comparison) || Tokens.CHAR; return this.createToken(tt, comparison, startLine, startCol); }, hashToken: function(first, startLine, startCol) { var name = this.readName(first); return this.createToken(Tokens.HASH, name, startLine, startCol); }, htmlCommentStartToken: function(first, startLine, startCol) { var reader = this._reader, text = first; reader.mark(); text += reader.readCount(3); if (text === "<!--") { return this.createToken(Tokens.CDO, text, startLine, startCol); } else { reader.reset(); return this.charToken(first, startLine, startCol); } }, htmlCommentEndToken: function(first, startLine, startCol) { var reader = this._reader, text = first; reader.mark(); text += reader.readCount(2); if (text === "-->") { return this.createToken(Tokens.CDC, text, startLine, startCol); } else { reader.reset(); return this.charToken(first, startLine, startCol); } }, identOrFunctionToken: function(first, startLine, startCol) { var reader = this._reader, ident = this.readName(first), tt = Tokens.IDENT, uriFns = ["url(", "url-prefix(", "domain("], uri; if (reader.peek() === "(") { ident += reader.read(); if (uriFns.indexOf(ident.toLowerCase()) > -1) { reader.mark(); uri = this.readURI(ident); if (uri === null) { reader.reset(); tt = Tokens.FUNCTION; } else { tt = Tokens.URI; ident = uri; } } else { tt = Tokens.FUNCTION; } } else if (reader.peek() === ":") { // might be an IE function if (ident.toLowerCase() === "progid") { ident += reader.readTo("("); tt = Tokens.IE_FUNCTION; } } return this.createToken(tt, ident, startLine, startCol); }, importantToken: function(first, startLine, startCol) { var reader = this._reader, important = first, tt = Tokens.CHAR, temp, c; reader.mark(); c = reader.read(); while (c) { if (c === "/") { if (reader.peek() !== "*") { break; } else { temp = this.readComment(c); if (temp === "") { // broken! break; } } } else if (isWhitespace(c)) { important += c + this.readWhitespace(); } else if (/i/i.test(c)) { temp = reader.readCount(8); if (/mportant/i.test(temp)) { important += c + temp; tt = Tokens.IMPORTANT_SYM; } break; // we're done } else { break; } c = reader.read(); } if (tt === Tokens.CHAR) { reader.reset(); return this.charToken(first, startLine, startCol); } else { return this.createToken(tt, important, startLine, startCol); } }, notToken: function(first, startLine, startCol) { var reader = this._reader, text = first; reader.mark(); text += reader.readCount(4); if (text.toLowerCase() === ":not(") { return this.createToken(Tokens.NOT, text, startLine, startCol); } else { reader.reset(); return this.charToken(first, startLine, startCol); } }, numberToken: function(first, startLine, startCol) { var reader = this._reader, value = this.readNumber(first), ident, tt = Tokens.NUMBER, c = reader.peek(); if (isIdentStart(c)) { ident = this.readName(reader.read()); value += ident; if (/^em$|^ex$|^px$|^gd$|^rem$|^vw$|^vh$|^fr$|^vmax$|^vmin$|^ch$|^cm$|^mm$|^in$|^pt$|^pc$/i.test(ident)) { tt = Tokens.LENGTH; } else if (/^deg|^rad$|^grad$|^turn$/i.test(ident)) { tt = Tokens.ANGLE; } else if (/^ms$|^s$/i.test(ident)) { tt = Tokens.TIME; } else if (/^hz$|^khz$/i.test(ident)) { tt = Tokens.FREQ; } else if (/^dpi$|^dpcm$/i.test(ident)) { tt = Tokens.RESOLUTION; } else { tt = Tokens.DIMENSION; } } else if (c === "%") { value += reader.read(); tt = Tokens.PERCENTAGE; } return this.createToken(tt, value, startLine, startCol); }, stringToken: function(first, startLine, startCol) { var delim = first, string = first, reader = this._reader, tt = Tokens.STRING, c = reader.read(), i; while (c) { string += c; if (c === "\\") { c = reader.read(); if (c === null) { break; // premature EOF after backslash } else if (/[^\r\n\f0-9a-f]/i.test(c)) { string += c; } else { for (i = 0; isHexDigit(c) && i < 6; i++) { string += c; c = reader.read(); } if (c === "\r" && reader.peek() === "\n") { string += c; c = reader.read(); } if (isWhitespace(c)) { string += c; } else { continue; } } } else if (c === delim) { break; // delimiter found. } else if (isNewLine(reader.peek())) { tt = Tokens.INVALID; break; } c = reader.read(); } if (c === null) { tt = Tokens.INVALID; } return this.createToken(tt, string, startLine, startCol); }, unicodeRangeToken: function(first, startLine, startCol) { var reader = this._reader, value = first, temp, tt = Tokens.CHAR; if (reader.peek() === "+") { reader.mark(); value += reader.read(); value += this.readUnicodeRangePart(true); if (value.length === 2) { reader.reset(); } else { tt = Tokens.UNICODE_RANGE; if (value.indexOf("?") === -1) { if (reader.peek() === "-") { reader.mark(); temp = reader.read(); temp += this.readUnicodeRangePart(false); if (temp.length === 1) { reader.reset(); } else { value += temp; } } } } } return this.createToken(tt, value, startLine, startCol); }, whitespaceToken: function(first, startLine, startCol) { var value = first + this.readWhitespace(); return this.createToken(Tokens.S, value, startLine, startCol); }, readUnicodeRangePart: function(allowQuestionMark) { var reader = this._reader, part = "", c = reader.peek(); while (isHexDigit(c) && part.length < 6) { reader.read(); part += c; c = reader.peek(); } if (allowQuestionMark) { while (c === "?" && part.length < 6) { reader.read(); part += c; c = reader.peek(); } } return part; }, readWhitespace: function() { var reader = this._reader, whitespace = "", c = reader.peek(); while (isWhitespace(c)) { reader.read(); whitespace += c; c = reader.peek(); } return whitespace; }, readNumber: function(first) { var reader = this._reader, number = first, hasDot = first === ".", c = reader.peek(); while (c) { if (isDigit(c)) { number += reader.read(); } else if (c === ".") { if (hasDot) { break; } else { hasDot = true; number += reader.read(); } } else { break; } c = reader.peek(); } return number; }, readString: function() { var token = this.stringToken(this._reader.read(), 0, 0); return token.type === Tokens.INVALID ? null : token.value; }, readURI: function(first) { var reader = this._reader, uri = first, inner = "", c = reader.peek(); while (c && isWhitespace(c)) { reader.read(); c = reader.peek(); } if (c === "'" || c === "\"") { inner = this.readString(); if (inner !== null) { inner = PropertyValuePart.parseString(inner); } } else { inner = this.readUnquotedURL(); } c = reader.peek(); while (c && isWhitespace(c)) { reader.read(); c = reader.peek(); } if (inner === null || c !== ")") { uri = null; } else { uri += PropertyValuePart.serializeString(inner) + reader.read(); } return uri; }, readUnquotedURL: function(first) { var reader = this._reader, url = first || "", c; for (c = reader.peek(); c; c = reader.peek()) { if (nonascii.test(c) || /^[-!#$%&*-[\]-~]$/.test(c)) { url += c; reader.read(); } else if (c === "\\") { if (/^[^\r\n\f]$/.test(reader.peek(2))) { url += this.readEscape(reader.read(), true); } else { break; // bad escape sequence. } } else { break; // bad character } } return url; }, readName: function(first) { var reader = this._reader, ident = first || "", c; for (c = reader.peek(); c; c = reader.peek()) { if (c === "\\") { if (/^[^\r\n\f]$/.test(reader.peek(2))) { ident += this.readEscape(reader.read(), true); } else { break; } } else if (isNameChar(c)) { ident += reader.read(); } else { break; } } return ident; }, readEscape: function(first, unescape) { var reader = this._reader, cssEscape = first || "", i = 0, c = reader.peek(); if (isHexDigit(c)) { do { cssEscape += reader.read(); c = reader.peek(); } while (c && isHexDigit(c) && ++i < 6); } if (cssEscape.length === 1) { if (/^[^\r\n\f0-9a-f]$/.test(c)) { reader.read(); if (unescape) { return c; } } else { throw new Error("Bad escape sequence."); } } else if (c === "\r") { reader.read(); if (reader.peek() === "\n") { c += reader.read(); } } else if (/^[ \t\n\f]$/.test(c)) { reader.read(); } else { c = ""; } if (unescape) { var cp = parseInt(cssEscape.slice(first.length), 16); return String.fromCodePoint ? String.fromCodePoint(cp) : String.fromCharCode(cp); } return cssEscape + c; }, readComment: function(first) { var reader = this._reader, comment = first || "", c = reader.read(); if (c === "*") { while (c) { comment += c; if (comment.length > 2 && c === "*" && reader.peek() === "/") { comment += reader.read(); break; } c = reader.read(); } return comment; } else { return ""; } } }); },{"../util/TokenStreamBase":27,"./PropertyValuePart":11,"./Tokens":18}],18:[function(require,module,exports){ "use strict"; var Tokens = module.exports = [ { name: "CDO" }, { name: "CDC" }, { name: "S", whitespace: true/*, channel: "ws"*/ }, { name: "COMMENT", comment: true, hide: true, channel: "comment" }, { name: "INCLUDES", text: "~=" }, { name: "DASHMATCH", text: "|=" }, { name: "PREFIXMATCH", text: "^=" }, { name: "SUFFIXMATCH", text: "$=" }, { name: "SUBSTRINGMATCH", text: "*=" }, { name: "STRING" }, { name: "IDENT" }, { name: "HASH" }, { name: "IMPORT_SYM", text: "@import" }, { name: "PAGE_SYM", text: "@page" }, { name: "MEDIA_SYM", text: "@media" }, { name: "FONT_FACE_SYM", text: "@font-face" }, { name: "CHARSET_SYM", text: "@charset" }, { name: "NAMESPACE_SYM", text: "@namespace" }, { name: "SUPPORTS_SYM", text: "@supports" }, { name: "VIEWPORT_SYM", text: ["@viewport", "@-ms-viewport", "@-o-viewport"] }, { name: "DOCUMENT_SYM", text: ["@document", "@-moz-document"] }, { name: "UNKNOWN_SYM" }, { name: "KEYFRAMES_SYM", text: [ "@keyframes", "@-webkit-keyframes", "@-moz-keyframes", "@-o-keyframes" ] }, { name: "IMPORTANT_SYM" }, { name: "LENGTH" }, { name: "ANGLE" }, { name: "TIME" }, { name: "FREQ" }, { name: "DIMENSION" }, { name: "PERCENTAGE" }, { name: "NUMBER" }, { name: "URI" }, { name: "FUNCTION" }, { name: "UNICODE_RANGE" }, { name: "INVALID" }, { name: "PLUS", text: "+" }, { name: "GREATER", text: ">" }, { name: "COMMA", text: "," }, { name: "TILDE", text: "~" }, { name: "NOT" }, { name: "TOPLEFTCORNER_SYM", text: "@top-left-corner" }, { name: "TOPLEFT_SYM", text: "@top-left" }, { name: "TOPCENTER_SYM", text: "@top-center" }, { name: "TOPRIGHT_SYM", text: "@top-right" }, { name: "TOPRIGHTCORNER_SYM", text: "@top-right-corner" }, { name: "BOTTOMLEFTCORNER_SYM", text: "@bottom-left-corner" }, { name: "BOTTOMLEFT_SYM", text: "@bottom-left" }, { name: "BOTTOMCENTER_SYM", text: "@bottom-center" }, { name: "BOTTOMRIGHT_SYM", text: "@bottom-right" }, { name: "BOTTOMRIGHTCORNER_SYM", text: "@bottom-right-corner" }, { name: "LEFTTOP_SYM", text: "@left-top" }, { name: "LEFTMIDDLE_SYM", text: "@left-middle" }, { name: "LEFTBOTTOM_SYM", text: "@left-bottom" }, { name: "RIGHTTOP_SYM", text: "@right-top" }, { name: "RIGHTMIDDLE_SYM", text: "@right-middle" }, { name: "RIGHTBOTTOM_SYM", text: "@right-bottom" }, { name: "RESOLUTION", state: "media" }, { name: "IE_FUNCTION" }, { name: "CHAR" }, { name: "PIPE", text: "|" }, { name: "SLASH", text: "/" }, { name: "MINUS", text: "-" }, { name: "STAR", text: "*" }, { name: "LBRACE", endChar: "}", text: "{" }, { name: "RBRACE", text: "}" }, { name: "LBRACKET", endChar: "]", text: "[" }, { name: "RBRACKET", text: "]" }, { name: "EQUALS", text: "=" }, { name: "COLON", text: ":" }, { name: "SEMICOLON", text: ";" }, { name: "LPAREN", endChar: ")", text: "(" }, { name: "RPAREN", text: ")" }, { name: "DOT", text: "." } ]; (function() { var nameMap = [], typeMap = Object.create(null); Tokens.UNKNOWN = -1; Tokens.unshift({ name:"EOF" }); for (var i = 0, len = Tokens.length; i < len; i++) { nameMap.push(Tokens[i].name); Tokens[Tokens[i].name] = i; if (Tokens[i].text) { if (Tokens[i].text instanceof Array) { for (var j = 0; j < Tokens[i].text.length; j++) { typeMap[Tokens[i].text[j]] = i; } } else { typeMap[Tokens[i].text] = i; } } } Tokens.name = function(tt) { return nameMap[tt]; }; Tokens.type = function(c) { return typeMap[c] || -1; }; })(); },{}],19:[function(require,module,exports){ "use strict"; var Matcher = require("./Matcher"); var Properties = require("./Properties"); var ValidationTypes = require("./ValidationTypes"); var ValidationError = require("./ValidationError"); var PropertyValueIterator = require("./PropertyValueIterator"); var Validation = module.exports = { validate: function(property, value) { var name = property.toString().toLowerCase(), expression = new PropertyValueIterator(value), spec = Properties[name], part; if (!spec) { if (name.indexOf("-") !== 0) { // vendor prefixed are ok throw new ValidationError("Unknown property '" + property + "'.", property.line, property.col); } } else if (typeof spec !== "number") { if (ValidationTypes.isAny(expression, "inherit | initial | unset")) { if (expression.hasNext()) { part = expression.next(); throw new ValidationError("Expected end of value but found '" + part + "'.", part.line, part.col); } return; } this.singleProperty(spec, expression); } }, singleProperty: function(types, expression) { var result = false, value = expression.value, part; result = Matcher.parse(types).match(expression); if (!result) { if (expression.hasNext() && !expression.isFirst()) { part = expression.peek(); throw new ValidationError("Expected end of value but found '" + part + "'.", part.line, part.col); } else { throw new ValidationError("Expected (" + ValidationTypes.describe(types) + ") but found '" + value + "'.", value.line, value.col); } } else if (expression.hasNext()) { part = expression.next(); throw new ValidationError("Expected end of value but found '" + part + "'.", part.line, part.col); } } }; },{"./Matcher":3,"./Properties":7,"./PropertyValueIterator":10,"./ValidationError":20,"./ValidationTypes":21}],20:[function(require,module,exports){ "use strict"; module.exports = ValidationError; function ValidationError(message, line, col) { this.col = col; this.line = line; this.message = message; } ValidationError.prototype = new Error(); },{}],21:[function(require,module,exports){ "use strict"; var ValidationTypes = module.exports; var Matcher = require("./Matcher"); function copy(to, from) { Object.keys(from).forEach(function(prop) { to[prop] = from[prop]; }); } copy(ValidationTypes, { isLiteral: function (part, literals) { var text = part.text.toString().toLowerCase(), args = literals.split(" | "), i, len, found = false; for (i = 0, len = args.length; i < len && !found; i++) { if (args[i].charAt(0) === "<") { found = this.simple[args[i]](part); } else if (args[i].slice(-2) === "()") { found = (part.type === "function" && part.name === args[i].slice(0, -2)); } else if (text === args[i].toLowerCase()) { found = true; } } return found; }, isSimple: function(type) { return Boolean(this.simple[type]); }, isComplex: function(type) { return Boolean(this.complex[type]); }, describe: function(type) { if (this.complex[type] instanceof Matcher) { return this.complex[type].toString(0); } return type; }, isAny: function (expression, types) { var args = types.split(" | "), i, len, found = false; for (i = 0, len = args.length; i < len && !found && expression.hasNext(); i++) { found = this.isType(expression, args[i]); } return found; }, isAnyOfGroup: function(expression, types) { var args = types.split(" || "), i, len, found = false; for (i = 0, len = args.length; i < len && !found; i++) { found = this.isType(expression, args[i]); } return found ? args[i - 1] : false; }, isType: function (expression, type) { var part = expression.peek(), result = false; if (type.charAt(0) !== "<") { result = this.isLiteral(part, type); if (result) { expression.next(); } } else if (this.simple[type]) { result = this.simple[type](part); if (result) { expression.next(); } } else if (this.complex[type] instanceof Matcher) { result = this.complex[type].match(expression); } else { result = this.complex[type](expression); } return result; }, simple: { __proto__: null, "<absolute-size>": "xx-small | x-small | small | medium | large | x-large | xx-large", "<animateable-feature>": "scroll-position | contents | <animateable-feature-name>", "<animateable-feature-name>": function(part) { return this["<ident>"](part) && !/^(unset|initial|inherit|will-change|auto|scroll-position|contents)$/i.test(part); }, "<angle>": function(part) { return part.type === "angle"; }, "<attachment>": "scroll | fixed | local", "<attr>": "attr()", "<basic-shape>": "inset() | circle() | ellipse() | polygon()", "<bg-image>": "<image> | <gradient> | none", "<border-style>": "none | hidden | dotted | dashed | solid | double | groove | " + "ridge | inset | outset", "<border-width>": "<length> | thin | medium | thick", "<box>": "padding-box | border-box | content-box", "<clip-source>": "<uri>", "<color>": function(part) { return part.type === "color" || String(part) === "transparent" || String(part) === "currentColor"; }, "<color-svg>": function(part) { return part.type === "color"; }, "<content>": "content()", "<content-sizing>": "fill-available | -moz-available | -webkit-fill-available | " + "max-content | -moz-max-content | -webkit-max-content | " + "min-content | -moz-min-content | -webkit-min-content | " + "fit-content | -moz-fit-content | -webkit-fit-content", "<feature-tag-value>": function(part) { return part.type === "function" && /^[A-Z0-9]{4}$/i.test(part); }, "<filter-function>": "blur() | brightness() | contrast() | custom() | " + "drop-shadow() | grayscale() | hue-rotate() | invert() | " + "opacity() | saturate() | sepia()", "<flex-basis>": "<width>", "<flex-direction>": "row | row-reverse | column | column-reverse", "<flex-grow>": "<number>", "<flex-shrink>": "<number>", "<flex-wrap>": "nowrap | wrap | wrap-reverse", "<font-size>": "<absolute-size> | <relative-size> | <length> | <percentage>", "<font-stretch>": "normal | ultra-condensed | extra-condensed | condensed | " + "semi-condensed | semi-expanded | expanded | extra-expanded | " + "ultra-expanded", "<font-style>": "normal | italic | oblique", "<font-variant-caps>": "small-caps | all-small-caps | petite-caps | all-petite-caps | " + "unicase | titling-caps", "<font-variant-css21>": "normal | small-caps", "<font-weight>": "normal | bold | bolder | lighter | " + "100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900", "<generic-family>": "serif | sans-serif | cursive | fantasy | monospace", "<geometry-box>": "<shape-box> | fill-box | stroke-box | view-box", "<glyph-angle>": function(part) { return part.type === "angle" && part.units === "deg"; }, "<gradient>": function(part) { return part.type === "function" && /^(?:-(?:ms|moz|o|webkit)-)?(?:repeating-)?(?:radial-|linear-)?gradient/i.test(part); }, "<icccolor>": "cielab() | cielch() | cielchab() | " + "icc-color() | icc-named-color()", "<ident>": function(part) { return part.type === "identifier" || part.wasIdent; }, "<ident-not-generic-family>": function(part) { return this["<ident>"](part) && !this["<generic-family>"](part); }, "<image>": "<uri>", "<integer>": function(part) { return part.type === "integer"; }, "<length>": function(part) { if (part.type === "function" && /^(?:-(?:ms|moz|o|webkit)-)?calc/i.test(part)) { return true; } else { return part.type === "length" || part.type === "number" || part.type === "integer" || String(part) === "0"; } }, "<line>": function(part) { return part.type === "integer"; }, "<line-height>": "<number> | <length> | <percentage> | normal", "<margin-width>": "<length> | <percentage> | auto", "<miterlimit>": function(part) { return this["<number>"](part) && part.value >= 1; }, "<nonnegative-length-or-percentage>": function(part) { return (this["<length>"](part) || this["<percentage>"](part)) && (String(part) === "0" || part.type === "function" || (part.value) >= 0); }, "<nonnegative-number-or-percentage>": function(part) { return (this["<number>"](part) || this["<percentage>"](part)) && (String(part) === "0" || part.type === "function" || (part.value) >= 0); }, "<number>": function(part) { return part.type === "number" || this["<integer>"](part); }, "<opacity-value>": function(part) { return this["<number>"](part) && part.value >= 0 && part.value <= 1; }, "<padding-width>": "<nonnegative-length-or-percentage>", "<percentage>": function(part) { return part.type === "percentage" || String(part) === "0"; }, "<relative-size>": "smaller | larger", "<shape>": "rect() | inset-rect()", "<shape-box>": "<box> | margin-box", "<single-animation-direction>": "normal | reverse | alternate | alternate-reverse", "<single-animation-name>": function(part) { return this["<ident>"](part) && /^-?[a-z_][-a-z0-9_]+$/i.test(part) && !/^(none|unset|initial|inherit)$/i.test(part); }, "<string>": function(part) { return part.type === "string"; }, "<time>": function(part) { return part.type === "time"; }, "<uri>": function(part) { return part.type === "uri"; }, "<width>": "<margin-width>" }, complex: { __proto__: null, "<azimuth>": "<angle>" + " | " + "[ [ left-side | far-left | left | center-left | center | " + "center-right | right | far-right | right-side ] || behind ]" + " | " + "leftwards | rightwards", "<bg-position>": "<position>#", "<bg-size>": "[ <length> | <percentage> | auto ]{1,2} | cover | contain", "<blend-mode>": "normal | multiply | screen | overlay | darken | lighten | color-dodge | " + "color-burn | hard-light | soft-light | difference | exclusion | hue | " + "saturation | color | luminosity", "<border-image-slice>": Matcher.many([true /* first element is required */], Matcher.cast("<nonnegative-number-or-percentage>"), Matcher.cast("<nonnegative-number-or-percentage>"), Matcher.cast("<nonnegative-number-or-percentage>"), Matcher.cast("<nonnegative-number-or-percentage>"), "fill"), "<border-radius>": "<nonnegative-length-or-percentage>{1,4} " + "[ / <nonnegative-length-or-percentage>{1,4} ]?", "<box-shadow>": "none | <shadow>#", "<clip-path>": "<basic-shape> || <geometry-box>", "<dasharray>": Matcher.cast("<nonnegative-length-or-percentage>") .braces(1, Infinity, "#", Matcher.cast(",").question()), "<family-name>": "<string> | <ident-not-generic-family> <ident>*", "<filter-function-list>": "[ <filter-function> | <uri> ]+", "<flex>": "none | [ <flex-grow> <flex-shrink>? || <flex-basis> ]", "<font-family>": "[ <generic-family> | <family-name> ]#", "<font-shorthand>": "[ <font-style> || <font-variant-css21> || " + "<font-weight> || <font-stretch> ]? <font-size> " + "[ / <line-height> ]? <font-family>", "<font-variant-alternates>": "stylistic() || " + "historical-forms || " + "styleset() || " + "character-variant() || " + "swash() || " + "ornaments() || " + "annotation()", "<font-variant-ligatures>": "[ common-ligatures | no-common-ligatures ] || " + "[ discretionary-ligatures | no-discretionary-ligatures ] || " + "[ historical-ligatures | no-historical-ligatures ] || " + "[ contextual | no-contextual ]", "<font-variant-numeric>": "[ lining-nums | oldstyle-nums ] || " + "[ proportional-nums | tabular-nums ] || " + "[ diagonal-fractions | stacked-fractions ] || " + "ordinal || slashed-zero", "<font-variant-east-asian>": "[ jis78 | jis83 | jis90 | jis04 | simplified | traditional ] || " + "[ full-width | proportional-width ] || " + "ruby", "<paint>": "<paint-basic> | <uri> <paint-basic>?", "<paint-basic>": "none | currentColor | <color-svg> <icccolor>?", "<position>": "[ center | [ left | right ] [ <percentage> | <length> ]? ] && " + "[ center | [ top | bottom ] [ <percentage> | <length> ]? ]" + " | " + "[ left | center | right | <percentage> | <length> ] " + "[ top | center | bottom | <percentage> | <length> ]" + " | " + "[ left | center | right | top | bottom | <percentage> | <length> ]", "<repeat-style>": "repeat-x | repeat-y | [ repeat | space | round | no-repeat ]{1,2}", "<shadow>": Matcher.many([true /* length is required */], Matcher.cast("<length>").braces(2, 4), "inset", "<color>"), "<text-decoration-color>": "<color>", "<text-decoration-line>": "none | [ underline || overline || line-through || blink ]", "<text-decoration-style>": "solid | double | dotted | dashed | wavy", "<will-change>": "auto | <animateable-feature>#", "<x-one-radius>": "[ <length> | <percentage> ]{1,2}" } }); Object.keys(ValidationTypes.simple).forEach(function(nt) { var rule = ValidationTypes.simple[nt]; if (typeof rule === "string") { ValidationTypes.simple[nt] = function(part) { return ValidationTypes.isLiteral(part, rule); }; } }); Object.keys(ValidationTypes.complex).forEach(function(nt) { var rule = ValidationTypes.complex[nt]; if (typeof rule === "string") { ValidationTypes.complex[nt] = Matcher.parse(rule); } }); ValidationTypes.complex["<font-variant>"] = Matcher.oror({ expand: "<font-variant-ligatures>" }, { expand: "<font-variant-alternates>" }, "<font-variant-caps>", { expand: "<font-variant-numeric>" }, { expand: "<font-variant-east-asian>" }); },{"./Matcher":3}],22:[function(require,module,exports){ "use strict"; module.exports = { Colors : require("./Colors"), Combinator : require("./Combinator"), Parser : require("./Parser"), PropertyName : require("./PropertyName"), PropertyValue : require("./PropertyValue"), PropertyValuePart : require("./PropertyValuePart"), Matcher : require("./Matcher"), MediaFeature : require("./MediaFeature"), MediaQuery : require("./MediaQuery"), Selector : require("./Selector"), SelectorPart : require("./SelectorPart"), SelectorSubPart : require("./SelectorSubPart"), Specificity : require("./Specificity"), TokenStream : require("./TokenStream"), Tokens : require("./Tokens"), ValidationError : require("./ValidationError") }; },{"./Colors":1,"./Combinator":2,"./Matcher":3,"./MediaFeature":4,"./MediaQuery":5,"./Parser":6,"./PropertyName":8,"./PropertyValue":9,"./PropertyValuePart":11,"./Selector":13,"./SelectorPart":14,"./SelectorSubPart":15,"./Specificity":16,"./TokenStream":17,"./Tokens":18,"./ValidationError":20}],23:[function(require,module,exports){ "use strict"; module.exports = EventTarget; function EventTarget() { this._listeners = Object.create(null); } EventTarget.prototype = { constructor: EventTarget, addListener: function(type, listener) { if (!this._listeners[type]) { this._listeners[type] = []; } this._listeners[type].push(listener); }, fire: function(event) { if (typeof event === "string") { event = { type: event }; } if (typeof event.target !== "undefined") { event.target = this; } if (typeof event.type === "undefined") { throw new Error("Event object missing 'type' property."); } if (this._listeners[event.type]) { var listeners = this._listeners[event.type].concat(); for (var i = 0, len = listeners.length; i < len; i++) { listeners[i].call(this, event); } } }, removeListener: function(type, listener) { if (this._listeners[type]) { var listeners = this._listeners[type]; for (var i = 0, len = listeners.length; i < len; i++) { if (listeners[i] === listener) { listeners.splice(i, 1); break; } } } } }; },{}],24:[function(require,module,exports){ "use strict"; module.exports = StringReader; function StringReader(text) { this._input = text.replace(/(\r\n?|\n)/g, "\n"); this._line = 1; this._col = 1; this._cursor = 0; } StringReader.prototype = { constructor: StringReader, getCol: function() { return this._col; }, getLine: function() { return this._line; }, eof: function() { return this._cursor === this._input.length; }, peek: function(count) { var c = null; count = typeof count === "undefined" ? 1 : count; if (this._cursor < this._input.length) { c = this._input.charAt(this._cursor + count - 1); } return c; }, read: function() { var c = null; if (this._cursor < this._input.length) { if (this._input.charAt(this._cursor) === "\n") { this._line++; this._col = 1; } else { this._col++; } c = this._input.charAt(this._cursor++); } return c; }, mark: function() { this._bookmark = { cursor: this._cursor, line: this._line, col: this._col }; }, reset: function() { if (this._bookmark) { this._cursor = this._bookmark.cursor; this._line = this._bookmark.line; this._col = this._bookmark.col; delete this._bookmark; } }, peekCount: function(count) { count = typeof count === "undefined" ? 1 : Math.max(count, 0); return this._input.substring(this._cursor, this._cursor + count); }, readTo: function(pattern) { var buffer = "", c; while (buffer.length < pattern.length || buffer.lastIndexOf(pattern) !== buffer.length - pattern.length) { c = this.read(); if (c) { buffer += c; } else { throw new Error("Expected \"" + pattern + "\" at line " + this._line + ", col " + this._col + "."); } } return buffer; }, readWhile: function(filter) { var buffer = "", c = this.peek(); while (c !== null && filter(c)) { buffer += this.read(); c = this.peek(); } return buffer; }, readMatch: function(matcher) { var source = this._input.substring(this._cursor), value = null; if (typeof matcher === "string") { if (source.slice(0, matcher.length) === matcher) { value = this.readCount(matcher.length); } } else if (matcher instanceof RegExp) { if (matcher.test(source)) { value = this.readCount(RegExp.lastMatch.length); } } return value; }, readCount: function(count) { var buffer = ""; while (count--) { buffer += this.read(); } return buffer; } }; },{}],25:[function(require,module,exports){ "use strict"; module.exports = SyntaxError; function SyntaxError(message, line, col) { Error.call(this); this.name = this.constructor.name; this.col = col; this.line = line; this.message = message; } SyntaxError.prototype = Object.create(Error.prototype); // jshint ignore:line SyntaxError.prototype.constructor = SyntaxError; // jshint ignore:line },{}],26:[function(require,module,exports){ "use strict"; module.exports = SyntaxUnit; function SyntaxUnit(text, line, col, type) { this.col = col; this.line = line; this.text = text; this.type = type; } SyntaxUnit.fromToken = function(token) { return new SyntaxUnit(token.value, token.startLine, token.startCol); }; SyntaxUnit.prototype = { constructor: SyntaxUnit, valueOf: function() { return this.toString(); }, toString: function() { return this.text; } }; },{}],27:[function(require,module,exports){ "use strict"; module.exports = TokenStreamBase; var StringReader = require("./StringReader"); var SyntaxError = require("./SyntaxError"); function TokenStreamBase(input, tokenData) { this._reader = new StringReader(input ? input.toString() : ""); this._token = null; this._tokenData = tokenData; this._lt = []; this._ltIndex = 0; this._ltIndexCache = []; } TokenStreamBase.createTokenData = function(tokens) { var nameMap = [], typeMap = Object.create(null), tokenData = tokens.concat([]), i = 0, len = tokenData.length + 1; tokenData.UNKNOWN = -1; tokenData.unshift({ name:"EOF" }); for (; i < len; i++) { nameMap.push(tokenData[i].name); tokenData[tokenData[i].name] = i; if (tokenData[i].text) { typeMap[tokenData[i].text] = i; } } tokenData.name = function(tt) { return nameMap[tt]; }; tokenData.type = function(c) { return typeMap[c]; }; return tokenData; }; TokenStreamBase.prototype = { constructor: TokenStreamBase, match: function(tokenTypes, channel) { if (!(tokenTypes instanceof Array)) { tokenTypes = [tokenTypes]; } var tt = this.get(channel), i = 0, len = tokenTypes.length; while (i < len) { if (tt === tokenTypes[i++]) { return true; } } this.unget(); return false; }, mustMatch: function(tokenTypes) { var token; if (!(tokenTypes instanceof Array)) { tokenTypes = [tokenTypes]; } if (!this.match.apply(this, arguments)) { token = this.LT(1); throw new SyntaxError("Expected " + this._tokenData[tokenTypes[0]].name + " at line " + token.startLine + ", col " + token.startCol + ".", token.startLine, token.startCol); } }, advance: function(tokenTypes, channel) { while (this.LA(0) !== 0 && !this.match(tokenTypes, channel)) { this.get(); } return this.LA(0); }, get: function(channel) { var tokenInfo = this._tokenData, i = 0, token, info; if (this._lt.length && this._ltIndex >= 0 && this._ltIndex < this._lt.length) { i++; this._token = this._lt[this._ltIndex++]; info = tokenInfo[this._token.type]; while ((typeof info.channel !== "undefined" && channel !== info.channel) && this._ltIndex < this._lt.length) { this._token = this._lt[this._ltIndex++]; info = tokenInfo[this._token.type]; i++; } if ((typeof info.channel === "undefined" || channel === info.channel) && this._ltIndex <= this._lt.length) { this._ltIndexCache.push(i); return this._token.type; } } token = this._getToken(); if (token.type > -1 && !tokenInfo[token.type].hide) { token.channel = tokenInfo[token.type].channel; this._token = token; this._lt.push(token); this._ltIndexCache.push(this._lt.length - this._ltIndex + i); if (this._lt.length > 5) { this._lt.shift(); } if (this._ltIndexCache.length > 5) { this._ltIndexCache.shift(); } this._ltIndex = this._lt.length; } info = tokenInfo[token.type]; if (info && (info.hide || (typeof info.channel !== "undefined" && channel !== info.channel))) { return this.get(channel); } else { return token.type; } }, LA: function(index) { var total = index, tt; if (index > 0) { if (index > 5) { throw new Error("Too much lookahead."); } while (total) { tt = this.get(); total--; } while (total < index) { this.unget(); total++; } } else if (index < 0) { if (this._lt[this._ltIndex + index]) { tt = this._lt[this._ltIndex + index].type; } else { throw new Error("Too much lookbehind."); } } else { tt = this._token.type; } return tt; }, LT: function(index) { this.LA(index); return this._lt[this._ltIndex + index - 1]; }, peek: function() { return this.LA(1); }, token: function() { return this._token; }, tokenName: function(tokenType) { if (tokenType < 0 || tokenType > this._tokenData.length) { return "UNKNOWN_TOKEN"; } else { return this._tokenData[tokenType].name; } }, tokenType: function(tokenName) { return this._tokenData[tokenName] || -1; }, unget: function() { if (this._ltIndexCache.length) { this._ltIndex -= this._ltIndexCache.pop();//--; this._token = this._lt[this._ltIndex - 1]; } else { throw new Error("Too much lookahead."); } } }; },{"./StringReader":24,"./SyntaxError":25}],28:[function(require,module,exports){ "use strict"; module.exports = { StringReader : require("./StringReader"), SyntaxError : require("./SyntaxError"), SyntaxUnit : require("./SyntaxUnit"), EventTarget : require("./EventTarget"), TokenStreamBase : require("./TokenStreamBase") }; },{"./EventTarget":23,"./StringReader":24,"./SyntaxError":25,"./SyntaxUnit":26,"./TokenStreamBase":27}],"parserlib":[function(require,module,exports){ "use strict"; module.exports = { css : require("./css"), util : require("./util") }; },{"./css":22,"./util":28}]},{},[]); return require('parserlib'); })(); var clone = (function() { 'use strict'; function _instanceof(obj, type) { return type != null && obj instanceof type; } var nativeMap; try { nativeMap = Map; } catch(_) { nativeMap = function() {}; } var nativeSet; try { nativeSet = Set; } catch(_) { nativeSet = function() {}; } var nativePromise; try { nativePromise = Promise; } catch(_) { nativePromise = function() {}; } function clone(parent, circular, depth, prototype, includeNonEnumerable) { if (typeof circular === 'object') { depth = circular.depth; prototype = circular.prototype; includeNonEnumerable = circular.includeNonEnumerable; circular = circular.circular; } var allParents = []; var allChildren = []; var useBuffer = typeof Buffer != 'undefined'; if (typeof circular == 'undefined') circular = true; if (typeof depth == 'undefined') depth = Infinity; function _clone(parent, depth) { if (parent === null) return null; if (depth === 0) return parent; var child; var proto; if (typeof parent != 'object') { return parent; } if (_instanceof(parent, nativeMap)) { child = new nativeMap(); } else if (_instanceof(parent, nativeSet)) { child = new nativeSet(); } else if (_instanceof(parent, nativePromise)) { child = new nativePromise(function (resolve, reject) { parent.then(function(value) { resolve(_clone(value, depth - 1)); }, function(err) { reject(_clone(err, depth - 1)); }); }); } else if (clone.__isArray(parent)) { child = []; } else if (clone.__isRegExp(parent)) { child = new RegExp(parent.source, __getRegExpFlags(parent)); if (parent.lastIndex) child.lastIndex = parent.lastIndex; } else if (clone.__isDate(parent)) { child = new Date(parent.getTime()); } else if (useBuffer && Buffer.isBuffer(parent)) { if (Buffer.allocUnsafe) { child = Buffer.allocUnsafe(parent.length); } else { child = new Buffer(parent.length); } parent.copy(child); return child; } else if (_instanceof(parent, Error)) { child = Object.create(parent); } else { if (typeof prototype == 'undefined') { proto = Object.getPrototypeOf(parent); child = Object.create(proto); } else { child = Object.create(prototype); proto = prototype; } } if (circular) { var index = allParents.indexOf(parent); if (index != -1) { return allChildren[index]; } allParents.push(parent); allChildren.push(child); } if (_instanceof(parent, nativeMap)) { parent.forEach(function(value, key) { var keyChild = _clone(key, depth - 1); var valueChild = _clone(value, depth - 1); child.set(keyChild, valueChild); }); } if (_instanceof(parent, nativeSet)) { parent.forEach(function(value) { var entryChild = _clone(value, depth - 1); child.add(entryChild); }); } for (var i in parent) { var attrs; if (proto) { attrs = Object.getOwnPropertyDescriptor(proto, i); } if (attrs && attrs.set == null) { continue; } child[i] = _clone(parent[i], depth - 1); } if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(parent); for (var i = 0; i < symbols.length; i++) { var symbol = symbols[i]; var descriptor = Object.getOwnPropertyDescriptor(parent, symbol); if (descriptor && !descriptor.enumerable && !includeNonEnumerable) { continue; } child[symbol] = _clone(parent[symbol], depth - 1); if (!descriptor.enumerable) { Object.defineProperty(child, symbol, { enumerable: false }); } } } if (includeNonEnumerable) { var allPropertyNames = Object.getOwnPropertyNames(parent); for (var i = 0; i < allPropertyNames.length; i++) { var propertyName = allPropertyNames[i]; var descriptor = Object.getOwnPropertyDescriptor(parent, propertyName); if (descriptor && descriptor.enumerable) { continue; } child[propertyName] = _clone(parent[propertyName], depth - 1); Object.defineProperty(child, propertyName, { enumerable: false }); } } return child; } return _clone(parent, depth); } clone.clonePrototype = function clonePrototype(parent) { if (parent === null) return null; var c = function () {}; c.prototype = parent; return new c(); }; function __objToStr(o) { return Object.prototype.toString.call(o); } clone.__objToStr = __objToStr; function __isDate(o) { return typeof o === 'object' && __objToStr(o) === '[object Date]'; } clone.__isDate = __isDate; function __isArray(o) { return typeof o === 'object' && __objToStr(o) === '[object Array]'; } clone.__isArray = __isArray; function __isRegExp(o) { return typeof o === 'object' && __objToStr(o) === '[object RegExp]'; } clone.__isRegExp = __isRegExp; function __getRegExpFlags(re) { var flags = ''; if (re.global) flags += 'g'; if (re.ignoreCase) flags += 'i'; if (re.multiline) flags += 'm'; return flags; } clone.__getRegExpFlags = __getRegExpFlags; return clone; })(); if (typeof module === 'object' && module.exports) { module.exports = clone; } var CSSLint = (function() { "use strict"; var rules = [], formatters = [], embeddedRuleset = /\/\*\s*csslint([^\*]*)\*\//, api = new parserlib.util.EventTarget(); api.version = "1.0.5"; api.addRule = function(rule) { rules.push(rule); rules[rule.id] = rule; }; api.clearRules = function() { rules = []; }; api.getRules = function() { return [].concat(rules).sort(function(a, b) { return a.id > b.id ? 1 : 0; }); }; api.getRuleset = function() { var ruleset = {}, i = 0, len = rules.length; while (i < len) { ruleset[rules[i++].id] = 1; // by default, everything is a warning } return ruleset; }; function applyEmbeddedRuleset(text, ruleset) { var valueMap, embedded = text && text.match(embeddedRuleset), rules = embedded && embedded[1]; if (rules) { valueMap = { "true": 2, // true is error "": 1, // blank is warning "false": 0, // false is ignore "2": 2, // explicit error "1": 1, // explicit warning "0": 0 // explicit ignore }; rules.toLowerCase().split(",").forEach(function(rule) { var pair = rule.split(":"), property = pair[0] || "", value = pair[1] || ""; ruleset[property.trim()] = valueMap[value.trim()]; }); } return ruleset; } api.addFormatter = function(formatter) { formatters[formatter.id] = formatter; }; api.getFormatter = function(formatId) { return formatters[formatId]; }; api.format = function(results, filename, formatId, options) { var formatter = api.getFormatter(formatId), result = null; if (formatter) { result = formatter.startFormat(); result += formatter.formatResults(results, filename, options || {}); result += formatter.endFormat(); } return result; }; api.hasFormat = function(formatId) { return formatters.hasOwnProperty(formatId); }; api.verify = function(text, ruleset) { var i = 0, reporter, lines, allow = {}, ignore = [], report, parser = new parserlib.css.Parser({ starHack: true, ieFilters: true, underscoreHack: true, strict: false }); lines = text.replace(/\n\r?/g, "$split$").split("$split$"); CSSLint.Util.forEach(lines, function (line, lineno) { var allowLine = line && line.match(/\/\*[ \t]*csslint[ \t]+allow:[ \t]*([^\*]*)\*\//i), allowRules = allowLine && allowLine[1], allowRuleset = {}; if (allowRules) { allowRules.toLowerCase().split(",").forEach(function(allowRule) { allowRuleset[allowRule.trim()] = true; }); if (Object.keys(allowRuleset).length > 0) { allow[lineno + 1] = allowRuleset; } } }); var ignoreStart = null, ignoreEnd = null; CSSLint.Util.forEach(lines, function (line, lineno) { if (ignoreStart === null && line.match(/\/\*[ \t]*csslint[ \t]+ignore:start[ \t]*\*\//i)) { ignoreStart = lineno; } if (line.match(/\/\*[ \t]*csslint[ \t]+ignore:end[ \t]*\*\//i)) { ignoreEnd = lineno; } if (ignoreStart !== null && ignoreEnd !== null) { ignore.push([ignoreStart, ignoreEnd]); ignoreStart = ignoreEnd = null; } }); if (ignoreStart !== null) { ignore.push([ignoreStart, lines.length]); } if (!ruleset) { ruleset = api.getRuleset(); } if (embeddedRuleset.test(text)) { ruleset = clone(ruleset); ruleset = applyEmbeddedRuleset(text, ruleset); } reporter = new Reporter(lines, ruleset, allow, ignore); ruleset.errors = 2; // always report parsing errors as errors for (i in ruleset) { if (ruleset.hasOwnProperty(i) && ruleset[i]) { if (rules[i]) { rules[i].init(parser, reporter); } } } try { parser.parse(text); } catch (ex) { reporter.error("Fatal error, cannot continue: " + ex.message, ex.line, ex.col, {}); } report = { messages : reporter.messages, stats : reporter.stats, ruleset : reporter.ruleset, allow : reporter.allow, ignore : reporter.ignore }; report.messages.sort(function (a, b) { if (a.rollup && !b.rollup) { return 1; } else if (!a.rollup && b.rollup) { return -1; } else { return a.line - b.line; } }); return report; }; return api; })(); function Reporter(lines, ruleset, allow, ignore) { "use strict"; this.messages = []; this.stats = []; this.lines = lines; this.ruleset = ruleset; this.allow = allow; if (!this.allow) { this.allow = {}; } this.ignore = ignore; if (!this.ignore) { this.ignore = []; } } Reporter.prototype = { constructor: Reporter, error: function(message, line, col, rule) { "use strict"; this.messages.push({ type : "error", line : line, col : col, message : message, evidence: this.lines[line-1], rule : rule || {} }); }, warn: function(message, line, col, rule) { "use strict"; this.report(message, line, col, rule); }, report: function(message, line, col, rule) { "use strict"; if (this.allow.hasOwnProperty(line) && this.allow[line].hasOwnProperty(rule.id)) { return; } if (this.isIgnored(line)) { return; } this.messages.push({ type : this.ruleset[rule.id] === 2 ? "error" : "warning", line : line, col : col, message : message, evidence: this.lines[line-1], rule : rule }); }, info: function(message, line, col, rule) { "use strict"; this.messages.push({ type : "info", line : line, col : col, message : message, evidence: this.lines[line-1], rule : rule }); }, rollupError: function(message, rule) { "use strict"; this.messages.push({ type : "error", rollup : true, message : message, rule : rule }); }, rollupWarn: function(message, rule) { "use strict"; this.messages.push({ type : "warning", rollup : true, message : message, rule : rule }); }, stat: function(name, value) { "use strict"; this.stats[name] = value; }, isIgnored: function(line) { "use strict"; var ignore = false; CSSLint.Util.forEach(this.ignore, function (range) { if (range[0] <= line && line <= range[1]) { ignore = true; } }); return ignore; } }; CSSLint._Reporter = Reporter; CSSLint.Util = { mix: function(receiver, supplier) { "use strict"; var prop; for (prop in supplier) { if (supplier.hasOwnProperty(prop)) { receiver[prop] = supplier[prop]; } } return prop; }, indexOf: function(values, value) { "use strict"; if (values.indexOf) { return values.indexOf(value); } else { for (var i=0, len=values.length; i < len; i++) { if (values[i] === value) { return i; } } return -1; } }, forEach: function(values, func) { "use strict"; if (values.forEach) { return values.forEach(func); } else { for (var i=0, len=values.length; i < len; i++) { func(values[i], i, values); } } } }; CSSLint.addRule({ id: "box-model", name: "Beware of broken box size", desc: "Don't use width or height when using padding or border.", url: "https://github.com/CSSLint/csslint/wiki/Beware-of-box-model-size", browsers: "All", init: function(parser, reporter) { "use strict"; var rule = this, widthProperties = { border: 1, "border-left": 1, "border-right": 1, padding: 1, "padding-left": 1, "padding-right": 1 }, heightProperties = { border: 1, "border-bottom": 1, "border-top": 1, padding: 1, "padding-bottom": 1, "padding-top": 1 }, properties, boxSizing = false; function startRule() { properties = {}; boxSizing = false; } function endRule() { var prop, value; if (!boxSizing) { if (properties.height) { for (prop in heightProperties) { if (heightProperties.hasOwnProperty(prop) && properties[prop]) { value = properties[prop].value; if (!(prop === "padding" && value.parts.length === 2 && value.parts[0].value === 0)) { reporter.report("Using height with " + prop + " can sometimes make elements larger than you expect.", properties[prop].line, properties[prop].col, rule); } } } } if (properties.width) { for (prop in widthProperties) { if (widthProperties.hasOwnProperty(prop) && properties[prop]) { value = properties[prop].value; if (!(prop === "padding" && value.parts.length === 2 && value.parts[1].value === 0)) { reporter.report("Using width with " + prop + " can sometimes make elements larger than you expect.", properties[prop].line, properties[prop].col, rule); } } } } } } parser.addListener("startrule", startRule); parser.addListener("startfontface", startRule); parser.addListener("startpage", startRule); parser.addListener("startpagemargin", startRule); parser.addListener("startkeyframerule", startRule); parser.addListener("startviewport", startRule); parser.addListener("property", function(event) { var name = event.property.text.toLowerCase(); if (heightProperties[name] || widthProperties[name]) { if (!/^0\S*$/.test(event.value) && !(name === "border" && event.value.toString() === "none")) { properties[name] = { line: event.property.line, col: event.property.col, value: event.value }; } } else { if (/^(width|height)/i.test(name) && /^(length|percentage)/.test(event.value.parts[0].type)) { properties[name] = 1; } else if (name === "box-sizing") { boxSizing = true; } } }); parser.addListener("endrule", endRule); parser.addListener("endfontface", endRule); parser.addListener("endpage", endRule); parser.addListener("endpagemargin", endRule); parser.addListener("endkeyframerule", endRule); parser.addListener("endviewport", endRule); } }); CSSLint.addRule({ id: "bulletproof-font-face", name: "Use the bulletproof @font-face syntax", desc: "Use the bulletproof @font-face syntax to avoid 404's in old IE (http://www.fontspring.com/blog/the-new-bulletproof-font-face-syntax).", url: "https://github.com/CSSLint/csslint/wiki/Bulletproof-font-face", browsers: "All", init: function(parser, reporter) { "use strict"; var rule = this, fontFaceRule = false, firstSrc = true, ruleFailed = false, line, col; parser.addListener("startfontface", function() { fontFaceRule = true; }); parser.addListener("property", function(event) { if (!fontFaceRule) { return; } var propertyName = event.property.toString().toLowerCase(), value = event.value.toString(); line = event.line; col = event.col; if (propertyName === "src") { var regex = /^\s?url\(['"].+\.eot\?.*['"]\)\s*format\(['"]embedded-opentype['"]\).*$/i; if (!value.match(regex) && firstSrc) { ruleFailed = true; firstSrc = false; } else if (value.match(regex) && !firstSrc) { ruleFailed = false; } } }); parser.addListener("endfontface", function() { fontFaceRule = false; if (ruleFailed) { reporter.report("@font-face declaration doesn't follow the fontspring bulletproof syntax.", line, col, rule); } }); } }); CSSLint.addRule({ id: "compatible-vendor-prefixes", name: "Require compatible vendor prefixes", desc: "Include all compatible vendor prefixes to reach a wider range of users.", url: "https://github.com/CSSLint/csslint/wiki/Require-compatible-vendor-prefixes", browsers: "All", init: function (parser, reporter) { "use strict"; var rule = this, compatiblePrefixes, properties, prop, variations, prefixed, i, len, inKeyFrame = false, arrayPush = Array.prototype.push, applyTo = []; compatiblePrefixes = { "animation" : "webkit", "animation-delay" : "webkit", "animation-direction" : "webkit", "animation-duration" : "webkit", "animation-fill-mode" : "webkit", "animation-iteration-count" : "webkit", "animation-name" : "webkit", "animation-play-state" : "webkit", "animation-timing-function" : "webkit", "appearance" : "webkit moz", "border-end" : "webkit moz", "border-end-color" : "webkit moz", "border-end-style" : "webkit moz", "border-end-width" : "webkit moz", "border-image" : "webkit moz o", "border-radius" : "webkit", "border-start" : "webkit moz", "border-start-color" : "webkit moz", "border-start-style" : "webkit moz", "border-start-width" : "webkit moz", "box-align" : "webkit moz", "box-direction" : "webkit moz", "box-flex" : "webkit moz", "box-lines" : "webkit", "box-ordinal-group" : "webkit moz", "box-orient" : "webkit moz", "box-pack" : "webkit moz", "box-sizing" : "", "box-shadow" : "", "column-count" : "webkit moz ms", "column-gap" : "webkit moz ms", "column-rule" : "webkit moz ms", "column-rule-color" : "webkit moz ms", "column-rule-style" : "webkit moz ms", "column-rule-width" : "webkit moz ms", "column-width" : "webkit moz ms", "flex" : "webkit ms", "flex-basis" : "webkit", "flex-direction" : "webkit ms", "flex-flow" : "webkit", "flex-grow" : "webkit", "flex-shrink" : "webkit", "hyphens" : "epub moz", "line-break" : "webkit ms", "margin-end" : "webkit moz", "margin-start" : "webkit moz", "marquee-speed" : "webkit wap", "marquee-style" : "webkit wap", "padding-end" : "webkit moz", "padding-start" : "webkit moz", "tab-size" : "moz o", "text-size-adjust" : "webkit ms", "transform" : "webkit ms", "transform-origin" : "webkit ms", "transition" : "", "transition-delay" : "", "transition-duration" : "", "transition-property" : "", "transition-timing-function" : "", "user-modify" : "webkit moz", "user-select" : "webkit moz ms", "word-break" : "epub ms", "writing-mode" : "epub ms" }; for (prop in compatiblePrefixes) { if (compatiblePrefixes.hasOwnProperty(prop)) { variations = []; prefixed = compatiblePrefixes[prop].split(" "); for (i = 0, len = prefixed.length; i < len; i++) { variations.push("-" + prefixed[i] + "-" + prop); } compatiblePrefixes[prop] = variations; arrayPush.apply(applyTo, variations); } } parser.addListener("startrule", function () { properties = []; }); parser.addListener("startkeyframes", function (event) { inKeyFrame = event.prefix || true; }); parser.addListener("endkeyframes", function () { inKeyFrame = false; }); parser.addListener("property", function (event) { var name = event.property; if (CSSLint.Util.indexOf(applyTo, name.text) > -1) { if (!inKeyFrame || typeof inKeyFrame !== "string" || name.text.indexOf("-" + inKeyFrame + "-") !== 0) { properties.push(name); } } }); parser.addListener("endrule", function () { if (!properties.length) { return; } var propertyGroups = {}, i, len, name, prop, variations, value, full, actual, item, propertiesSpecified; for (i = 0, len = properties.length; i < len; i++) { name = properties[i]; for (prop in compatiblePrefixes) { if (compatiblePrefixes.hasOwnProperty(prop)) { variations = compatiblePrefixes[prop]; if (CSSLint.Util.indexOf(variations, name.text) > -1) { if (!propertyGroups[prop]) { propertyGroups[prop] = { full: variations.slice(0), actual: [], actualNodes: [] }; } if (CSSLint.Util.indexOf(propertyGroups[prop].actual, name.text) === -1) { propertyGroups[prop].actual.push(name.text); propertyGroups[prop].actualNodes.push(name); } } } } } for (prop in propertyGroups) { if (propertyGroups.hasOwnProperty(prop)) { value = propertyGroups[prop]; full = value.full; actual = value.actual; if (full.length > actual.length) { for (i = 0, len = full.length; i < len; i++) { item = full[i]; if (CSSLint.Util.indexOf(actual, item) === -1) { propertiesSpecified = (actual.length === 1) ? actual[0] : (actual.length === 2) ? actual.join(" and ") : actual.join(", "); reporter.report("The property " + item + " is compatible with " + propertiesSpecified + " and should be included as well.", value.actualNodes[0].line, value.actualNodes[0].col, rule); } } } } } }); } }); CSSLint.addRule({ id: "display-property-grouping", name: "Require properties appropriate for display", desc: "Certain properties shouldn't be used with certain display property values.", url: "https://github.com/CSSLint/csslint/wiki/Require-properties-appropriate-for-display", browsers: "All", init: function(parser, reporter) { "use strict"; var rule = this; var propertiesToCheck = { display: 1, "float": "none", height: 1, width: 1, margin: 1, "margin-left": 1, "margin-right": 1, "margin-bottom": 1, "margin-top": 1, padding: 1, "padding-left": 1, "padding-right": 1, "padding-bottom": 1, "padding-top": 1, "vertical-align": 1 }, properties; function reportProperty(name, display, msg) { if (properties[name]) { if (typeof propertiesToCheck[name] !== "string" || properties[name].value.toLowerCase() !== propertiesToCheck[name]) { reporter.report(msg || name + " can't be used with display: " + display + ".", properties[name].line, properties[name].col, rule); } } } function startRule() { properties = {}; } function endRule() { var display = properties.display ? properties.display.value : null; if (display) { switch (display) { case "inline": reportProperty("height", display); reportProperty("width", display); reportProperty("margin", display); reportProperty("margin-top", display); reportProperty("margin-bottom", display); reportProperty("float", display, "display:inline has no effect on floated elements (but may be used to fix the IE6 double-margin bug)."); break; case "block": reportProperty("vertical-align", display); break; case "inline-block": reportProperty("float", display); break; default: if (display.indexOf("table-") === 0) { reportProperty("margin", display); reportProperty("margin-left", display); reportProperty("margin-right", display); reportProperty("margin-top", display); reportProperty("margin-bottom", display); reportProperty("float", display); } } } } parser.addListener("startrule", startRule); parser.addListener("startfontface", startRule); parser.addListener("startkeyframerule", startRule); parser.addListener("startpagemargin", startRule); parser.addListener("startpage", startRule); parser.addListener("startviewport", startRule); parser.addListener("property", function(event) { var name = event.property.text.toLowerCase(); if (propertiesToCheck[name]) { properties[name] = { value: event.value.text, line: event.property.line, col: event.property.col }; } }); parser.addListener("endrule", endRule); parser.addListener("endfontface", endRule); parser.addListener("endkeyframerule", endRule); parser.addListener("endpagemargin", endRule); parser.addListener("endpage", endRule); parser.addListener("endviewport", endRule); } }); CSSLint.addRule({ id: "duplicate-background-images", name: "Disallow duplicate background images", desc: "Every background-image should be unique. Use a common class for e.g. sprites.", url: "https://github.com/CSSLint/csslint/wiki/Disallow-duplicate-background-images", browsers: "All", init: function(parser, reporter) { "use strict"; var rule = this, stack = {}; parser.addListener("property", function(event) { var name = event.property.text, value = event.value, i, len; if (name.match(/background/i)) { for (i=0, len=value.parts.length; i < len; i++) { if (value.parts[i].type === "uri") { if (typeof stack[value.parts[i].uri] === "undefined") { stack[value.parts[i].uri] = event; } else { reporter.report("Background image '" + value.parts[i].uri + "' was used multiple times, first declared at line " + stack[value.parts[i].uri].line + ", col " + stack[value.parts[i].uri].col + ".", event.line, event.col, rule); } } } } }); } }); CSSLint.addRule({ id: "duplicate-properties", name: "Disallow duplicate properties", desc: "Duplicate properties must appear one after the other.", url: "https://github.com/CSSLint/csslint/wiki/Disallow-duplicate-properties", browsers: "All", init: function(parser, reporter) { "use strict"; var rule = this, properties, lastProperty; function startRule() { properties = {}; } parser.addListener("startrule", startRule); parser.addListener("startfontface", startRule); parser.addListener("startpage", startRule); parser.addListener("startpagemargin", startRule); parser.addListener("startkeyframerule", startRule); parser.addListener("startviewport", startRule); parser.addListener("property", function(event) { var property = event.property, name = property.text.toLowerCase(); if (properties[name] && (lastProperty !== name || properties[name] === event.value.text)) { reporter.report("Duplicate property '" + event.property + "' found.", event.line, event.col, rule); } properties[name] = event.value.text; lastProperty = name; }); } }); CSSLint.addRule({ id: "empty-rules", name: "Disallow empty rules", desc: "Rules without any properties specified should be removed.", url: "https://github.com/CSSLint/csslint/wiki/Disallow-empty-rules", browsers: "All", init: function(parser, reporter) { "use strict"; var rule = this, count = 0; parser.addListener("startrule", function() { count=0; }); parser.addListener("property", function() { count++; }); parser.addListener("endrule", function(event) { var selectors = event.selectors; if (count === 0) { reporter.report("Rule is empty.", selectors[0].line, selectors[0].col, rule); } }); } }); CSSLint.addRule({ id: "errors", name: "Parsing Errors", desc: "This rule looks for recoverable syntax errors.", browsers: "All", init: function(parser, reporter) { "use strict"; var rule = this; parser.addListener("error", function(event) { reporter.error(event.message, event.line, event.col, rule); }); } }); CSSLint.addRule({ id: "floats", name: "Disallow too many floats", desc: "This rule tests if the float property is used too many times", url: "https://github.com/CSSLint/csslint/wiki/Disallow-too-many-floats", browsers: "All", init: function(parser, reporter) { "use strict"; var rule = this; var count = 0; parser.addListener("property", function(event) { if (!reporter.isIgnored(event.property.line)) { if (event.property.text.toLowerCase() === "float" && event.value.text.toLowerCase() !== "none") { count++; } } }); parser.addListener("endstylesheet", function() { reporter.stat("floats", count); if (count >= 10) { reporter.rollupWarn("Too many floats (" + count + "), you're probably using them for layout. Consider using a grid system instead.", rule); } }); } }); CSSLint.addRule({ id: "font-faces", name: "Don't use too many web fonts", desc: "Too many different web fonts in the same stylesheet.", url: "https://github.com/CSSLint/csslint/wiki/Don%27t-use-too-many-web-fonts", browsers: "All", init: function(parser, reporter) { "use strict"; var rule = this, count = 0; parser.addListener("startfontface", function(event) { if (!reporter.isIgnored(event.line)) { count++; } }); parser.addListener("endstylesheet", function() { if (count > 5) { reporter.rollupWarn("Too many @font-face declarations (" + count + ").", rule); } }); } }); CSSLint.addRule({ id: "font-sizes", name: "Disallow too many font sizes", desc: "Checks the number of font-size declarations.", url: "https://github.com/CSSLint/csslint/wiki/Don%27t-use-too-many-font-size-declarations", browsers: "All", init: function(parser, reporter) { "use strict"; var rule = this, count = 0; parser.addListener("property", function(event) { if (!reporter.isIgnored(event.property.line)) { if (event.property.toString() === "font-size") { count++; } } }); parser.addListener("endstylesheet", function() { reporter.stat("font-sizes", count); if (count >= 10) { reporter.rollupWarn("Too many font-size declarations (" + count + "), abstraction needed.", rule); } }); } }); CSSLint.addRule({ id: "gradients", name: "Require all gradient definitions", desc: "When using a vendor-prefixed gradient, make sure to use them all.", url: "https://github.com/CSSLint/csslint/wiki/Require-all-gradient-definitions", browsers: "All", init: function(parser, reporter) { "use strict"; var rule = this, gradients; parser.addListener("startrule", function() { gradients = { moz: 0, webkit: 0, oldWebkit: 0, o: 0 }; }); parser.addListener("property", function(event) { if (/\-(moz|o|webkit)(?:\-(?:linear|radial))\-gradient/i.test(event.value)) { gradients[RegExp.$1] = 1; } else if (/\-webkit\-gradient/i.test(event.value)) { gradients.oldWebkit = 1; } }); parser.addListener("endrule", function(event) { var missing = []; if (!gradients.moz) { missing.push("Firefox 3.6+"); } if (!gradients.webkit) { missing.push("Webkit (Safari 5+, Chrome)"); } if (!gradients.oldWebkit) { missing.push("Old Webkit (Safari 4+, Chrome)"); } if (!gradients.o) { missing.push("Opera 11.1+"); } if (missing.length && missing.length < 4) { reporter.report("Missing vendor-prefixed CSS gradients for " + missing.join(", ") + ".", event.selectors[0].line, event.selectors[0].col, rule); } }); } }); CSSLint.addRule({ id: "ids", name: "Disallow IDs in selectors", desc: "Selectors should not contain IDs.", url: "https://github.com/CSSLint/csslint/wiki/Disallow-IDs-in-selectors", browsers: "All", init: function(parser, reporter) { "use strict"; var rule = this; parser.addListener("startrule", function(event) { var selectors = event.selectors, selector, part, modifier, idCount, i, j, k; for (i=0; i < selectors.length; i++) { selector = selectors[i]; idCount = 0; for (j=0; j < selector.parts.length; j++) { part = selector.parts[j]; if (part.type === parser.SELECTOR_PART_TYPE) { for (k=0; k < part.modifiers.length; k++) { modifier = part.modifiers[k]; if (modifier.type === "id") { idCount++; } } } } if (idCount === 1) { reporter.report("Don't use IDs in selectors.", selector.line, selector.col, rule); } else if (idCount > 1) { reporter.report(idCount + " IDs in the selector, really?", selector.line, selector.col, rule); } } }); } }); CSSLint.addRule({ id: "import-ie-limit", name: "@import limit on IE6-IE9", desc: "IE6-9 supports up to 31 @import per stylesheet", browsers: "IE6, IE7, IE8, IE9", init: function(parser, reporter) { "use strict"; var rule = this, MAX_IMPORT_COUNT = 31, count = 0; function startPage() { count = 0; } parser.addListener("startpage", startPage); parser.addListener("import", function() { count++; }); parser.addListener("endstylesheet", function() { if (count > MAX_IMPORT_COUNT) { reporter.rollupError( "Too many @import rules (" + count + "). IE6-9 supports up to 31 import per stylesheet.", rule ); } }); } }); CSSLint.addRule({ id: "import", name: "Disallow @import", desc: "Don't use @import, use <link> instead.", url: "https://github.com/CSSLint/csslint/wiki/Disallow-%40import", browsers: "All", init: function(parser, reporter) { "use strict"; var rule = this; parser.addListener("import", function(event) { reporter.report("@import prevents parallel downloads, use <link> instead.", event.line, event.col, rule); }); } }); CSSLint.addRule({ id: "important", name: "Disallow !important", desc: "Be careful when using !important declaration", url: "https://github.com/CSSLint/csslint/wiki/Disallow-%21important", browsers: "All", init: function(parser, reporter) { "use strict"; var rule = this, count = 0; parser.addListener("property", function(event) { if (!reporter.isIgnored(event.line)) { if (event.important === true) { count++; reporter.report("Use of !important", event.line, event.col, rule); } } }); parser.addListener("endstylesheet", function() { reporter.stat("important", count); if (count >= 10) { reporter.rollupWarn("Too many !important declarations (" + count + "), try to use less than 10 to avoid specificity issues.", rule); } }); } }); CSSLint.addRule({ id: "known-properties", name: "Require use of known properties", desc: "Properties should be known (listed in CSS3 specification) or be a vendor-prefixed property.", url: "https://github.com/CSSLint/csslint/wiki/Require-use-of-known-properties", browsers: "All", init: function(parser, reporter) { "use strict"; var rule = this; parser.addListener("property", function(event) { if (event.invalid) { reporter.report(event.invalid.message, event.line, event.col, rule); } }); } }); CSSLint.addRule({ id: "order-alphabetical", name: "Alphabetical order", desc: "Assure properties are in alphabetical order", browsers: "All", init: function(parser, reporter) { "use strict"; var rule = this, properties; var startRule = function () { properties = []; }; var endRule = function(event) { var currentProperties = properties.join(","), expectedProperties = properties.sort().join(","); if (currentProperties !== expectedProperties) { reporter.report("Rule doesn't have all its properties in alphabetical order.", event.line, event.col, rule); } }; parser.addListener("startrule", startRule); parser.addListener("startfontface", startRule); parser.addListener("startpage", startRule); parser.addListener("startpagemargin", startRule); parser.addListener("startkeyframerule", startRule); parser.addListener("startviewport", startRule); parser.addListener("property", function(event) { var name = event.property.text, lowerCasePrefixLessName = name.toLowerCase().replace(/^-.*?-/, ""); properties.push(lowerCasePrefixLessName); }); parser.addListener("endrule", endRule); parser.addListener("endfontface", endRule); parser.addListener("endpage", endRule); parser.addListener("endpagemargin", endRule); parser.addListener("endkeyframerule", endRule); parser.addListener("endviewport", endRule); } }); CSSLint.addRule({ id: "outline-none", name: "Disallow outline: none", desc: "Use of outline: none or outline: 0 should be limited to :focus rules.", url: "https://github.com/CSSLint/csslint/wiki/Disallow-outline%3Anone", browsers: "All", tags: ["Accessibility"], init: function(parser, reporter) { "use strict"; var rule = this, lastRule; function startRule(event) { if (event.selectors) { lastRule = { line: event.line, col: event.col, selectors: event.selectors, propCount: 0, outline: false }; } else { lastRule = null; } } function endRule() { if (lastRule) { if (lastRule.outline) { if (lastRule.selectors.toString().toLowerCase().indexOf(":focus") === -1) { reporter.report("Outlines should only be modified using :focus.", lastRule.line, lastRule.col, rule); } else if (lastRule.propCount === 1) { reporter.report("Outlines shouldn't be hidden unless other visual changes are made.", lastRule.line, lastRule.col, rule); } } } } parser.addListener("startrule", startRule); parser.addListener("startfontface", startRule); parser.addListener("startpage", startRule); parser.addListener("startpagemargin", startRule); parser.addListener("startkeyframerule", startRule); parser.addListener("startviewport", startRule); parser.addListener("property", function(event) { var name = event.property.text.toLowerCase(), value = event.value; if (lastRule) { lastRule.propCount++; if (name === "outline" && (value.toString() === "none" || value.toString() === "0")) { lastRule.outline = true; } } }); parser.addListener("endrule", endRule); parser.addListener("endfontface", endRule); parser.addListener("endpage", endRule); parser.addListener("endpagemargin", endRule); parser.addListener("endkeyframerule", endRule); parser.addListener("endviewport", endRule); } }); CSSLint.addRule({ id: "overqualified-elements", name: "Disallow overqualified elements", desc: "Don't use classes or IDs with elements (a.foo or a#foo).", url: "https://github.com/CSSLint/csslint/wiki/Disallow-overqualified-elements", browsers: "All", init: function(parser, reporter) { "use strict"; var rule = this, classes = {}; parser.addListener("startrule", function(event) { var selectors = event.selectors, selector, part, modifier, i, j, k; for (i=0; i < selectors.length; i++) { selector = selectors[i]; for (j=0; j < selector.parts.length; j++) { part = selector.parts[j]; if (part.type === parser.SELECTOR_PART_TYPE) { for (k=0; k < part.modifiers.length; k++) { modifier = part.modifiers[k]; if (part.elementName && modifier.type === "id") { reporter.report("Element (" + part + ") is overqualified, just use " + modifier + " without element name.", part.line, part.col, rule); } else if (modifier.type === "class") { if (!classes[modifier]) { classes[modifier] = []; } classes[modifier].push({ modifier: modifier, part: part }); } } } } } }); parser.addListener("endstylesheet", function() { var prop; for (prop in classes) { if (classes.hasOwnProperty(prop)) { if (classes[prop].length === 1 && classes[prop][0].part.elementName) { reporter.report("Element (" + classes[prop][0].part + ") is overqualified, just use " + classes[prop][0].modifier + " without element name.", classes[prop][0].part.line, classes[prop][0].part.col, rule); } } } }); } }); CSSLint.addRule({ id: "regex-selectors", name: "Disallow selectors that look like regexs", desc: "Selectors that look like regular expressions are slow and should be avoided.", url: "https://github.com/CSSLint/csslint/wiki/Disallow-selectors-that-look-like-regular-expressions", browsers: "All", init: function(parser, reporter) { "use strict"; var rule = this; parser.addListener("startrule", function(event) { var selectors = event.selectors, selector, part, modifier, i, j, k; for (i=0; i < selectors.length; i++) { selector = selectors[i]; for (j=0; j < selector.parts.length; j++) { part = selector.parts[j]; if (part.type === parser.SELECTOR_PART_TYPE) { for (k=0; k < part.modifiers.length; k++) { modifier = part.modifiers[k]; if (modifier.type === "attribute") { if (/([~\|\^\$\*]=)/.test(modifier)) { reporter.report("Attribute selectors with " + RegExp.$1 + " are slow!", modifier.line, modifier.col, rule); } } } } } } }); } }); CSSLint.addRule({ id: "rules-count", name: "Rules Count", desc: "Track how many rules there are.", browsers: "All", init: function(parser, reporter) { "use strict"; var count = 0; parser.addListener("startrule", function() { count++; }); parser.addListener("endstylesheet", function() { reporter.stat("rule-count", count); }); } }); CSSLint.addRule({ id: "selector-max-approaching", name: "Warn when approaching the 4095 selector limit for IE", desc: "Will warn when selector count is >= 3800 selectors.", browsers: "IE", init: function(parser, reporter) { "use strict"; var rule = this, count = 0; parser.addListener("startrule", function(event) { count += event.selectors.length; }); parser.addListener("endstylesheet", function() { if (count >= 3800) { reporter.report("You have " + count + " selectors. Internet Explorer supports a maximum of 4095 selectors per stylesheet. Consider refactoring.", 0, 0, rule); } }); } }); CSSLint.addRule({ id: "selector-max", name: "Error when past the 4095 selector limit for IE", desc: "Will error when selector count is > 4095.", browsers: "IE", init: function(parser, reporter) { "use strict"; var rule = this, count = 0; parser.addListener("startrule", function(event) { count += event.selectors.length; }); parser.addListener("endstylesheet", function() { if (count > 4095) { reporter.report("You have " + count + " selectors. Internet Explorer supports a maximum of 4095 selectors per stylesheet. Consider refactoring.", 0, 0, rule); } }); } }); CSSLint.addRule({ id: "selector-newline", name: "Disallow new-line characters in selectors", desc: "New-line characters in selectors are usually a forgotten comma and not a descendant combinator.", browsers: "All", init: function(parser, reporter) { "use strict"; var rule = this; function startRule(event) { var i, len, selector, p, n, pLen, part, part2, type, currentLine, nextLine, selectors = event.selectors; for (i = 0, len = selectors.length; i < len; i++) { selector = selectors[i]; for (p = 0, pLen = selector.parts.length; p < pLen; p++) { for (n = p + 1; n < pLen; n++) { part = selector.parts[p]; part2 = selector.parts[n]; type = part.type; currentLine = part.line; nextLine = part2.line; if (type === "descendant" && nextLine > currentLine) { reporter.report("newline character found in selector (forgot a comma?)", currentLine, selectors[i].parts[0].col, rule); } } } } } parser.addListener("startrule", startRule); } }); CSSLint.addRule({ id: "shorthand", name: "Require shorthand properties", desc: "Use shorthand properties where possible.", url: "https://github.com/CSSLint/csslint/wiki/Require-shorthand-properties", browsers: "All", init: function(parser, reporter) { "use strict"; var rule = this, prop, i, len, propertiesToCheck = {}, properties, mapping = { "margin": [ "margin-top", "margin-bottom", "margin-left", "margin-right" ], "padding": [ "padding-top", "padding-bottom", "padding-left", "padding-right" ] }; for (prop in mapping) { if (mapping.hasOwnProperty(prop)) { for (i=0, len=mapping[prop].length; i < len; i++) { propertiesToCheck[mapping[prop][i]] = prop; } } } function startRule() { properties = {}; } function endRule(event) { var prop, i, len, total; for (prop in mapping) { if (mapping.hasOwnProperty(prop)) { total=0; for (i=0, len=mapping[prop].length; i < len; i++) { total += properties[mapping[prop][i]] ? 1 : 0; } if (total === mapping[prop].length) { reporter.report("The properties " + mapping[prop].join(", ") + " can be replaced by " + prop + ".", event.line, event.col, rule); } } } } parser.addListener("startrule", startRule); parser.addListener("startfontface", startRule); parser.addListener("property", function(event) { var name = event.property.toString().toLowerCase(); if (propertiesToCheck[name]) { properties[name] = 1; } }); parser.addListener("endrule", endRule); parser.addListener("endfontface", endRule); } }); CSSLint.addRule({ id: "star-property-hack", name: "Disallow properties with a star prefix", desc: "Checks for the star property hack (targets IE6/7)", url: "https://github.com/CSSLint/csslint/wiki/Disallow-star-hack", browsers: "All", init: function(parser, reporter) { "use strict"; var rule = this; parser.addListener("property", function(event) { var property = event.property; if (property.hack === "*") { reporter.report("Property with star prefix found.", event.property.line, event.property.col, rule); } }); } }); CSSLint.addRule({ id: "text-indent", name: "Disallow negative text-indent", desc: "Checks for text indent less than -99px", url: "https://github.com/CSSLint/csslint/wiki/Disallow-negative-text-indent", browsers: "All", init: function(parser, reporter) { "use strict"; var rule = this, textIndent, direction; function startRule() { textIndent = false; direction = "inherit"; } function endRule() { if (textIndent && direction !== "ltr") { reporter.report("Negative text-indent doesn't work well with RTL. If you use text-indent for image replacement explicitly set direction for that item to ltr.", textIndent.line, textIndent.col, rule); } } parser.addListener("startrule", startRule); parser.addListener("startfontface", startRule); parser.addListener("property", function(event) { var name = event.property.toString().toLowerCase(), value = event.value; if (name === "text-indent" && value.parts[0].value < -99) { textIndent = event.property; } else if (name === "direction" && value.toString() === "ltr") { direction = "ltr"; } }); parser.addListener("endrule", endRule); parser.addListener("endfontface", endRule); } }); CSSLint.addRule({ id: "underscore-property-hack", name: "Disallow properties with an underscore prefix", desc: "Checks for the underscore property hack (targets IE6)", url: "https://github.com/CSSLint/csslint/wiki/Disallow-underscore-hack", browsers: "All", init: function(parser, reporter) { "use strict"; var rule = this; parser.addListener("property", function(event) { var property = event.property; if (property.hack === "_") { reporter.report("Property with underscore prefix found.", event.property.line, event.property.col, rule); } }); } }); CSSLint.addRule({ id: "universal-selector", name: "Disallow universal selector", desc: "The universal selector (*) is known to be slow.", url: "https://github.com/CSSLint/csslint/wiki/Disallow-universal-selector", browsers: "All", init: function(parser, reporter) { "use strict"; var rule = this; parser.addListener("startrule", function(event) { var selectors = event.selectors, selector, part, i; for (i=0; i < selectors.length; i++) { selector = selectors[i]; part = selector.parts[selector.parts.length-1]; if (part.elementName === "*") { reporter.report(rule.desc, part.line, part.col, rule); } } }); } }); CSSLint.addRule({ id: "unqualified-attributes", name: "Disallow unqualified attribute selectors", desc: "Unqualified attribute selectors are known to be slow.", url: "https://github.com/CSSLint/csslint/wiki/Disallow-unqualified-attribute-selectors", browsers: "All", init: function(parser, reporter) { "use strict"; var rule = this; parser.addListener("startrule", function(event) { var selectors = event.selectors, selectorContainsClassOrId = false, selector, part, modifier, i, k; for (i=0; i < selectors.length; i++) { selector = selectors[i]; part = selector.parts[selector.parts.length-1]; if (part.type === parser.SELECTOR_PART_TYPE) { for (k=0; k < part.modifiers.length; k++) { modifier = part.modifiers[k]; if (modifier.type === "class" || modifier.type === "id") { selectorContainsClassOrId = true; break; } } if (!selectorContainsClassOrId) { for (k=0; k < part.modifiers.length; k++) { modifier = part.modifiers[k]; if (modifier.type === "attribute" && (!part.elementName || part.elementName === "*")) { reporter.report(rule.desc, part.line, part.col, rule); } } } } } }); } }); CSSLint.addRule({ id: "vendor-prefix", name: "Require standard property with vendor prefix", desc: "When using a vendor-prefixed property, make sure to include the standard one.", url: "https://github.com/CSSLint/csslint/wiki/Require-standard-property-with-vendor-prefix", browsers: "All", init: function(parser, reporter) { "use strict"; var rule = this, properties, num, propertiesToCheck = { "-webkit-border-radius": "border-radius", "-webkit-border-top-left-radius": "border-top-left-radius", "-webkit-border-top-right-radius": "border-top-right-radius", "-webkit-border-bottom-left-radius": "border-bottom-left-radius", "-webkit-border-bottom-right-radius": "border-bottom-right-radius", "-o-border-radius": "border-radius", "-o-border-top-left-radius": "border-top-left-radius", "-o-border-top-right-radius": "border-top-right-radius", "-o-border-bottom-left-radius": "border-bottom-left-radius", "-o-border-bottom-right-radius": "border-bottom-right-radius", "-moz-border-radius": "border-radius", "-moz-border-radius-topleft": "border-top-left-radius", "-moz-border-radius-topright": "border-top-right-radius", "-moz-border-radius-bottomleft": "border-bottom-left-radius", "-moz-border-radius-bottomright": "border-bottom-right-radius", "-moz-column-count": "column-count", "-webkit-column-count": "column-count", "-moz-column-gap": "column-gap", "-webkit-column-gap": "column-gap", "-moz-column-rule": "column-rule", "-webkit-column-rule": "column-rule", "-moz-column-rule-style": "column-rule-style", "-webkit-column-rule-style": "column-rule-style", "-moz-column-rule-color": "column-rule-color", "-webkit-column-rule-color": "column-rule-color", "-moz-column-rule-width": "column-rule-width", "-webkit-column-rule-width": "column-rule-width", "-moz-column-width": "column-width", "-webkit-column-width": "column-width", "-webkit-column-span": "column-span", "-webkit-columns": "columns", "-moz-box-shadow": "box-shadow", "-webkit-box-shadow": "box-shadow", "-moz-transform": "transform", "-webkit-transform": "transform", "-o-transform": "transform", "-ms-transform": "transform", "-moz-transform-origin": "transform-origin", "-webkit-transform-origin": "transform-origin", "-o-transform-origin": "transform-origin", "-ms-transform-origin": "transform-origin", "-moz-box-sizing": "box-sizing", "-webkit-box-sizing": "box-sizing" }; function startRule() { properties = {}; num = 1; } function endRule() { var prop, i, len, needed, actual, needsStandard = []; for (prop in properties) { if (propertiesToCheck[prop]) { needsStandard.push({ actual: prop, needed: propertiesToCheck[prop] }); } } for (i=0, len=needsStandard.length; i < len; i++) { needed = needsStandard[i].needed; actual = needsStandard[i].actual; if (!properties[needed]) { reporter.report("Missing standard property '" + needed + "' to go along with '" + actual + "'.", properties[actual][0].name.line, properties[actual][0].name.col, rule); } else { if (properties[needed][0].pos < properties[actual][0].pos) { reporter.report("Standard property '" + needed + "' should come after vendor-prefixed property '" + actual + "'.", properties[actual][0].name.line, properties[actual][0].name.col, rule); } } } } parser.addListener("startrule", startRule); parser.addListener("startfontface", startRule); parser.addListener("startpage", startRule); parser.addListener("startpagemargin", startRule); parser.addListener("startkeyframerule", startRule); parser.addListener("startviewport", startRule); parser.addListener("property", function(event) { var name = event.property.text.toLowerCase(); if (!properties[name]) { properties[name] = []; } properties[name].push({ name: event.property, value: event.value, pos: num++ }); }); parser.addListener("endrule", endRule); parser.addListener("endfontface", endRule); parser.addListener("endpage", endRule); parser.addListener("endpagemargin", endRule); parser.addListener("endkeyframerule", endRule); parser.addListener("endviewport", endRule); } }); CSSLint.addRule({ id: "zero-units", name: "Disallow units for 0 values", desc: "You don't need to specify units when a value is 0.", url: "https://github.com/CSSLint/csslint/wiki/Disallow-units-for-zero-values", browsers: "All", init: function(parser, reporter) { "use strict"; var rule = this; parser.addListener("property", function(event) { var parts = event.value.parts, i = 0, len = parts.length; while (i < len) { if ((parts[i].units || parts[i].type === "percentage") && parts[i].value === 0 && parts[i].type !== "time") { reporter.report("Values of 0 shouldn't have units specified.", parts[i].line, parts[i].col, rule); } i++; } }); } }); (function() { "use strict"; var xmlEscape = function(str) { if (!str || str.constructor !== String) { return ""; } return str.replace(/["&><]/g, function(match) { switch (match) { case "\"": return """; case "&": return "&"; case "<": return "<"; case ">": return ">"; } }); }; CSSLint.addFormatter({ id: "checkstyle-xml", name: "Checkstyle XML format", startFormat: function() { return "<?xml version=\"1.0\" encoding=\"utf-8\"?><checkstyle>"; }, endFormat: function() { return "</checkstyle>"; }, readError: function(filename, message) { return "<file name=\"" + xmlEscape(filename) + "\"><error line=\"0\" column=\"0\" severty=\"error\" message=\"" + xmlEscape(message) + "\"></error></file>"; }, formatResults: function(results, filename/*, options*/) { var messages = results.messages, output = []; var generateSource = function(rule) { if (!rule || !("name" in rule)) { return ""; } return "net.csslint." + rule.name.replace(/\s/g, ""); }; if (messages.length > 0) { output.push("<file name=\""+filename+"\">"); CSSLint.Util.forEach(messages, function (message) { if (!message.rollup) { output.push("<error line=\"" + message.line + "\" column=\"" + message.col + "\" severity=\"" + message.type + "\"" + " message=\"" + xmlEscape(message.message) + "\" source=\"" + generateSource(message.rule) +"\"/>"); } }); output.push("</file>"); } return output.join(""); } }); }()); CSSLint.addFormatter({ id: "compact", name: "Compact, 'porcelain' format", startFormat: function() { "use strict"; return ""; }, endFormat: function() { "use strict"; return ""; }, formatResults: function(results, filename, options) { "use strict"; var messages = results.messages, output = ""; options = options || {}; var capitalize = function(str) { return str.charAt(0).toUpperCase() + str.slice(1); }; if (messages.length === 0) { return options.quiet ? "" : filename + ": Lint Free!"; } CSSLint.Util.forEach(messages, function(message) { if (message.rollup) { output += filename + ": " + capitalize(message.type) + " - " + message.message + " (" + message.rule.id + ")\n"; } else { output += filename + ": line " + message.line + ", col " + message.col + ", " + capitalize(message.type) + " - " + message.message + " (" + message.rule.id + ")\n"; } }); return output; } }); CSSLint.addFormatter({ id: "csslint-xml", name: "CSSLint XML format", startFormat: function() { "use strict"; return "<?xml version=\"1.0\" encoding=\"utf-8\"?><csslint>"; }, endFormat: function() { "use strict"; return "</csslint>"; }, formatResults: function(results, filename/*, options*/) { "use strict"; var messages = results.messages, output = []; var escapeSpecialCharacters = function(str) { if (!str || str.constructor !== String) { return ""; } return str.replace(/"/g, "'").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">"); }; if (messages.length > 0) { output.push("<file name=\""+filename+"\">"); CSSLint.Util.forEach(messages, function (message) { if (message.rollup) { output.push("<issue severity=\"" + message.type + "\" reason=\"" + escapeSpecialCharacters(message.message) + "\" evidence=\"" + escapeSpecialCharacters(message.evidence) + "\"/>"); } else { output.push("<issue line=\"" + message.line + "\" char=\"" + message.col + "\" severity=\"" + message.type + "\"" + " reason=\"" + escapeSpecialCharacters(message.message) + "\" evidence=\"" + escapeSpecialCharacters(message.evidence) + "\"/>"); } }); output.push("</file>"); } return output.join(""); } }); CSSLint.addFormatter({ id: "json", name: "JSON", startFormat: function() { "use strict"; this.json = []; return ""; }, endFormat: function() { "use strict"; var ret = ""; if (this.json.length > 0) { if (this.json.length === 1) { ret = JSON.stringify(this.json[0]); } else { ret = JSON.stringify(this.json); } } return ret; }, formatResults: function(results, filename, options) { "use strict"; if (results.messages.length > 0 || !options.quiet) { this.json.push({ filename: filename, messages: results.messages, stats: results.stats }); } return ""; } }); CSSLint.addFormatter({ id: "junit-xml", name: "JUNIT XML format", startFormat: function() { "use strict"; return "<?xml version=\"1.0\" encoding=\"utf-8\"?><testsuites>"; }, endFormat: function() { "use strict"; return "</testsuites>"; }, formatResults: function(results, filename/*, options*/) { "use strict"; var messages = results.messages, output = [], tests = { "error": 0, "failure": 0 }; var generateSource = function(rule) { if (!rule || !("name" in rule)) { return ""; } return "net.csslint." + rule.name.replace(/\s/g, ""); }; var escapeSpecialCharacters = function(str) { if (!str || str.constructor !== String) { return ""; } return str.replace(/"/g, "'").replace(/</g, "<").replace(/>/g, ">"); }; if (messages.length > 0) { messages.forEach(function (message) { var type = message.type === "warning" ? "error" : message.type; if (!message.rollup) { output.push("<testcase time=\"0\" name=\"" + generateSource(message.rule) + "\">"); output.push("<" + type + " message=\"" + escapeSpecialCharacters(message.message) + "\"><![CDATA[" + message.line + ":" + message.col + ":" + escapeSpecialCharacters(message.evidence) + "]]></" + type + ">"); output.push("</testcase>"); tests[type] += 1; } }); output.unshift("<testsuite time=\"0\" tests=\"" + messages.length + "\" skipped=\"0\" errors=\"" + tests.error + "\" failures=\"" + tests.failure + "\" package=\"net.csslint\" name=\"" + filename + "\">"); output.push("</testsuite>"); } return output.join(""); } }); CSSLint.addFormatter({ id: "lint-xml", name: "Lint XML format", startFormat: function() { "use strict"; return "<?xml version=\"1.0\" encoding=\"utf-8\"?><lint>"; }, endFormat: function() { "use strict"; return "</lint>"; }, formatResults: function(results, filename/*, options*/) { "use strict"; var messages = results.messages, output = []; var escapeSpecialCharacters = function(str) { if (!str || str.constructor !== String) { return ""; } return str.replace(/"/g, "'").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">"); }; if (messages.length > 0) { output.push("<file name=\""+filename+"\">"); CSSLint.Util.forEach(messages, function (message) { if (message.rollup) { output.push("<issue severity=\"" + message.type + "\" reason=\"" + escapeSpecialCharacters(message.message) + "\" evidence=\"" + escapeSpecialCharacters(message.evidence) + "\"/>"); } else { var rule = ""; if (message.rule && message.rule.id) { rule = "rule=\"" + escapeSpecialCharacters(message.rule.id) + "\" "; } output.push("<issue " + rule + "line=\"" + message.line + "\" char=\"" + message.col + "\" severity=\"" + message.type + "\"" + " reason=\"" + escapeSpecialCharacters(message.message) + "\" evidence=\"" + escapeSpecialCharacters(message.evidence) + "\"/>"); } }); output.push("</file>"); } return output.join(""); } }); CSSLint.addFormatter({ id: "text", name: "Plain Text", startFormat: function() { "use strict"; return ""; }, endFormat: function() { "use strict"; return ""; }, formatResults: function(results, filename, options) { "use strict"; var messages = results.messages, output = ""; options = options || {}; if (messages.length === 0) { return options.quiet ? "" : "\n\ncsslint: No errors in " + filename + "."; } output = "\n\ncsslint: There "; if (messages.length === 1) { output += "is 1 problem"; } else { output += "are " + messages.length + " problems"; } output += " in " + filename + "."; var pos = filename.lastIndexOf("/"), shortFilename = filename; if (pos === -1) { pos = filename.lastIndexOf("\\"); } if (pos > -1) { shortFilename = filename.substring(pos+1); } CSSLint.Util.forEach(messages, function (message, i) { output = output + "\n\n" + shortFilename; if (message.rollup) { output += "\n" + (i+1) + ": " + message.type; output += "\n" + message.message; } else { output += "\n" + (i+1) + ": " + message.type + " at line " + message.line + ", col " + message.col; output += "\n" + message.message; output += "\n" + message.evidence; } }); return output; } }); return CSSLint; })(); module.exports.CSSLint = CSSLint; }); define("ace/mode/css_worker",[], function(require, exports, module) { "use strict"; var oop = require("../lib/oop"); var lang = require("../lib/lang"); var Mirror = require("../worker/mirror").Mirror; var CSSLint = require("./css/csslint").CSSLint; var Worker = exports.Worker = function(sender) { Mirror.call(this, sender); this.setTimeout(400); this.ruleset = null; this.setDisabledRules("ids|order-alphabetical"); this.setInfoRules( "adjoining-classes|zero-units|gradients|box-model|" + "import|outline-none|vendor-prefix" ); }; oop.inherits(Worker, Mirror); (function() { this.setInfoRules = function(ruleNames) { if (typeof ruleNames == "string") ruleNames = ruleNames.split("|"); this.infoRules = lang.arrayToMap(ruleNames); this.doc.getValue() && this.deferredUpdate.schedule(100); }; this.setDisabledRules = function(ruleNames) { if (!ruleNames) { this.ruleset = null; } else { if (typeof ruleNames == "string") ruleNames = ruleNames.split("|"); var all = {}; CSSLint.getRules().forEach(function(x){ all[x.id] = true; }); ruleNames.forEach(function(x) { delete all[x]; }); this.ruleset = all; } this.doc.getValue() && this.deferredUpdate.schedule(100); }; this.onUpdate = function() { var value = this.doc.getValue(); if (!value) return this.sender.emit("annotate", []); var infoRules = this.infoRules; var result = CSSLint.verify(value, this.ruleset); this.sender.emit("annotate", result.messages.map(function(msg) { return { row: msg.line - 1, column: msg.col - 1, text: msg.message, type: infoRules[msg.rule.id] ? "info" : msg.type, rule: msg.rule.name }; })); }; }).call(Worker.prototype); });