aurelia / template-lint

Sanity check of Aurelia-flavor template HTML
Apache License 2.0
56 stars 17 forks source link

Cannot read property 'children' of null #118

Closed bondib closed 7 years ago

bondib commented 7 years ago

I've attached all the parser information as well:

Parser { _readableState: ReadableState { objectMode: false, highWaterMark: 16384, buffer: [], length: 0, pipes: Writable { _writableState: [Object], writable: true, domain: null, _events: [Object], _eventsCount: 5, _maxListeners: undefined }, pipesCount: 1, flowing: true, ended: false, endEmitted: false, reading: true, sync: false, needReadable: true, emittedReadable: false, readableListening: false, resumeScheduled: false, defaultEncoding: 'utf8', ranOut: false, awaitDrain: 0, readingMore: false, decoder: null, encoding: null }, readable: true, domain: null, _events: { end: [ [Object], [Object], [Function] ], prefinish: { [Function: g] listener: [Function] }, data: [Function: ondata], startTag: [ [Function], [Function], [Function], [Function], [Function], [Function], [Function], [Function], [Function], [Function], [Function], [Function], [Function] ], endTag: [ [Function], [Function], [Function] ], text: [ [Function], [Function] ], unpipe: [Function: onunpipe], drain: [Function], error: [Function: onerror], close: { [Function: g] listener: [Function: onclose] }, finish: { [Function: g] listener: [Function: onfinish] } }, _eventsCount: 11, _maxListeners: 100, _writableState: WritableState { objectMode: false, highWaterMark: 16384, needDrain: false, ending: false, ended: false, finished: false, decodeStrings: true, defaultEncoding: 'utf8', length: 9703, writing: true, corked: 0, sync: true, bufferProcessing: false, onwrite: [Function], writecb: [Function: nop], writelen: 9703, bufferedRequest: null, lastBufferedRequest: null, pendingcb: 1, prefinished: false, errorEmitted: false, bufferedRequestCount: 0, corkedRequestsFree: CorkedRequest { next: null, entry: null, finish: [Function] } }, writable: true, allowHalfOpen: true, _transformState: TransformState { afterTransform: [Function], needTransform: true, transforming: true, writecb: [Function], writechunk: <Buffer 3c 74 65 6d 70 6c 61 74 65 3e 0a 20 20 20 20 3c 72 65 71 75 69 72 65 20 66 72 6f 6d 3d 22 2e 2f 74 6f 49 63 6f 6e 22 3e 3c 2f 72 65 71 75 69 72 65 3e ... >, writeencoding: 'buffer' }, options: { locationInfo: true }, tokenizer: { preprocessor: { html: '<template>\n <require from="./toIcon"></require>\n <require from="./k2-menu.css"></require>\n <div class="k2-menu">\n <div class="quick-add inline-form">\n <!-- Quick add -->\n <div class="form-group">\n <div class="input-group input-group-sm">\n <span class="input-group-btn">\n <button class="btn btn-default" data-toggle="modal" href="#newk2MenuGroupModal" title="Add K2s">\n <i class="fa fa-plus" aria-hidden="true"></i>\n </button>\n </span>\n <input type="text" class="form-control quick-add-input" value.bind="quickAddStr" placeholder="Quick Add..." keydown.trigger="quickAddkeydown($event)">\n <!--<span class="input-group-btn">\n <button class="btn btn-default" type="button" click.trigger="quickAddBtnClick()">\n <i class="fa fa-caret-right" aria-hidden="true"></i>\n </button>\n </span>-->\n </div>\n <!-- auto complete -->\n <div class="dropdown quick-add-dropdown">\n <a class="dropdown-toggle hidden" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true"></a>\n <ul class="dropdown-menu">\n <li repeat.for="quickAddSugg of quickAddAvailableValues">\n <a href="#" href="javascript:;" click.trigger="quickAddDropdownClick(quickAddSugg)">${quickAddSugg.label}</a>\n </li>\n </ul>\n </div>\n <!-- /input-group -->\n </div>\n </div>\n <!-- The k2 group list -->\n <div class="k2-list">\n <!-- Main menu -->\n <div if.bind="isMainMenuVisible" class="k2-list-group list-group main-menu au-animate">\n <a href="#" title.bind="menuItem.tooltip" repeat.for="menuItem of mainMenuItems" click.trigger="menuClick(menuItem)" class="au-animate list-group-item ${menuItem.id == selectedItem.id ? \'active\':\'\'}">\n <button if.bind="menuItem.canDelete()" type="button" class="close" aria-label="Close" click.trigger="deleteGroupClick(menuItem,$event)"\n title="Remove"><span aria-hidden="true">&times;</span></button>\n <button if.bind="menuItem.canDrillDown" click.delegate="drillDown(menuItem,$event)" class="item-btn grey-cararra list-group-item-drill-btn">\n <i class="fa fa-angle-right" aria-hidden="true"></i>\n </button>\n <!--<i class="${menuItem.type | toIcon}" aria-hidden="true"></i>-->\n <span class="list-group-item-label">${menuItem.label}</span>\n <small if.bind="menuItem.type == \'k2\' && menuItem.account"> - ${menuItem.account.name}</small>\n <small if.bind="menuItem.k2s.length>0 && menuItem.type != \'k2\'"> [${menuItem.k2s.length} k2s]</small>\n </a>\n </div>\n <!-- Secondary menu-->\n <div if.bind="!isMainMenuVisible" class="k2-list-group list-group secondary-menu au-animate">\n <a href="#" title.bind="menuItem.tooltip" repeat.for="menuItem of secondaryMenuItems" click.trigger="menuClick(menuItem)"\n class="au-animate list-group-item ${selectedItem!=null && menuItem.id == selectedItem.id ? \'active\':\'\'}">\n <button if.bind="menuItem.type == \'Back\'" click.delegate="backToMainMenu(menuItem,$event)" class="item-btn">\n <i class="${menuItem.type | toIcon}" aria-hidden="true"></i>\n </button>\n <span>${menuItem.label}</span>\n <small if.bind="showFullLabel"> - ${menuItem.account.name}</small>\n <small if.bind="menuItem.type == \'Back\' && menuItem.k2s.length>0 && menuItem.type != \'k2\'"> [${menuItem.k2s.length} k2s]</small>\n </a>\n </div>\n </div>\n <!-- Create group Modal -->\n <div class="modal fade" id="newk2MenuGroupModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">\n <div class="modal-dialog" role="document">\n <div class="modal-content">\n <div class="portlet light bordered">\n <div class="portlet-title tabbable-line">\n <div class="caption font-yellow-crusta">\n <i class="icon-pin font-yellow-crusta"></i>\n <span class="caption-subject bold uppercase"> Add new </span>\n </div>\n <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>\n <ul class="nav nav-tabs">\n <li class="active">\n <a href="#addSinglek2TabPanel" data-toggle="tab"> Single K2 </a>\n </li>\n <li>\n <a href="#addk2GroupTabPanel" data-toggle="tab"> K2 group </a>\n </li>\n <li>\n <a href="#addEverythingTabPanel" data-toggle="tab"> Everything </a>\n </li>\n </ul>\n </div>\n <div class="portlet-body">\n <!-- Tab panes -->\n <div class="tab-content">\n <div id="addSinglek2TabPanel" role="tabpanel" class="tab-pane active">\n <form>\n <div class="form-body clearfix">\n <div class="form-group">\n <label class="control-label">New K2 id</label>\n <input type="text" value.bind="newArbitraryK2sId" class="form-control" placeholder="K2 Id to add" required>\n </div>\n <br>\n <div class="form-group pull-right">\n <input type="submit" value=" Add K2 " class="btn btn-sm btn-default" click.delegate="addArbitraryK2ToMenu(newArbitraryK2sId)"></button>\n <button type="button" class="btn btn-sm default" data-dismiss="modal">Close</button>\n </div>\n </div>\n </form>\n </div>\n <div id="addk2GroupTabPanel" role="tabpanel" class="tab-pane">\n <form>\n <div class="form-body clearfix">\n <div class="form-group">\n <label class="control-label">Group name</label>\n <input type="text" value.bind="newCustomeGroupK2sName" class="form-control" placeholder="Group name" required>\n </div>\n <div class="form-group">\n <label class="control-label">Group K2s (comma seperated id list)</label>\n <textarea class="form-control" placeholder="K2 id list" value.bind="newCustomeGroupK2sList"></textarea>\n </div>\n <br>\n <div class="form-group pull-right">\n <input type="submit" value="Create new K2 group" class="btn btn-sm btn-default" click.delegate="createCustomK2Group(newCustomeGroupK2sName,newCustomeGroupK2sList)"></input>\n <button type="button" class="btn btn-sm default" data-dismiss="modal">Close</button>\n </div>\n </div>\n </form>\n </div>\n <div id="addEverythingTabPanel" role="tabpanel" class="tab-pane">\n <div class="form-body clearfix">\n <div class="form-group">\n <label class="mt-checkbox mt-checkbox-outline"> Include "All K2s" in menu\n <input type="checkbox" checked.bind="includesEverything">\n <span></span>\n </label>\n </div>\n <div class="form-group pull-right">\n <button type="button" class="btn btn-sm default" data-dismiss="modal">Close</button>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n </div>\n </div>\n </div>\n </div>\n</template>', pos: 9702, lastGapPos: -1, gapStack: [], skipNextNewLine: false, lastChunkWritten: false, endOfChunkHit: false, lastCharPos: 9702 }, tokenQueue: [], allowCDATA: false, state: 'DATA_STATE', returnState: 'ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE', tempBuff: [ 116, 101, 120, 116, 97, 114, 101, 97 ], additionalAllowedCp: undefined, lastStartTagName: 'button', consumedAfterSnapshot: 1, active: true, currentCharacterToken: null, currentToken: null, currentAttr: { name: 'data-dismiss', value: 'modal' }, _consume: [Function], _unconsume: [Function], _createStartTagToken: [Function], _createEndTagToken: [Function], _createCommentToken: [Function], _createDoctypeToken: [Function], _createCharacterToken: [Function], _createAttr: [Function], _leaveAttrName: [Function], _leaveAttrValue: [Function], _attachCurrentAttrLocationInfo: [Function], _emitCurrentToken: [Function], _emitCurrentCharacterToken: [Function], DATA_STATE: [Function], RCDATA_STATE: [Function], RAWTEXT_STATE: [Function], SCRIPT_DATA_STATE: [Function], PLAINTEXT_STATE: [Function], currentAttrLocation: { line: 131, col: 94, startOffset: 9365, endOffset: 9385 } }, parserFeedbackSimulator: { tokenizer: { preprocessor: [Object], tokenQueue: [], allowCDATA: false, state: 'DATA_STATE', returnState: 'ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE', tempBuff: [Object], additionalAllowedCp: undefined, lastStartTagName: 'button', consumedAfterSnapshot: 1, active: true, currentCharacterToken: null, currentToken: null, currentAttr: [Object], _consume: [Function], _unconsume: [Function], _createStartTagToken: [Function], _createEndTagToken: [Function], _createCommentToken: [Function], _createDoctypeToken: [Function], _createCharacterToken: [Function], _createAttr: [Function], _leaveAttrName: [Function], _leaveAttrValue: [Function], _attachCurrentAttrLocationInfo: [Function], _emitCurrentToken: [Function], _emitCurrentCharacterToken: [Function], DATA_STATE: [Function], RCDATA_STATE: [Function], RAWTEXT_STATE: [Function], SCRIPT_DATA_STATE: [Function], PLAINTEXT_STATE: [Function], currentAttrLocation: [Object] }, namespaceStack: [ 'http://www.w3.org/1999/xhtml' ], namespaceStackTop: 0, inForeignContent: false, currentNamespace: 'http://www.w3.org/1999/xhtml', skipNextNewLine: false }, pendingText: '\n', currentTokenLocation: { line: 142, col: 11, startOffset: 9691, endOffset: 9692 }, lastChunkWritten: false, stopped: false, state: ParserState { scopes: [ 'html', 'body', 'template', 'svg', 'math' ], voids: [ 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr' ], stack: [ [Object] ], issues: [ [Object], [Object] ], nextScope: null, nextNode: null, scope: undefined } } /home/bondi/dev/healthshield/harmony/node_modules/template-lint/dist/ast.js:59 current.children.push(child); ^

TypeError: Cannot read property 'children' of null

at Parser.<anonymous> (/home/bondi/dev/healthshield/harmony/node_modules/template-lint/dist/ast.js:59:20)
at emitTwo (events.js:105:20)
at Parser.emit (events.js:185:7)
at Parser.SAXParser._emitPendingText (/home/bondi/dev/healthshield/harmony/node_modules/parse5/lib/sax/index.js:227:14)
at Parser.SAXParser._runParsingLoop (/home/bondi/dev/healthshield/harmony/node_modules/parse5/lib/sax/index.js:148:18)
at Parser.SAXParser._transform (/home/bondi/dev/healthshield/harmony/node_modules/parse5/lib/sax/index.js:76:14)
at Parser.Transform._read (_stream_transform.js:167:10)
at Parser.Transform._write (_stream_transform.js:155:12)
at doWrite (_stream_writable.js:300:12)
at writeOrBuffer (_stream_writable.js:286:5)
at Parser.Writable.write (_stream_writable.js:214:11)
at Readable.ondata (_stream_readable.js:536:20)
at emitOne (events.js:90:13)
at Readable.emit (events.js:182:7)
at Readable.read (_stream_readable.js:368:10)
at flow (_stream_readable.js:751:26)
at emitReadable_ (_stream_readable.js:420:3)
at _combinedTickCallback (internal/process/next_tick.js:71:11)
at process._tickCallback (internal/process/next_tick.js:98:9)
MeirionHughes commented 7 years ago

Could you narrow down the html that causes the issue, please?

bondib commented 7 years ago

Well, after upgrading to aurelia-template-lint 0.9.9.(which also requires template-lint 0.8.9) - the issue is gone - so I'm closing the issue. Thanks again for the quick fixes!

obedm503 commented 6 years ago

I'm getting the same error. I just hooked the linter into the aurelia process-markup task

import gulp from 'gulp';
import changedInPlace from 'gulp-changed-in-place';
import { build } from 'aurelia-cli';
import linter from 'gulp-aurelia-template-lint';
import project from '../aurelia.json';

export default function processMarkup() {
  return gulp.src(project.markupProcessor.source)
    .pipe(changedInPlace({ firstPass: true }))
    .pipe(linter())
    .pipe(build.bundle());
}
arnederuwe commented 6 years ago

I can also reproduce this. My html contained

<span></span>:</span>

When correcting this, the linter stopped crashing