Skip to content

Commit

Permalink
Fix issue #28: Inline event handlers in markup cause errors when used…
Browse files Browse the repository at this point in the history
… without quotes
  • Loading branch information
alexprey committed Aug 25, 2020
1 parent 2d295a9 commit fc7ed7b
Show file tree
Hide file tree
Showing 10 changed files with 73 additions and 48 deletions.
13 changes: 9 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,20 @@ All notable changes to the "svelte-intellisense" extension will be documented in

Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.

## [3.0.3] 25.08.2020

- 🛠 **[Fixed]** Fix [issue #28](https://github.com/alexprey/sveltedoc-parser/issues/28) (Inline event handlers in markup cause errors when used without quotes)
- Change dependency from `htmlparser2` to [htmlparser2-svelte](https://www.npmjs.com/package/htmlparser2-svelte) special fork of [htmlparser2](https://www.npmjs.com/package/htmlparser2) to handle Svelte specific cases to parse markup

## [3.0.2] 24.08.2020

- 🛠 [Fixed] Fix issue #6 (Build a correct component name from a file name)
- 🛠 **[Fixed]** Fix issue #6 (Build a correct component name from a file name)
```
round.button.svelte -> RoundButton
```
- 🛠 [Fixed] Fix issue #27 (Events is not exposed from exported functions and arrow functions)
- 🛠 [Fixed] Fix issue #31 (Propogated events in markup should be parsed even it was before handled)
- 🛠 [Fixed] Fix issue #32 (Event is not registered when dispatched from functions used as a parameters of another functions)
- 🛠 **[Fixed]** Fix [issue #27](https://github.com/alexprey/sveltedoc-parser/issues/27) (Events is not exposed from exported functions and arrow functions)
- 🛠 **[Fixed]** Fix [issue #31](https://github.com/alexprey/sveltedoc-parser/issues/31) (Propogated events in markup should be parsed even it was before handled)
- 🛠 **[Fixed]** Fix [issue #32](https://github.com/alexprey/sveltedoc-parser/issues/32) (Event is not registered when dispatched from functions used as a parameters of another functions)

## [3.0.1] 17.08.2020

Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ Generate a JSON documentation for a Svelte file

## Changelog

### [3.0.3] 25.08.2020

- 🛠 **[Fixed]** Fix [issue #28](https://github.com/alexprey/sveltedoc-parser/issues/28) (Inline event handlers in markup cause errors when used without quotes)
- Change dependency from `htmlparser2` to [htmlparser2-svelte](https://www.npmjs.com/package/htmlparser2-svelte) special fork of [htmlparser2](https://www.npmjs.com/package/htmlparser2) to handle Svelte specific cases to parse markup

### [3.0.2] 24.08.2020

- 🛠 **[Fixed]** Fix issue #6 (Build a correct component name from a file name)
Expand Down
2 changes: 1 addition & 1 deletion examples/Alert.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
The `close` event fired when user click to X button in the panel.
@event CloseEvent#close
-->
<button on:click="{e => dispatch('close')}">&times;</button>
<button on:click={() => dispatch('close')}>&times;</button>
</div>
{/if}
</div>
2 changes: 1 addition & 1 deletion lib/parser.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const EventEmitter = require('events');
const espree = require('espree');
const eslint = require('eslint');
const HtmlParser = require('htmlparser2').Parser;
const HtmlParser = require('htmlparser2-svelte').Parser;
const path = require('path');
const utils = require('./utils');
const jsdoc = require('./jsdoc');
Expand Down
53 changes: 25 additions & 28 deletions lib/v3/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const path = require('path');

const espree = require('espree');
const eslint = require('eslint');
const HtmlParser = require('htmlparser2').Parser;
const HtmlParser = require('htmlparser2-svelte').Parser;

const utils = require('./../utils');
const jsdoc = require('./../jsdoc');
Expand Down Expand Up @@ -573,10 +573,15 @@ class Parser extends EventEmitter {

parseMarkupExpressionBlock(expression, offset) {
// Add name for anonymous functions to prevent parser error
const regex = /^{\s*function\s+\(/i;
const regex = /^{?\s*function\s+\(/i;

expression = expression.replace(regex, function () {
return '{function a(';
expression = expression.replace(regex, function (m) {
// When quotes in attributes used curcly braces are provided here, so we should handle it separatly
if (m.startsWith('{')) {
return '{function a(';
}

return 'function a(';
});

const ast = espree.parse(
Expand Down Expand Up @@ -724,8 +729,6 @@ class Parser extends EventEmitter {
}
},
onattribute: (name, value) => {
console.log('onattribute', name, value);

if (this.includeSourceLocations && parser.startIndex >= 0 && parser.endIndex >= parser.startIndex) {
lastAttributeLocations[name] = {
start: lastAttributeIndex,
Expand Down Expand Up @@ -783,14 +786,11 @@ class Parser extends EventEmitter {
}
},
onopentagname: (tagName) => {
console.log('onopentagname', tagName);
lastTagName = tagName;
lastAttributeIndex = parser._tokenizer._index;
lastAttributeLocations = {};
},
onopentag: (tagName, attrs) => {
console.log('onopentag', tagName, attrs);

const isNotStyleOrScript = !['style', 'script'].includes(tagName);
const isTopLevelElement = parser._stack.length === 1;

Expand Down Expand Up @@ -845,8 +845,8 @@ class Parser extends EventEmitter {

const attributeValue = attrs[name];

if (attributeValue && attributeValue.length > 2 && attributeValue.charAt(0) === '{' && attributeValue.charAt(attributeValue.length - 1) === '}') {
targetPropertyName = attributeValue.substr(1, attributeValue.length - 2);
if (attributeValue && attributeValue.length > 0) {
targetPropertyName = attributeValue;
}

return {
Expand Down Expand Up @@ -885,30 +885,27 @@ class Parser extends EventEmitter {

if (this.features.includes('refs')) {
if (hasOwnProperty(attrs, 'bind:this') && attrs['bind:this']) {
const value = attrs['bind:this'];
const bindedVariableName = attrs['bind:this'];

if (value.length > 2 && value.charAt(0) === '{' && value.charAt(value.length - 1) === '}') {
const bindedVariableName = value.substr(1, value.length - 2);

this.emitRefItem({
name: bindedVariableName,
parent: tagName,
locations: this.includeSourceLocations && hasOwnProperty(lastAttributeLocations, 'bind:this')
? [lastAttributeLocations['bind:this']]
: null,
// TODO: Reprication, remove this property with 3.*
loc: this.includeSourceLocations && hasOwnProperty(lastAttributeLocations, 'bind:this')
? lastAttributeLocations['bind:this']
: null
});
}
this.emitRefItem({
name: bindedVariableName,
parent: tagName,
locations: this.includeSourceLocations && hasOwnProperty(lastAttributeLocations, 'bind:this')
? [lastAttributeLocations['bind:this']]
: null,
// TODO: Reprication, remove this property with 3.*
loc: this.includeSourceLocations && hasOwnProperty(lastAttributeLocations, 'bind:this')
? lastAttributeLocations['bind:this']
: null
});
}
}
}
}
}, {
lowerCaseTags: false,
lowerCaseAttributeNames: false
lowerCaseAttributeNames: false,
curlyBracesInAttributes: true
});

parser.write(this.structure.template);
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sveltedoc-parser",
"version": "3.0.2",
"version": "3.0.3",
"description": "Generate a JSON documentation for a Svelte file",
"main": "index.js",
"scripts": {
Expand Down Expand Up @@ -38,7 +38,7 @@
"dependencies": {
"espree": "7.2.0",
"eslint": "7.6.0",
"htmlparser2": "3.9.2"
"htmlparser2-svelte": "4.1.0"
},
"devDependencies": {
"chai": "4.1.2",
Expand Down
4 changes: 2 additions & 2 deletions test/svelte3/integration/bind/bind.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ describe('SvelteDoc v3 - Bind', () => {
expect(doc, 'Document should be provided').to.exist;
expect(doc.data, 'Document data should be parsed').to.exist;

expect(doc.data.length).to.equal(1);
expect(doc.data.length, 'Found following data items - ' + doc.data.map(d => d.name).join(', ')).to.equal(1);
const item = doc.data[0];

expect(item, 'Bind item should be a valid entity').to.exist;
Expand Down Expand Up @@ -98,7 +98,7 @@ describe('SvelteDoc v3 - Bind', () => {
expect(doc, 'Document should be provided').to.exist;
expect(doc.data, 'Document data should be parsed').to.exist;

expect(doc.data.length).to.equal(1);
expect(doc.data.length, 'Found following data items - ' + doc.data.map(d => d.name).join(', ')).to.equal(1);
const item = doc.data[0];

expect(item, 'Bind item should be a valid entity').to.exist;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@

<button on:click="{() => customDispatcherName('notify', 'data')}">
FIRE!
</button>

<button on:click={() => customDispatcherName('notify2', 'data')}>
FIRE!
</button>
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@

<button on:click="{function () { dispatch('notify'); }}">
CLICK!
</button>

<button on:click={function () { dispatch('notify2'); }}>
CLICK!
</button>
30 changes: 20 additions & 10 deletions test/svelte3/integration/events/events.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,12 +147,17 @@ describe('SvelteDoc v3 - Events', () => {
expect(doc, 'Document should be provided').to.exist;
expect(doc.events, 'Document events should be parsed').to.exist;

expect(doc.events.length).to.equal(1);
const event = doc.events[0];
const event1 = doc.events.find(e => e.name === 'notify');

expect(event, 'Event should be a valid entity').to.exist;
expect(event.name).to.equal('notify');
expect(event.visibility).to.equal('public');
expect(event1, 'Event should be a valid entity').to.exist;
expect(event1.name).to.equal('notify');
expect(event1.visibility).to.equal('public');

const event2 = doc.events.find(e => e.name === 'notify2');

expect(event2, 'Event should be a valid entity').to.exist;
expect(event2.name).to.equal('notify2');
expect(event2.visibility).to.equal('public');

done();
}).catch(e => {
Expand Down Expand Up @@ -279,12 +284,17 @@ describe('SvelteDoc v3 - Events', () => {
expect(doc, 'Document should be provided').to.exist;
expect(doc.events, 'Document events should be parsed').to.exist;

expect(doc.events.length).to.equal(1);
const event = doc.events[0];
const event1 = doc.events.find(e => e.name === 'notify');

expect(event, 'Event should be a valid entity').to.exist;
expect(event.name).to.equal('notify');
expect(event.visibility).to.equal('public');
expect(event1, 'Event should be a valid entity').to.exist;
expect(event1.name).to.equal('notify');
expect(event1.visibility).to.equal('public');

const event2 = doc.events.find(e => e.name === 'notify2');

expect(event2, 'Event should be a valid entity').to.exist;
expect(event2.name).to.equal('notify2');
expect(event2.visibility).to.equal('public');

done();
}).catch(e => {
Expand Down

0 comments on commit fc7ed7b

Please sign in to comment.