Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 259964 Details for
Bug 488586
Followup of bug 488257
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read
this important communication.
[patch]
Proposed patch including regression tests
488586.patch (text/plain), 14.57 KB, created by
Olivier Thomann
on 2016-02-26 13:21:31 EST
(
hide
)
Description:
Proposed patch including regression tests
Filename:
MIME Type:
Creator:
Olivier Thomann
Created:
2016-02-26 13:21:31 EST
Size:
14.57 KB
patch
obsolete
>diff --git a/bundles/org.eclipse.orion.client.webtools/web/htmlparser2/tokenizer.js b/bundles/org.eclipse.orion.client.webtools/web/htmlparser2/tokenizer.js >index 3464176..57eb319 100644 >--- a/bundles/org.eclipse.orion.client.webtools/web/htmlparser2/tokenizer.js >+++ b/bundles/org.eclipse.orion.client.webtools/web/htmlparser2/tokenizer.js >@@ -307,6 +307,12 @@ > this._baseState = this._state; > this._state = BEFORE_ENTITY; > this._sectionStart = this._index; >+ } else if (c === '<') { >+ valueStart = this._quoteStart; >+ this._emitToken("onattribdata"); >+ this._cbs.onattribend(false, valueStart); >+ this._state = BEFORE_ATTRIBUTE_NAME; >+ this._index--; > } > }; > >@@ -321,6 +327,12 @@ > this._baseState = this._state; > this._state = BEFORE_ENTITY; > this._sectionStart = this._index; >+ } else if (c === '<') { >+ valueStart = this._quoteStart; >+ this._emitToken("onattribdata"); >+ this._cbs.onattribend(false, valueStart); >+ this._state = BEFORE_ATTRIBUTE_NAME; >+ this._index--; > } > }; > >diff --git a/bundles/org.eclipse.orion.client.webtools/web/js-tests/webtools/htmlContentAssistTests.js b/bundles/org.eclipse.orion.client.webtools/web/js-tests/webtools/htmlContentAssistTests.js >index c06caeb..378dfb1 100644 >--- a/bundles/org.eclipse.orion.client.webtools/web/js-tests/webtools/htmlContentAssistTests.js >+++ b/bundles/org.eclipse.orion.client.webtools/web/js-tests/webtools/htmlContentAssistTests.js >@@ -22,7 +22,7 @@ > var astmanager = new ASTManager.HtmlAstManager(); > var assist = new HTMLAssist.HTMLContentAssistProvider(astmanager); > var tagTemplates = assist.getTags("", ""); >- var globalTagAttributes = assist.getAttributesForNode({name: "zzz", type: "tag"}, {offset: 0, prefix: ""}); >+ var globalTagAttributes = assist.getAttributesForNode({name: "zzz", type: "tag"}, "", {offset: 0, prefix: ""}); > > /** > * Set up the test and return an object for the test context >@@ -1732,6 +1732,97 @@ > assert(knownProp, "Could not find expected proposal role"); > }); > }); >+ it('Tags that support the attributes of many roles: details (13). Prefix role. <details r>', function() { >+ var _o = setup({buffer: '<html><body><details role></details></body></html>'}); >+ return assist.computeContentAssist(_o.editorContext, {offset: 25, prefix: 'role'}).then(function(proposals) { >+ var expectedCount = 2; // "ARIA title" + role >+ assert(proposals.length === expectedCount, "Incorrect number of proposals for details tag attributes. Proposal count: " + proposals.length + " Expected count: " + expectedCount); >+ var knownProp; >+ for (var i=0; i<proposals.length; i++) { >+ if (proposals[i].name === "role"){ >+ knownProp = proposals[i]; >+ } >+ } >+ assert(knownProp, "Could not find expected proposal role"); >+ }); >+ }); >+ it('Tags that support the attributes of many roles: details (13). Prefix empty. <details r>', function() { >+ var _o = setup({buffer: '<html><body><details role=></details></body></html>'}); >+ return assist.computeContentAssist(_o.editorContext, {offset: 26, prefix: ''}).then(function(proposals) { >+ var expectedCount = 1; // "ARIA title" + role >+ assert(proposals.length === expectedCount, "Incorrect number of proposals for details tag attributes. Proposal count: " + proposals.length + " Expected count: " + expectedCount); >+ var knownProp; >+ for (var i=0; i<proposals.length; i++) { >+ if (proposals[i].proposal === "\"\""){ >+ knownProp = proposals[i]; >+ } >+ } >+ assert(knownProp, "Could not find expected proposal role"); >+ }); >+ }); >+ it('Tags that support the attributes of many roles: details (13). Empty prefix. <details aria->', function() { >+ var _o = setup({buffer: '<html><body><details aria-></details></body></html>'}); >+ return assist.computeContentAssist(_o.editorContext, {offset: 26, prefix: ''}).then(function(proposals) { >+ var expectedCount = 17 + 13; // "ARIA title" + 16 aria-* globals + 13 role-specific aria-* attributes >+ assert(proposals.length === expectedCount, "Incorrect number of proposals for details tag attributes. Proposal count: " + proposals.length + " Expected count: " + expectedCount); >+ var knownProp; >+ for (var i=0; i<proposals.length; i++) { >+ if (proposals[i].name === "aria-checked"){ >+ knownProp = proposals[i]; >+ } >+ } >+ assert(knownProp, "Could not find expected proposal aria-checked"); >+ knownProp = null; >+ for (i=0; i<proposals.length; i++) { >+ if (proposals[i].name === "aria-expanded"){ >+ knownProp = proposals[i]; >+ } >+ } >+ assert(knownProp, "Could not find expected proposal aria-expanded"); >+ knownProp = null; >+ for (i=0; i<proposals.length; i++) { >+ if (proposals[i].name === "aria-activedescendant"){ >+ knownProp = proposals[i]; >+ } >+ } >+ assert(knownProp, "Could not find expected proposal aria-activedescendant"); >+ knownProp = null; >+ for (i=0; i<proposals.length; i++) { >+ if (proposals[i].name === "aria-multiselectable"){ >+ knownProp = proposals[i]; >+ } >+ } >+ assert(knownProp, "Could not find expected proposal aria-multiselectable"); >+ knownProp = null; >+ for (i=0; i<proposals.length; i++) { >+ if (proposals[i].name === "aria-pressed"){ >+ knownProp = proposals[i]; >+ } >+ } >+ assert(knownProp, "Could not find expected proposal aria-pressed"); >+ knownProp = null; >+ for (i=0; i<proposals.length; i++) { >+ if (proposals[i].name === "aria-required"){ >+ knownProp = proposals[i]; >+ } >+ } >+ assert(knownProp, "Could not find expected proposal aria-required"); >+ knownProp = null; >+ for (i=0; i<proposals.length; i++) { >+ if (proposals[i].name === "aria-posinset"){ >+ knownProp = proposals[i]; >+ } >+ } >+ assert(knownProp, "Could not find expected proposal aria-posinset"); >+ knownProp = null; >+ for (i=0; i<proposals.length; i++) { >+ if (proposals[i].name === "aria-setsize"){ >+ knownProp = proposals[i]; >+ } >+ } >+ assert(knownProp, "Could not find expected proposal aria-setsize"); >+ }); >+ }); > it('Tags that support the attributes of many roles: details (13). Prefix ar. <details ar>', function() { > var _o = setup({buffer: '<html><body><details ar></details></body></html>'}); > return assist.computeContentAssist(_o.editorContext, {offset: 21, prefix: 'ar'}).then(function(proposals) { >diff --git a/bundles/org.eclipse.orion.client.webtools/web/js-tests/webtools/htmlParserTests.js b/bundles/org.eclipse.orion.client.webtools/web/js-tests/webtools/htmlParserTests.js >index 7746b71..ed09e32 100644 >--- a/bundles/org.eclipse.orion.client.webtools/web/js-tests/webtools/htmlParserTests.js >+++ b/bundles/org.eclipse.orion.client.webtools/web/js-tests/webtools/htmlParserTests.js >@@ -490,7 +490,74 @@ > } > ]); > }); >- >+ it("Parse attributes - unclosed value, unclosed tag", function() { >+ var results = parse('<a src="</a>'); >+ assertResults(results.children, [ >+ { >+ type: 'tag', >+ name: 'a', >+ range: [0,12], >+ attributes: [ >+ { >+ name: 'src', >+ value: null, >+ range: [3,8] >+ } >+ ] >+ } >+ ]); >+ }); >+ it("Parse attributes - unclosed value, closed tag", function() { >+ var results = parse('<a src="></a>'); >+ assertResults(results.children, [ >+ { >+ type: 'tag', >+ name: 'a', >+ range: [0,13], >+ attributes: [ >+ { >+ name: 'src', >+ value: ">", >+ range: [3,9] >+ } >+ ] >+ } >+ ]); >+ }); >+ it("Parse attributes - unclosed value, unclosed tag", function() { >+ var results = parse("<a src='</a>"); >+ assertResults(results.children, [ >+ { >+ type: 'tag', >+ name: 'a', >+ range: [0,12], >+ attributes: [ >+ { >+ name: 'src', >+ value: null, >+ range: [3,8] >+ } >+ ] >+ } >+ ]); >+ }); >+ it("Parse attributes - unclosed value, closed tag", function() { >+ var results = parse("<a src='></a>"); >+ assertResults(results.children, [ >+ { >+ type: 'tag', >+ name: 'a', >+ range: [0,13], >+ attributes: [ >+ { >+ name: 'src', >+ value: ">", >+ range: [3,9] >+ } >+ ] >+ } >+ ]); >+ }); > // Instructions > it("Parse !doctype instruction", function() { > var results = parse('<!doctype html><html></html>'); >diff --git a/bundles/org.eclipse.orion.client.webtools/web/webtools/htmlContentAssist.js b/bundles/org.eclipse.orion.client.webtools/web/webtools/htmlContentAssist.js >index 9bd78ca..043f50c 100644 >--- a/bundles/org.eclipse.orion.client.webtools/web/webtools/htmlContentAssist.js >+++ b/bundles/org.eclipse.orion.client.webtools/web/webtools/htmlContentAssist.js >@@ -186,9 +186,9 @@ > if (this.isCompletingCommentClose(node, params.offset)){ > return this.getComment(node, params.offset, ast.source, false); > } else if (this.isCompletingAttributeValue(node, ast.source, params)) { >- return this.getValuesForAttribute(node, params); >+ return this.getValuesForAttribute(node, ast.source, params); > } else if (this.isCompletingTagAttribute(node, ast.source, params)) { >- return this.getAttributesForNode(node, params); >+ return this.getAttributesForNode(node, ast.source, params); > } else if (this.isCompletingTag(node, params)){ > if (this.isCompletingCommentOpen(node)){ > return this.getComment(node, params.offset, ast.source, true); >@@ -442,9 +442,38 @@ > * @returns {Array.<Object>} The array of proposals > * @since 10.0 > */ >- getAttributesForNode: function(node, params) { >- var attrs = Attributes.getAttributesForNode(node); >+ getAttributesForNode: function(node, source, params) { > var proposals = []; >+ var prefix = params.prefix ? params.prefix : ""; >+ // we need to check if we need to rebuild the prefix for completion that contains a '-' >+ var index = params.offset - prefix.length - 1; >+ if (index > 0 && index < source.length) { >+ var precedingChar = source.charAt(index); >+ if (precedingChar === '-') { >+ index--; >+ if (index !== 0) { >+ // rebuild a prefix based on what characters (letter only) are before the '-' >+ precedingChar = source.charAt(index); >+ var currentPrefix = "-" + prefix; >+ loop: while (index > 0 && /[A-Za-z0-9_-]/.test(precedingChar)) { >+ index--; >+ currentPrefix = precedingChar + currentPrefix; >+ if (index === 0) { >+ break loop; >+ } >+ precedingChar = source.charAt(index); >+ } >+ params.prefix = currentPrefix; >+ } >+ } else if (precedingChar === '=' && prefix.length === 0 && (index - 1) > 0) { >+ precedingChar = source.charAt(index - 1); >+ if (/[A-Za-z0-9_]/.test(precedingChar)) { >+ proposals.push(this.makeComputedProposal("\"\"", Messages['addQuotesToAttributes'], " - \"\"", null, prefix)); //$NON-NLS-1$ //$NON-NLS-2$ >+ return proposals; >+ } >+ } >+ } >+ var attrs = Attributes.getAttributesForNode(node); > if(Array.isArray(attrs.global)) { > proposals = proposals.concat(this.addProposals(node, attrs.global, params)); > } >@@ -460,7 +489,6 @@ > }); > proposals = proposals.concat(arr); > } >- > } > if(Array.isArray(attrs.keyboardevents)) { > arr = this.addProposals(node, attrs.keyboardevents, params); >@@ -474,7 +502,6 @@ > }); > proposals = proposals.concat(arr); > } >- > } > if(Array.isArray(attrs.mouseevents)) { > arr = this.addProposals(node, attrs.mouseevents, params); >@@ -488,7 +515,6 @@ > }); > proposals = proposals.concat(arr); > } >- > } > if(Array.isArray(attrs.windowevents) && attrs.windowevents.length > 0) { > arr = this.addProposals(node, attrs.windowevents, params); >@@ -502,7 +528,6 @@ > }); > proposals = proposals.concat(arr); > } >- > } > if(Array.isArray(attrs.aria)) { > arr = this.addProposals(node, attrs.aria, params); >@@ -517,7 +542,7 @@ > proposals = proposals.concat(arr); > } > } >- return proposals; >+ return proposals; > }, > > addProposals: function addProposals(node, attrs, params) { >@@ -652,9 +677,24 @@ > * @returns {Array.<Object>} The array of proposals > * @since 10.0 > */ >- getValuesForAttribute: function(node, params) { >- var vals = Attributes.getValuesForAttribute(node); >+ getValuesForAttribute: function(node, source, params) { > var proposals = []; >+ var prefix = params.prefix ? params.prefix : ""; >+ // we need to check if we need to rebuild the prefix for completion that contains a '-' >+ var index = params.offset - prefix.length - 1; >+ if (index > 0 && index < source.length) { >+ var precedingChar = source.charAt(index); >+ if (precedingChar === '=' && prefix.length === 0 && (index - 1) > 0) { >+ precedingChar = source.charAt(index - 1); >+ if (/[A-Za-z0-9_]/.test(precedingChar)) { >+ if (index + 1 >= source.length || >+ (source.charAt(index + 1) !== '\"' && source.charAt(index + 1) !== "'")) { >+ proposals.push(this.makeComputedProposal("\"\"", Messages['addQuotesToAttributes'], " - \"\"", null, prefix)); //$NON-NLS-1$ //$NON-NLS-2$ >+ } >+ } >+ } >+ } >+ var vals = Attributes.getValuesForAttribute(node); > if(Array.isArray(vals)) { > proposals = proposals.concat(this.addProposals(node, vals, params)); > } >@@ -703,6 +743,10 @@ > isCompletingAttributeValue: function(node, source, params) { > // TODO We can do better with the new parser, handle no quotes cases too > if(node && node.type === 'attr') { >+ if (node.valueRange) { >+ var range = node.valueRange; >+ return range[0] <= params.offset && range[1] >= params.offset; >+ } > return this.within('"', '"', source, params.offset, node.range) || //$NON-NLS-1$ //$NON-NLS-2$ > this.within("'", "'", source, params.offset, node.range); //$NON-NLS-1$ //$NON-NLS-2$ > } >diff --git a/bundles/org.eclipse.orion.client.webtools/web/webtools/nls/root/messages.js b/bundles/org.eclipse.orion.client.webtools/web/webtools/nls/root/messages.js >index 19e987d..93f75c2 100644 >--- a/bundles/org.eclipse.orion.client.webtools/web/webtools/nls/root/messages.js >+++ b/bundles/org.eclipse.orion.client.webtools/web/webtools/nls/root/messages.js >@@ -83,6 +83,7 @@ > 'keyboardeventsHeader': 'Keyboard Events', > 'mouseeventsHeader': 'Mouse Events', > 'windoweventsHeader': 'Window Events', >+ 'addQuotesToAttributes': ' - Add quotes to the current attribute', > > //CSS content assist > 'ruleTemplateDescription': 'rule - class selector rule',
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 488586
: 259964