PageRenderTime 70ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 2ms

/lib/ace/mode/css/csslint.js

https://gitlab.com/GeekSir/ace
JavaScript | 9628 lines | 6298 code | 1272 blank | 2058 comment | 722 complexity | 572f604e808762d053dcd0a5aefb53e5 MD5 | raw file
Possible License(s): BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. define(function(require, exports, module) {
  2. /*!
  3. CSSLint
  4. Copyright (c) 2014 Nicole Sullivan and Nicholas C. Zakas. All rights reserved.
  5. Permission is hereby granted, free of charge, to any person obtaining a copy
  6. of this software and associated documentation files (the 'Software'), to deal
  7. in the Software without restriction, including without limitation the rights
  8. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. copies of the Software, and to permit persons to whom the Software is
  10. furnished to do so, subject to the following conditions:
  11. The above copyright notice and this permission notice shall be included in
  12. all copies or substantial portions of the Software.
  13. THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. THE SOFTWARE.
  20. */
  21. /* Build: v0.10.0 22-July-2014 01:17:52 */
  22. /*!
  23. Parser-Lib
  24. Copyright (c) 2009-2011 Nicholas C. Zakas. All rights reserved.
  25. Permission is hereby granted, free of charge, to any person obtaining a copy
  26. of this software and associated documentation files (the "Software"), to deal
  27. in the Software without restriction, including without limitation the rights
  28. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  29. copies of the Software, and to permit persons to whom the Software is
  30. furnished to do so, subject to the following conditions:
  31. The above copyright notice and this permission notice shall be included in
  32. all copies or substantial portions of the Software.
  33. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  34. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  35. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  36. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  37. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  38. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  39. THE SOFTWARE.
  40. */
  41. /* Version v0.2.5, Build time: 7-May-2014 03:37:38 */
  42. var parserlib = {};
  43. (function(){
  44. /**
  45. * A generic base to inherit from for any object
  46. * that needs event handling.
  47. * @class EventTarget
  48. * @constructor
  49. */
  50. function EventTarget(){
  51. /**
  52. * The array of listeners for various events.
  53. * @type Object
  54. * @property _listeners
  55. * @private
  56. */
  57. this._listeners = {};
  58. }
  59. EventTarget.prototype = {
  60. //restore constructor
  61. constructor: EventTarget,
  62. /**
  63. * Adds a listener for a given event type.
  64. * @param {String} type The type of event to add a listener for.
  65. * @param {Function} listener The function to call when the event occurs.
  66. * @return {void}
  67. * @method addListener
  68. */
  69. addListener: function(type, listener){
  70. if (!this._listeners[type]){
  71. this._listeners[type] = [];
  72. }
  73. this._listeners[type].push(listener);
  74. },
  75. /**
  76. * Fires an event based on the passed-in object.
  77. * @param {Object|String} event An object with at least a 'type' attribute
  78. * or a string indicating the event name.
  79. * @return {void}
  80. * @method fire
  81. */
  82. fire: function(event){
  83. if (typeof event == "string"){
  84. event = { type: event };
  85. }
  86. if (typeof event.target != "undefined"){
  87. event.target = this;
  88. }
  89. if (typeof event.type == "undefined"){
  90. throw new Error("Event object missing 'type' property.");
  91. }
  92. if (this._listeners[event.type]){
  93. //create a copy of the array and use that so listeners can't chane
  94. var listeners = this._listeners[event.type].concat();
  95. for (var i=0, len=listeners.length; i < len; i++){
  96. listeners[i].call(this, event);
  97. }
  98. }
  99. },
  100. /**
  101. * Removes a listener for a given event type.
  102. * @param {String} type The type of event to remove a listener from.
  103. * @param {Function} listener The function to remove from the event.
  104. * @return {void}
  105. * @method removeListener
  106. */
  107. removeListener: function(type, listener){
  108. if (this._listeners[type]){
  109. var listeners = this._listeners[type];
  110. for (var i=0, len=listeners.length; i < len; i++){
  111. if (listeners[i] === listener){
  112. listeners.splice(i, 1);
  113. break;
  114. }
  115. }
  116. }
  117. }
  118. };
  119. /**
  120. * Convenient way to read through strings.
  121. * @namespace parserlib.util
  122. * @class StringReader
  123. * @constructor
  124. * @param {String} text The text to read.
  125. */
  126. function StringReader(text){
  127. /**
  128. * The input text with line endings normalized.
  129. * @property _input
  130. * @type String
  131. * @private
  132. */
  133. this._input = text.replace(/\n\r?/g, "\n");
  134. /**
  135. * The row for the character to be read next.
  136. * @property _line
  137. * @type int
  138. * @private
  139. */
  140. this._line = 1;
  141. /**
  142. * The column for the character to be read next.
  143. * @property _col
  144. * @type int
  145. * @private
  146. */
  147. this._col = 1;
  148. /**
  149. * The index of the character in the input to be read next.
  150. * @property _cursor
  151. * @type int
  152. * @private
  153. */
  154. this._cursor = 0;
  155. }
  156. StringReader.prototype = {
  157. //restore constructor
  158. constructor: StringReader,
  159. //-------------------------------------------------------------------------
  160. // Position info
  161. //-------------------------------------------------------------------------
  162. /**
  163. * Returns the column of the character to be read next.
  164. * @return {int} The column of the character to be read next.
  165. * @method getCol
  166. */
  167. getCol: function(){
  168. return this._col;
  169. },
  170. /**
  171. * Returns the row of the character to be read next.
  172. * @return {int} The row of the character to be read next.
  173. * @method getLine
  174. */
  175. getLine: function(){
  176. return this._line ;
  177. },
  178. /**
  179. * Determines if you're at the end of the input.
  180. * @return {Boolean} True if there's no more input, false otherwise.
  181. * @method eof
  182. */
  183. eof: function(){
  184. return (this._cursor == this._input.length);
  185. },
  186. //-------------------------------------------------------------------------
  187. // Basic reading
  188. //-------------------------------------------------------------------------
  189. /**
  190. * Reads the next character without advancing the cursor.
  191. * @param {int} count How many characters to look ahead (default is 1).
  192. * @return {String} The next character or null if there is no next character.
  193. * @method peek
  194. */
  195. peek: function(count){
  196. var c = null;
  197. count = (typeof count == "undefined" ? 1 : count);
  198. //if we're not at the end of the input...
  199. if (this._cursor < this._input.length){
  200. //get character and increment cursor and column
  201. c = this._input.charAt(this._cursor + count - 1);
  202. }
  203. return c;
  204. },
  205. /**
  206. * Reads the next character from the input and adjusts the row and column
  207. * accordingly.
  208. * @return {String} The next character or null if there is no next character.
  209. * @method read
  210. */
  211. read: function(){
  212. var c = null;
  213. //if we're not at the end of the input...
  214. if (this._cursor < this._input.length){
  215. //if the last character was a newline, increment row count
  216. //and reset column count
  217. if (this._input.charAt(this._cursor) == "\n"){
  218. this._line++;
  219. this._col=1;
  220. } else {
  221. this._col++;
  222. }
  223. //get character and increment cursor and column
  224. c = this._input.charAt(this._cursor++);
  225. }
  226. return c;
  227. },
  228. //-------------------------------------------------------------------------
  229. // Misc
  230. //-------------------------------------------------------------------------
  231. /**
  232. * Saves the current location so it can be returned to later.
  233. * @method mark
  234. * @return {void}
  235. */
  236. mark: function(){
  237. this._bookmark = {
  238. cursor: this._cursor,
  239. line: this._line,
  240. col: this._col
  241. };
  242. },
  243. reset: function(){
  244. if (this._bookmark){
  245. this._cursor = this._bookmark.cursor;
  246. this._line = this._bookmark.line;
  247. this._col = this._bookmark.col;
  248. delete this._bookmark;
  249. }
  250. },
  251. //-------------------------------------------------------------------------
  252. // Advanced reading
  253. //-------------------------------------------------------------------------
  254. /**
  255. * Reads up to and including the given string. Throws an error if that
  256. * string is not found.
  257. * @param {String} pattern The string to read.
  258. * @return {String} The string when it is found.
  259. * @throws Error when the string pattern is not found.
  260. * @method readTo
  261. */
  262. readTo: function(pattern){
  263. var buffer = "",
  264. c;
  265. /*
  266. * First, buffer must be the same length as the pattern.
  267. * Then, buffer must end with the pattern or else reach the
  268. * end of the input.
  269. */
  270. while (buffer.length < pattern.length || buffer.lastIndexOf(pattern) != buffer.length - pattern.length){
  271. c = this.read();
  272. if (c){
  273. buffer += c;
  274. } else {
  275. throw new Error("Expected \"" + pattern + "\" at line " + this._line + ", col " + this._col + ".");
  276. }
  277. }
  278. return buffer;
  279. },
  280. /**
  281. * Reads characters while each character causes the given
  282. * filter function to return true. The function is passed
  283. * in each character and either returns true to continue
  284. * reading or false to stop.
  285. * @param {Function} filter The function to read on each character.
  286. * @return {String} The string made up of all characters that passed the
  287. * filter check.
  288. * @method readWhile
  289. */
  290. readWhile: function(filter){
  291. var buffer = "",
  292. c = this.read();
  293. while(c !== null && filter(c)){
  294. buffer += c;
  295. c = this.read();
  296. }
  297. return buffer;
  298. },
  299. /**
  300. * Reads characters that match either text or a regular expression and
  301. * returns those characters. If a match is found, the row and column
  302. * are adjusted; if no match is found, the reader's state is unchanged.
  303. * reading or false to stop.
  304. * @param {String|RegExp} matchter If a string, then the literal string
  305. * value is searched for. If a regular expression, then any string
  306. * matching the pattern is search for.
  307. * @return {String} The string made up of all characters that matched or
  308. * null if there was no match.
  309. * @method readMatch
  310. */
  311. readMatch: function(matcher){
  312. var source = this._input.substring(this._cursor),
  313. value = null;
  314. //if it's a string, just do a straight match
  315. if (typeof matcher == "string"){
  316. if (source.indexOf(matcher) === 0){
  317. value = this.readCount(matcher.length);
  318. }
  319. } else if (matcher instanceof RegExp){
  320. if (matcher.test(source)){
  321. value = this.readCount(RegExp.lastMatch.length);
  322. }
  323. }
  324. return value;
  325. },
  326. /**
  327. * Reads a given number of characters. If the end of the input is reached,
  328. * it reads only the remaining characters and does not throw an error.
  329. * @param {int} count The number of characters to read.
  330. * @return {String} The string made up the read characters.
  331. * @method readCount
  332. */
  333. readCount: function(count){
  334. var buffer = "";
  335. while(count--){
  336. buffer += this.read();
  337. }
  338. return buffer;
  339. }
  340. };
  341. /**
  342. * Type to use when a syntax error occurs.
  343. * @class SyntaxError
  344. * @namespace parserlib.util
  345. * @constructor
  346. * @param {String} message The error message.
  347. * @param {int} line The line at which the error occurred.
  348. * @param {int} col The column at which the error occurred.
  349. */
  350. function SyntaxError(message, line, col){
  351. /**
  352. * The column at which the error occurred.
  353. * @type int
  354. * @property col
  355. */
  356. this.col = col;
  357. /**
  358. * The line at which the error occurred.
  359. * @type int
  360. * @property line
  361. */
  362. this.line = line;
  363. /**
  364. * The text representation of the unit.
  365. * @type String
  366. * @property text
  367. */
  368. this.message = message;
  369. }
  370. //inherit from Error
  371. SyntaxError.prototype = new Error();
  372. /**
  373. * Base type to represent a single syntactic unit.
  374. * @class SyntaxUnit
  375. * @namespace parserlib.util
  376. * @constructor
  377. * @param {String} text The text of the unit.
  378. * @param {int} line The line of text on which the unit resides.
  379. * @param {int} col The column of text on which the unit resides.
  380. */
  381. function SyntaxUnit(text, line, col, type){
  382. /**
  383. * The column of text on which the unit resides.
  384. * @type int
  385. * @property col
  386. */
  387. this.col = col;
  388. /**
  389. * The line of text on which the unit resides.
  390. * @type int
  391. * @property line
  392. */
  393. this.line = line;
  394. /**
  395. * The text representation of the unit.
  396. * @type String
  397. * @property text
  398. */
  399. this.text = text;
  400. /**
  401. * The type of syntax unit.
  402. * @type int
  403. * @property type
  404. */
  405. this.type = type;
  406. }
  407. /**
  408. * Create a new syntax unit based solely on the given token.
  409. * Convenience method for creating a new syntax unit when
  410. * it represents a single token instead of multiple.
  411. * @param {Object} token The token object to represent.
  412. * @return {parserlib.util.SyntaxUnit} The object representing the token.
  413. * @static
  414. * @method fromToken
  415. */
  416. SyntaxUnit.fromToken = function(token){
  417. return new SyntaxUnit(token.value, token.startLine, token.startCol);
  418. };
  419. SyntaxUnit.prototype = {
  420. //restore constructor
  421. constructor: SyntaxUnit,
  422. /**
  423. * Returns the text representation of the unit.
  424. * @return {String} The text representation of the unit.
  425. * @method valueOf
  426. */
  427. valueOf: function(){
  428. return this.text;
  429. },
  430. /**
  431. * Returns the text representation of the unit.
  432. * @return {String} The text representation of the unit.
  433. * @method toString
  434. */
  435. toString: function(){
  436. return this.text;
  437. }
  438. };
  439. /*global StringReader, SyntaxError*/
  440. /**
  441. * Generic TokenStream providing base functionality.
  442. * @class TokenStreamBase
  443. * @namespace parserlib.util
  444. * @constructor
  445. * @param {String|StringReader} input The text to tokenize or a reader from
  446. * which to read the input.
  447. */
  448. function TokenStreamBase(input, tokenData){
  449. /**
  450. * The string reader for easy access to the text.
  451. * @type StringReader
  452. * @property _reader
  453. * @private
  454. */
  455. this._reader = input ? new StringReader(input.toString()) : null;
  456. /**
  457. * Token object for the last consumed token.
  458. * @type Token
  459. * @property _token
  460. * @private
  461. */
  462. this._token = null;
  463. /**
  464. * The array of token information.
  465. * @type Array
  466. * @property _tokenData
  467. * @private
  468. */
  469. this._tokenData = tokenData;
  470. /**
  471. * Lookahead token buffer.
  472. * @type Array
  473. * @property _lt
  474. * @private
  475. */
  476. this._lt = [];
  477. /**
  478. * Lookahead token buffer index.
  479. * @type int
  480. * @property _ltIndex
  481. * @private
  482. */
  483. this._ltIndex = 0;
  484. this._ltIndexCache = [];
  485. }
  486. /**
  487. * Accepts an array of token information and outputs
  488. * an array of token data containing key-value mappings
  489. * and matching functions that the TokenStream needs.
  490. * @param {Array} tokens An array of token descriptors.
  491. * @return {Array} An array of processed token data.
  492. * @method createTokenData
  493. * @static
  494. */
  495. TokenStreamBase.createTokenData = function(tokens){
  496. var nameMap = [],
  497. typeMap = {},
  498. tokenData = tokens.concat([]),
  499. i = 0,
  500. len = tokenData.length+1;
  501. tokenData.UNKNOWN = -1;
  502. tokenData.unshift({name:"EOF"});
  503. for (; i < len; i++){
  504. nameMap.push(tokenData[i].name);
  505. tokenData[tokenData[i].name] = i;
  506. if (tokenData[i].text){
  507. typeMap[tokenData[i].text] = i;
  508. }
  509. }
  510. tokenData.name = function(tt){
  511. return nameMap[tt];
  512. };
  513. tokenData.type = function(c){
  514. return typeMap[c];
  515. };
  516. return tokenData;
  517. };
  518. TokenStreamBase.prototype = {
  519. //restore constructor
  520. constructor: TokenStreamBase,
  521. //-------------------------------------------------------------------------
  522. // Matching methods
  523. //-------------------------------------------------------------------------
  524. /**
  525. * Determines if the next token matches the given token type.
  526. * If so, that token is consumed; if not, the token is placed
  527. * back onto the token stream. You can pass in any number of
  528. * token types and this will return true if any of the token
  529. * types is found.
  530. * @param {int|int[]} tokenTypes Either a single token type or an array of
  531. * token types that the next token might be. If an array is passed,
  532. * it's assumed that the token can be any of these.
  533. * @param {variant} channel (Optional) The channel to read from. If not
  534. * provided, reads from the default (unnamed) channel.
  535. * @return {Boolean} True if the token type matches, false if not.
  536. * @method match
  537. */
  538. match: function(tokenTypes, channel){
  539. //always convert to an array, makes things easier
  540. if (!(tokenTypes instanceof Array)){
  541. tokenTypes = [tokenTypes];
  542. }
  543. var tt = this.get(channel),
  544. i = 0,
  545. len = tokenTypes.length;
  546. while(i < len){
  547. if (tt == tokenTypes[i++]){
  548. return true;
  549. }
  550. }
  551. //no match found, put the token back
  552. this.unget();
  553. return false;
  554. },
  555. /**
  556. * Determines if the next token matches the given token type.
  557. * If so, that token is consumed; if not, an error is thrown.
  558. * @param {int|int[]} tokenTypes Either a single token type or an array of
  559. * token types that the next token should be. If an array is passed,
  560. * it's assumed that the token must be one of these.
  561. * @param {variant} channel (Optional) The channel to read from. If not
  562. * provided, reads from the default (unnamed) channel.
  563. * @return {void}
  564. * @method mustMatch
  565. */
  566. mustMatch: function(tokenTypes, channel){
  567. var token;
  568. //always convert to an array, makes things easier
  569. if (!(tokenTypes instanceof Array)){
  570. tokenTypes = [tokenTypes];
  571. }
  572. if (!this.match.apply(this, arguments)){
  573. token = this.LT(1);
  574. throw new SyntaxError("Expected " + this._tokenData[tokenTypes[0]].name +
  575. " at line " + token.startLine + ", col " + token.startCol + ".", token.startLine, token.startCol);
  576. }
  577. },
  578. //-------------------------------------------------------------------------
  579. // Consuming methods
  580. //-------------------------------------------------------------------------
  581. /**
  582. * Keeps reading from the token stream until either one of the specified
  583. * token types is found or until the end of the input is reached.
  584. * @param {int|int[]} tokenTypes Either a single token type or an array of
  585. * token types that the next token should be. If an array is passed,
  586. * it's assumed that the token must be one of these.
  587. * @param {variant} channel (Optional) The channel to read from. If not
  588. * provided, reads from the default (unnamed) channel.
  589. * @return {void}
  590. * @method advance
  591. */
  592. advance: function(tokenTypes, channel){
  593. while(this.LA(0) !== 0 && !this.match(tokenTypes, channel)){
  594. this.get();
  595. }
  596. return this.LA(0);
  597. },
  598. /**
  599. * Consumes the next token from the token stream.
  600. * @return {int} The token type of the token that was just consumed.
  601. * @method get
  602. */
  603. get: function(channel){
  604. var tokenInfo = this._tokenData,
  605. reader = this._reader,
  606. value,
  607. i =0,
  608. len = tokenInfo.length,
  609. found = false,
  610. token,
  611. info;
  612. //check the lookahead buffer first
  613. if (this._lt.length && this._ltIndex >= 0 && this._ltIndex < this._lt.length){
  614. i++;
  615. this._token = this._lt[this._ltIndex++];
  616. info = tokenInfo[this._token.type];
  617. //obey channels logic
  618. while((info.channel !== undefined && channel !== info.channel) &&
  619. this._ltIndex < this._lt.length){
  620. this._token = this._lt[this._ltIndex++];
  621. info = tokenInfo[this._token.type];
  622. i++;
  623. }
  624. //here be dragons
  625. if ((info.channel === undefined || channel === info.channel) &&
  626. this._ltIndex <= this._lt.length){
  627. this._ltIndexCache.push(i);
  628. return this._token.type;
  629. }
  630. }
  631. //call token retriever method
  632. token = this._getToken();
  633. //if it should be hidden, don't save a token
  634. if (token.type > -1 && !tokenInfo[token.type].hide){
  635. //apply token channel
  636. token.channel = tokenInfo[token.type].channel;
  637. //save for later
  638. this._token = token;
  639. this._lt.push(token);
  640. //save space that will be moved (must be done before array is truncated)
  641. this._ltIndexCache.push(this._lt.length - this._ltIndex + i);
  642. //keep the buffer under 5 items
  643. if (this._lt.length > 5){
  644. this._lt.shift();
  645. }
  646. //also keep the shift buffer under 5 items
  647. if (this._ltIndexCache.length > 5){
  648. this._ltIndexCache.shift();
  649. }
  650. //update lookahead index
  651. this._ltIndex = this._lt.length;
  652. }
  653. /*
  654. * Skip to the next token if:
  655. * 1. The token type is marked as hidden.
  656. * 2. The token type has a channel specified and it isn't the current channel.
  657. */
  658. info = tokenInfo[token.type];
  659. if (info &&
  660. (info.hide ||
  661. (info.channel !== undefined && channel !== info.channel))){
  662. return this.get(channel);
  663. } else {
  664. //return just the type
  665. return token.type;
  666. }
  667. },
  668. /**
  669. * Looks ahead a certain number of tokens and returns the token type at
  670. * that position. This will throw an error if you lookahead past the
  671. * end of input, past the size of the lookahead buffer, or back past
  672. * the first token in the lookahead buffer.
  673. * @param {int} The index of the token type to retrieve. 0 for the
  674. * current token, 1 for the next, -1 for the previous, etc.
  675. * @return {int} The token type of the token in the given position.
  676. * @method LA
  677. */
  678. LA: function(index){
  679. var total = index,
  680. tt;
  681. if (index > 0){
  682. //TODO: Store 5 somewhere
  683. if (index > 5){
  684. throw new Error("Too much lookahead.");
  685. }
  686. //get all those tokens
  687. while(total){
  688. tt = this.get();
  689. total--;
  690. }
  691. //unget all those tokens
  692. while(total < index){
  693. this.unget();
  694. total++;
  695. }
  696. } else if (index < 0){
  697. if(this._lt[this._ltIndex+index]){
  698. tt = this._lt[this._ltIndex+index].type;
  699. } else {
  700. throw new Error("Too much lookbehind.");
  701. }
  702. } else {
  703. tt = this._token.type;
  704. }
  705. return tt;
  706. },
  707. /**
  708. * Looks ahead a certain number of tokens and returns the token at
  709. * that position. This will throw an error if you lookahead past the
  710. * end of input, past the size of the lookahead buffer, or back past
  711. * the first token in the lookahead buffer.
  712. * @param {int} The index of the token type to retrieve. 0 for the
  713. * current token, 1 for the next, -1 for the previous, etc.
  714. * @return {Object} The token of the token in the given position.
  715. * @method LA
  716. */
  717. LT: function(index){
  718. //lookahead first to prime the token buffer
  719. this.LA(index);
  720. //now find the token, subtract one because _ltIndex is already at the next index
  721. return this._lt[this._ltIndex+index-1];
  722. },
  723. /**
  724. * Returns the token type for the next token in the stream without
  725. * consuming it.
  726. * @return {int} The token type of the next token in the stream.
  727. * @method peek
  728. */
  729. peek: function(){
  730. return this.LA(1);
  731. },
  732. /**
  733. * Returns the actual token object for the last consumed token.
  734. * @return {Token} The token object for the last consumed token.
  735. * @method token
  736. */
  737. token: function(){
  738. return this._token;
  739. },
  740. /**
  741. * Returns the name of the token for the given token type.
  742. * @param {int} tokenType The type of token to get the name of.
  743. * @return {String} The name of the token or "UNKNOWN_TOKEN" for any
  744. * invalid token type.
  745. * @method tokenName
  746. */
  747. tokenName: function(tokenType){
  748. if (tokenType < 0 || tokenType > this._tokenData.length){
  749. return "UNKNOWN_TOKEN";
  750. } else {
  751. return this._tokenData[tokenType].name;
  752. }
  753. },
  754. /**
  755. * Returns the token type value for the given token name.
  756. * @param {String} tokenName The name of the token whose value should be returned.
  757. * @return {int} The token type value for the given token name or -1
  758. * for an unknown token.
  759. * @method tokenName
  760. */
  761. tokenType: function(tokenName){
  762. return this._tokenData[tokenName] || -1;
  763. },
  764. /**
  765. * Returns the last consumed token to the token stream.
  766. * @method unget
  767. */
  768. unget: function(){
  769. //if (this._ltIndex > -1){
  770. if (this._ltIndexCache.length){
  771. this._ltIndex -= this._ltIndexCache.pop();//--;
  772. this._token = this._lt[this._ltIndex - 1];
  773. } else {
  774. throw new Error("Too much lookahead.");
  775. }
  776. }
  777. };
  778. parserlib.util = {
  779. StringReader: StringReader,
  780. SyntaxError : SyntaxError,
  781. SyntaxUnit : SyntaxUnit,
  782. EventTarget : EventTarget,
  783. TokenStreamBase : TokenStreamBase
  784. };
  785. })();
  786. /*
  787. Parser-Lib
  788. Copyright (c) 2009-2011 Nicholas C. Zakas. All rights reserved.
  789. Permission is hereby granted, free of charge, to any person obtaining a copy
  790. of this software and associated documentation files (the "Software"), to deal
  791. in the Software without restriction, including without limitation the rights
  792. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  793. copies of the Software, and to permit persons to whom the Software is
  794. furnished to do so, subject to the following conditions:
  795. The above copyright notice and this permission notice shall be included in
  796. all copies or substantial portions of the Software.
  797. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  798. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  799. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  800. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  801. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  802. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  803. THE SOFTWARE.
  804. */
  805. /* Version v0.2.5, Build time: 7-May-2014 03:37:38 */
  806. (function(){
  807. var EventTarget = parserlib.util.EventTarget,
  808. TokenStreamBase = parserlib.util.TokenStreamBase,
  809. StringReader = parserlib.util.StringReader,
  810. SyntaxError = parserlib.util.SyntaxError,
  811. SyntaxUnit = parserlib.util.SyntaxUnit;
  812. var Colors = {
  813. aliceblue :"#f0f8ff",
  814. antiquewhite :"#faebd7",
  815. aqua :"#00ffff",
  816. aquamarine :"#7fffd4",
  817. azure :"#f0ffff",
  818. beige :"#f5f5dc",
  819. bisque :"#ffe4c4",
  820. black :"#000000",
  821. blanchedalmond :"#ffebcd",
  822. blue :"#0000ff",
  823. blueviolet :"#8a2be2",
  824. brown :"#a52a2a",
  825. burlywood :"#deb887",
  826. cadetblue :"#5f9ea0",
  827. chartreuse :"#7fff00",
  828. chocolate :"#d2691e",
  829. coral :"#ff7f50",
  830. cornflowerblue :"#6495ed",
  831. cornsilk :"#fff8dc",
  832. crimson :"#dc143c",
  833. cyan :"#00ffff",
  834. darkblue :"#00008b",
  835. darkcyan :"#008b8b",
  836. darkgoldenrod :"#b8860b",
  837. darkgray :"#a9a9a9",
  838. darkgrey :"#a9a9a9",
  839. darkgreen :"#006400",
  840. darkkhaki :"#bdb76b",
  841. darkmagenta :"#8b008b",
  842. darkolivegreen :"#556b2f",
  843. darkorange :"#ff8c00",
  844. darkorchid :"#9932cc",
  845. darkred :"#8b0000",
  846. darksalmon :"#e9967a",
  847. darkseagreen :"#8fbc8f",
  848. darkslateblue :"#483d8b",
  849. darkslategray :"#2f4f4f",
  850. darkslategrey :"#2f4f4f",
  851. darkturquoise :"#00ced1",
  852. darkviolet :"#9400d3",
  853. deeppink :"#ff1493",
  854. deepskyblue :"#00bfff",
  855. dimgray :"#696969",
  856. dimgrey :"#696969",
  857. dodgerblue :"#1e90ff",
  858. firebrick :"#b22222",
  859. floralwhite :"#fffaf0",
  860. forestgreen :"#228b22",
  861. fuchsia :"#ff00ff",
  862. gainsboro :"#dcdcdc",
  863. ghostwhite :"#f8f8ff",
  864. gold :"#ffd700",
  865. goldenrod :"#daa520",
  866. gray :"#808080",
  867. grey :"#808080",
  868. green :"#008000",
  869. greenyellow :"#adff2f",
  870. honeydew :"#f0fff0",
  871. hotpink :"#ff69b4",
  872. indianred :"#cd5c5c",
  873. indigo :"#4b0082",
  874. ivory :"#fffff0",
  875. khaki :"#f0e68c",
  876. lavender :"#e6e6fa",
  877. lavenderblush :"#fff0f5",
  878. lawngreen :"#7cfc00",
  879. lemonchiffon :"#fffacd",
  880. lightblue :"#add8e6",
  881. lightcoral :"#f08080",
  882. lightcyan :"#e0ffff",
  883. lightgoldenrodyellow :"#fafad2",
  884. lightgray :"#d3d3d3",
  885. lightgrey :"#d3d3d3",
  886. lightgreen :"#90ee90",
  887. lightpink :"#ffb6c1",
  888. lightsalmon :"#ffa07a",
  889. lightseagreen :"#20b2aa",
  890. lightskyblue :"#87cefa",
  891. lightslategray :"#778899",
  892. lightslategrey :"#778899",
  893. lightsteelblue :"#b0c4de",
  894. lightyellow :"#ffffe0",
  895. lime :"#00ff00",
  896. limegreen :"#32cd32",
  897. linen :"#faf0e6",
  898. magenta :"#ff00ff",
  899. maroon :"#800000",
  900. mediumaquamarine:"#66cdaa",
  901. mediumblue :"#0000cd",
  902. mediumorchid :"#ba55d3",
  903. mediumpurple :"#9370d8",
  904. mediumseagreen :"#3cb371",
  905. mediumslateblue :"#7b68ee",
  906. mediumspringgreen :"#00fa9a",
  907. mediumturquoise :"#48d1cc",
  908. mediumvioletred :"#c71585",
  909. midnightblue :"#191970",
  910. mintcream :"#f5fffa",
  911. mistyrose :"#ffe4e1",
  912. moccasin :"#ffe4b5",
  913. navajowhite :"#ffdead",
  914. navy :"#000080",
  915. oldlace :"#fdf5e6",
  916. olive :"#808000",
  917. olivedrab :"#6b8e23",
  918. orange :"#ffa500",
  919. orangered :"#ff4500",
  920. orchid :"#da70d6",
  921. palegoldenrod :"#eee8aa",
  922. palegreen :"#98fb98",
  923. paleturquoise :"#afeeee",
  924. palevioletred :"#d87093",
  925. papayawhip :"#ffefd5",
  926. peachpuff :"#ffdab9",
  927. peru :"#cd853f",
  928. pink :"#ffc0cb",
  929. plum :"#dda0dd",
  930. powderblue :"#b0e0e6",
  931. purple :"#800080",
  932. red :"#ff0000",
  933. rosybrown :"#bc8f8f",
  934. royalblue :"#4169e1",
  935. saddlebrown :"#8b4513",
  936. salmon :"#fa8072",
  937. sandybrown :"#f4a460",
  938. seagreen :"#2e8b57",
  939. seashell :"#fff5ee",
  940. sienna :"#a0522d",
  941. silver :"#c0c0c0",
  942. skyblue :"#87ceeb",
  943. slateblue :"#6a5acd",
  944. slategray :"#708090",
  945. slategrey :"#708090",
  946. snow :"#fffafa",
  947. springgreen :"#00ff7f",
  948. steelblue :"#4682b4",
  949. tan :"#d2b48c",
  950. teal :"#008080",
  951. thistle :"#d8bfd8",
  952. tomato :"#ff6347",
  953. turquoise :"#40e0d0",
  954. violet :"#ee82ee",
  955. wheat :"#f5deb3",
  956. white :"#ffffff",
  957. whitesmoke :"#f5f5f5",
  958. yellow :"#ffff00",
  959. yellowgreen :"#9acd32",
  960. //CSS2 system colors http://www.w3.org/TR/css3-color/#css2-system
  961. activeBorder :"Active window border.",
  962. activecaption :"Active window caption.",
  963. appworkspace :"Background color of multiple document interface.",
  964. background :"Desktop background.",
  965. buttonface :"The face background color for 3-D elements that appear 3-D due to one layer of surrounding border.",
  966. 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.",
  967. 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.",
  968. buttontext :"Text on push buttons.",
  969. captiontext :"Text in caption, size box, and scrollbar arrow box.",
  970. graytext :"Grayed (disabled) text. This color is set to #000 if the current display driver does not support a solid gray color.",
  971. greytext :"Greyed (disabled) text. This color is set to #000 if the current display driver does not support a solid grey color.",
  972. highlight :"Item(s) selected in a control.",
  973. highlighttext :"Text of item(s) selected in a control.",
  974. inactiveborder :"Inactive window border.",
  975. inactivecaption :"Inactive window caption.",
  976. inactivecaptiontext :"Color of text in an inactive caption.",
  977. infobackground :"Background color for tooltip controls.",
  978. infotext :"Text color for tooltip controls.",
  979. menu :"Menu background.",
  980. menutext :"Text in menus.",
  981. scrollbar :"Scroll bar gray area.",
  982. 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.",
  983. threedface :"The face background color for 3-D elements that appear 3-D due to two concentric layers of surrounding border.",
  984. 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.",
  985. 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.",
  986. 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.",
  987. window :"Window background.",
  988. windowframe :"Window frame.",
  989. windowtext :"Text in windows."
  990. };
  991. /*global SyntaxUnit, Parser*/
  992. /**
  993. * Represents a selector combinator (whitespace, +, >).
  994. * @namespace parserlib.css
  995. * @class Combinator
  996. * @extends parserlib.util.SyntaxUnit
  997. * @constructor
  998. * @param {String} text The text representation of the unit.
  999. * @param {int} line The line of text on which the unit resides.
  1000. * @param {int} col The column of text on which the unit resides.
  1001. */
  1002. function Combinator(text, line, col){
  1003. SyntaxUnit.call(this, text, line, col, Parser.COMBINATOR_TYPE);
  1004. /**
  1005. * The type of modifier.
  1006. * @type String
  1007. * @property type
  1008. */
  1009. this.type = "unknown";
  1010. //pretty simple
  1011. if (/^\s+$/.test(text)){
  1012. this.type = "descendant";
  1013. } else if (text == ">"){
  1014. this.type = "child";
  1015. } else if (text == "+"){
  1016. this.type = "adjacent-sibling";
  1017. } else if (text == "~"){
  1018. this.type = "sibling";
  1019. }
  1020. }
  1021. Combinator.prototype = new SyntaxUnit();
  1022. Combinator.prototype.constructor = Combinator;
  1023. /*global SyntaxUnit, Parser*/
  1024. /**
  1025. * Represents a media feature, such as max-width:500.
  1026. * @namespace parserlib.css
  1027. * @class MediaFeature
  1028. * @extends parserlib.util.SyntaxUnit
  1029. * @constructor
  1030. * @param {SyntaxUnit} name The name of the feature.
  1031. * @param {SyntaxUnit} value The value of the feature or null if none.
  1032. */
  1033. function MediaFeature(name, value){
  1034. SyntaxUnit.call(this, "(" + name + (value !== null ? ":" + value : "") + ")", name.startLine, name.startCol, Parser.MEDIA_FEATURE_TYPE);
  1035. /**
  1036. * The name of the media feature
  1037. * @type String
  1038. * @property name
  1039. */
  1040. this.name = name;
  1041. /**
  1042. * The value for the feature or null if there is none.
  1043. * @type SyntaxUnit
  1044. * @property value
  1045. */
  1046. this.value = value;
  1047. }
  1048. MediaFeature.prototype = new SyntaxUnit();
  1049. MediaFeature.prototype.constructor = MediaFeature;
  1050. /*global SyntaxUnit, Parser*/
  1051. /**
  1052. * Represents an individual media query.
  1053. * @namespace parserlib.css
  1054. * @class MediaQuery
  1055. * @extends parserlib.util.SyntaxUnit
  1056. * @constructor
  1057. * @param {String} modifier The modifier "not" or "only" (or null).
  1058. * @param {String} mediaType The type of media (i.e., "print").
  1059. * @param {Array} parts Array of selectors parts making up this selector.
  1060. * @param {int} line The line of text on which the unit resides.
  1061. * @param {int} col The column of text on which the unit resides.
  1062. */
  1063. function MediaQuery(modifier, mediaType, features, line, col){
  1064. SyntaxUnit.call(this, (modifier ? modifier + " ": "") + (mediaType ? mediaType : "") + (mediaType && features.length > 0 ? " and " : "") + features.join(" and "), line, col, Parser.MEDIA_QUERY_TYPE);
  1065. /**
  1066. * The media modifier ("not" or "only")
  1067. * @type String
  1068. * @property modifier
  1069. */
  1070. this.modifier = modifier;
  1071. /**
  1072. * The mediaType (i.e., "print")
  1073. * @type String
  1074. * @property mediaType
  1075. */
  1076. this.mediaType = mediaType;
  1077. /**
  1078. * The parts that make up the selector.
  1079. * @type Array
  1080. * @property features
  1081. */
  1082. this.features = features;
  1083. }
  1084. MediaQuery.prototype = new SyntaxUnit();
  1085. MediaQuery.prototype.constructor = MediaQuery;
  1086. /*global Tokens, TokenStream, SyntaxError, Properties, Validation, ValidationError, SyntaxUnit,
  1087. PropertyValue, PropertyValuePart, SelectorPart, SelectorSubPart, Selector,
  1088. PropertyName, Combinator, MediaFeature, MediaQuery, EventTarget */
  1089. /**
  1090. * A CSS3 parser.
  1091. * @namespace parserlib.css
  1092. * @class Parser
  1093. * @constructor
  1094. * @param {Object} options (Optional) Various options for the parser:
  1095. * starHack (true|false) to allow IE6 star hack as valid,
  1096. * underscoreHack (true|false) to interpret leading underscores
  1097. * as IE6-7 targeting for known properties, ieFilters (true|false)
  1098. * to indicate that IE < 8 filters should be accepted and not throw
  1099. * syntax errors.
  1100. */
  1101. function Parser(options){
  1102. //inherit event functionality
  1103. EventTarget.call(this);
  1104. this.options = options || {};
  1105. this._tokenStream = null;
  1106. }
  1107. //Static constants
  1108. Parser.DEFAULT_TYPE = 0;
  1109. Parser.COMBINATOR_TYPE = 1;
  1110. Parser.MEDIA_FEATURE_TYPE = 2;
  1111. Parser.MEDIA_QUERY_TYPE = 3;
  1112. Parser.PROPERTY_NAME_TYPE = 4;
  1113. Parser.PROPERTY_VALUE_TYPE = 5;
  1114. Parser.PROPERTY_VALUE_PART_TYPE = 6;
  1115. Parser.SELECTOR_TYPE = 7;
  1116. Parser.SELECTOR_PART_TYPE = 8;
  1117. Parser.SELECTOR_SUB_PART_TYPE = 9;
  1118. Parser.prototype = function(){
  1119. var proto = new EventTarget(), //new prototype
  1120. prop,
  1121. additions = {
  1122. //restore constructor
  1123. constructor: Parser,
  1124. //instance constants - yuck
  1125. DEFAULT_TYPE : 0,
  1126. COMBINATOR_TYPE : 1,
  1127. MEDIA_FEATURE_TYPE : 2,
  1128. MEDIA_QUERY_TYPE : 3,
  1129. PROPERTY_NAME_TYPE : 4,
  1130. PROPERTY_VALUE_TYPE : 5,
  1131. PROPERTY_VALUE_PART_TYPE : 6,
  1132. SELECTOR_TYPE : 7,
  1133. SELECTOR_PART_TYPE : 8,
  1134. SELECTOR_SUB_PART_TYPE : 9,
  1135. //-----------------------------------------------------------------
  1136. // Grammar
  1137. //-----------------------------------------------------------------
  1138. _stylesheet: function(){
  1139. /*
  1140. * stylesheet
  1141. * : [ CHARSET_SYM S* STRING S* ';' ]?
  1142. * [S|CDO|CDC]* [ import [S|CDO|CDC]* ]*
  1143. * [ namespace [S|CDO|CDC]* ]*
  1144. * [ [ ruleset | media | page | font_face | keyframes ] [S|CDO|CDC]* ]*
  1145. * ;
  1146. */
  1147. var tokenStream = this._tokenStream,
  1148. charset = null,
  1149. count,
  1150. token,
  1151. tt;
  1152. this.fire("startstylesheet");
  1153. //try to read character set
  1154. this._charset();
  1155. this._skipCruft();
  1156. //try to read imports - may be more than one
  1157. while (tokenStream.peek() == Tokens.IMPORT_SYM){
  1158. this._import();
  1159. this._skipCruft();
  1160. }
  1161. //try to read namespaces - may be more than one
  1162. while (tokenStream.peek() == Tokens.NAMESPACE_SYM){
  1163. this._namespace();
  1164. this._skipCruft();
  1165. }
  1166. //get the next token
  1167. tt = tokenStream.peek();
  1168. //try to read the rest
  1169. while(tt > Tokens.EOF){
  1170. try {
  1171. switch(tt){
  1172. case Tokens.MEDIA_SYM:
  1173. this._media();
  1174. this._skipCruft();
  1175. break;
  1176. case Tokens.PAGE_SYM:
  1177. this._page();
  1178. this._skipCruft();
  1179. break;
  1180. case Tokens.FONT_FACE_SYM:
  1181. this._font_face();
  1182. this._skipCruft();
  1183. break;
  1184. case Tokens.KEYFRAMES_SYM:
  1185. this._keyframes();
  1186. this._skipCruft();
  1187. break;
  1188. case Tokens.VIEWPORT_SYM:
  1189. this._viewport();
  1190. this._skipCruft();
  1191. break;
  1192. case Tokens.UNKNOWN_SYM: //unknown @ rule
  1193. tokenStream.get();
  1194. if (!this.options.strict){
  1195. //fire error event
  1196. this.fire({
  1197. type: "error",
  1198. error: null,
  1199. message: "Unknown @ rule: " + tokenStream.LT(0).value + ".",
  1200. line: tokenStream.LT(0).startLine,
  1201. col: tokenStream.LT(0).startCol
  1202. });
  1203. //skip braces
  1204. count=0;
  1205. while (tokenStream.advance([Tokens.LBRACE, Tokens.RBRACE]) == Tokens.LBRACE){
  1206. count++; //keep track of nesting depth
  1207. }
  1208. while(count){
  1209. tokenStream.advance([Tokens.RBRACE]);
  1210. count--;
  1211. }
  1212. } else {
  1213. //not a syntax error, rethrow it
  1214. throw new SyntaxError("Unknown @ rule.", tokenStream.LT(0).startLine, tokenStream.LT(0).startCol);
  1215. }
  1216. break;
  1217. case Tokens.S:
  1218. this._readWhitespace();
  1219. break;
  1220. default:
  1221. if(!this._ruleset()){
  1222. //error handling for known issues
  1223. switch(tt){
  1224. case Tokens.CHARSET_SYM:
  1225. token = tokenStream.LT(1);
  1226. this._charset(false);
  1227. throw new SyntaxError("@charset not allowed here.", token.startLine, token.startCol);
  1228. case Tokens.IMPORT_SYM:
  1229. token = tokenStream.LT(1);
  1230. this._import(false);
  1231. throw new SyntaxError("@import not allowed here.", token.startLine, token.startCol);
  1232. case Tokens.NAMESPACE_SYM:
  1233. token = tokenStream.LT(1);
  1234. this._namespace(false);
  1235. throw new SyntaxError("@namespace not allowed here.", token.startLine, token.startCol);
  1236. default:
  1237. tokenStream.get(); //get the last token
  1238. this._unexpectedToken(tokenStream.token());
  1239. }
  1240. }
  1241. }
  1242. } catch(ex) {
  1243. if (ex instanceof SyntaxError && !this.options.strict){
  1244. this.fire({
  1245. type: "error",
  1246. error: ex,
  1247. message: ex.message,
  1248. line: ex.line,
  1249. col: ex.col
  1250. });
  1251. } else {
  1252. throw ex;
  1253. }
  1254. }
  1255. tt = tokenStream.peek();
  1256. }
  1257. if (tt != Tokens.EOF){
  1258. this._unexpectedToken(tokenStream.token());
  1259. }
  1260. this.fire("endstylesheet");
  1261. },
  1262. _charset: function(emit){
  1263. var tokenStream = this._tokenStream,
  1264. charset,
  1265. token,
  1266. line,
  1267. col;
  1268. if (tokenStream.match(Tokens.CHARSET_SYM)){
  1269. line = tokenStream.token().startLine;
  1270. col = tokenStream.token().startCol;
  1271. this._readWhitespace();
  1272. tokenStream.mustMatch(Tokens.STRING);
  1273. token = tokenStream.token();
  1274. charset = token.value;
  1275. this._readWhitespace();
  1276. tokenStream.mustMatch(Tokens.SEMICOLON);
  1277. if (emit !== false){
  1278. this.fire({
  1279. type: "charset",
  1280. charset:charset,
  1281. line: line,
  1282. col: col
  1283. });
  1284. }
  1285. }
  1286. },
  1287. _import: function(emit){
  1288. /*
  1289. * import
  1290. * : IMPORT_SYM S*
  1291. * [STRING|URI] S* media_query_list? ';' S*
  1292. */
  1293. var tokenStream = this._tokenStream,
  1294. tt,
  1295. uri,
  1296. importToken,
  1297. mediaList = [];
  1298. //read import symbol
  1299. tokenStream.mustMatch(Tokens.IMPORT_SYM);
  1300. importToken = tokenStream.token();
  1301. this._readWhitespace();
  1302. tokenStream.mustMatch([Tokens.STRING, Tokens.URI]);
  1303. //grab the URI value
  1304. uri = tokenStream.token().value.replace(/^(?:url\()?["']?([^"']+?)["']?\)?$/, "$1");
  1305. this._readWhitespace();
  1306. mediaList = this._media_query_list();
  1307. //must end with a semicolon
  1308. tokenStream.mustMatch(Tokens.SEMICOLON);
  1309. this._readWhitespace();
  1310. if (emit !== false){
  1311. this.fire({
  1312. type: "import",
  1313. uri: uri,
  1314. media: mediaList,
  1315. line: importToken.startLine,
  1316. col: importToken.startCol
  1317. });

Large files files are truncated, but you can click here to view the full file