123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- 'use strict';
- var Mixin = require('../../utils/mixin'),
- Tokenizer = require('../../tokenizer'),
- PositionTrackingPreprocessorMixin = require('../position_tracking/preprocessor_mixin'),
- inherits = require('util').inherits;
- var LocationInfoTokenizerMixin = module.exports = function (tokenizer) {
- Mixin.call(this, tokenizer);
- this.tokenizer = tokenizer;
- this.posTracker = new PositionTrackingPreprocessorMixin(tokenizer.preprocessor);
- this.currentAttrLocation = null;
- this.currentTokenLocation = null;
- };
- inherits(LocationInfoTokenizerMixin, Mixin);
- LocationInfoTokenizerMixin.prototype._getCurrentLocation = function () {
- return {
- line: this.posTracker.line,
- col: this.posTracker.col,
- startOffset: this.posTracker.offset,
- endOffset: -1
- };
- };
- LocationInfoTokenizerMixin.prototype._attachCurrentAttrLocationInfo = function () {
- this.currentAttrLocation.endOffset = this.posTracker.offset;
- var currentToken = this.tokenizer.currentToken,
- currentAttr = this.tokenizer.currentAttr;
- if (!currentToken.location.attrs)
- currentToken.location.attrs = Object.create(null);
- currentToken.location.attrs[currentAttr.name] = this.currentAttrLocation;
- };
- LocationInfoTokenizerMixin.prototype._getOverriddenMethods = function (mxn, orig) {
- var methods = {
- _createStartTagToken: function () {
- orig._createStartTagToken.call(this);
- this.currentToken.location = mxn.currentTokenLocation;
- },
- _createEndTagToken: function () {
- orig._createEndTagToken.call(this);
- this.currentToken.location = mxn.currentTokenLocation;
- },
- _createCommentToken: function () {
- orig._createCommentToken.call(this);
- this.currentToken.location = mxn.currentTokenLocation;
- },
- _createDoctypeToken: function (initialName) {
- orig._createDoctypeToken.call(this, initialName);
- this.currentToken.location = mxn.currentTokenLocation;
- },
- _createCharacterToken: function (type, ch) {
- orig._createCharacterToken.call(this, type, ch);
- this.currentCharacterToken.location = mxn.currentTokenLocation;
- },
- _createAttr: function (attrNameFirstCh) {
- orig._createAttr.call(this, attrNameFirstCh);
- mxn.currentAttrLocation = mxn._getCurrentLocation();
- },
- _leaveAttrName: function (toState) {
- orig._leaveAttrName.call(this, toState);
- mxn._attachCurrentAttrLocationInfo();
- },
- _leaveAttrValue: function (toState) {
- orig._leaveAttrValue.call(this, toState);
- mxn._attachCurrentAttrLocationInfo();
- },
- _emitCurrentToken: function () {
- //NOTE: if we have pending character token make it's end location equal to the
- //current token's start location.
- if (this.currentCharacterToken)
- this.currentCharacterToken.location.endOffset = this.currentToken.location.startOffset;
- this.currentToken.location.endOffset = mxn.posTracker.offset + 1;
- orig._emitCurrentToken.call(this);
- },
- _emitCurrentCharacterToken: function () {
- //NOTE: if we have character token and it's location wasn't set in the _emitCurrentToken(),
- //then set it's location at the current preprocessor position.
- //We don't need to increment preprocessor position, since character token
- //emission is always forced by the start of the next character token here.
- //So, we already have advanced position.
- if (this.currentCharacterToken && this.currentCharacterToken.location.endOffset === -1)
- this.currentCharacterToken.location.endOffset = mxn.posTracker.offset;
- orig._emitCurrentCharacterToken.call(this);
- }
- };
- //NOTE: patch initial states for each mode to obtain token start position
- Object.keys(Tokenizer.MODE).forEach(function (modeName) {
- var state = Tokenizer.MODE[modeName];
- methods[state] = function (cp) {
- mxn.currentTokenLocation = mxn._getCurrentLocation();
- orig[state].call(this, cp);
- };
- });
- return methods;
- };
|