Skip to content

Commit

Permalink
[568809] DOT Editor - Highlighting the indentation of HTML-Like Labels.
Browse files Browse the repository at this point in the history
- Modify the DotSemanticHighlightingCalculator to highlight the
indentation of the HTML-Like Labels with grey background.
- Implement corresponding DotHtmlLabelIndentationHighlightingTest test
cases.
  • Loading branch information
miklossy committed Nov 14, 2020
1 parent 8986b9a commit 3244b1b
Show file tree
Hide file tree
Showing 6 changed files with 498 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@
DotHighlightingTest.class, DotHoverTest.class,
DotHtmlLabelContentAssistLexerTest.class,
DotHtmlLabelContentAssistTest.class,
DotHtmlLabelHighlightingLexerTest.class, DotHtmlLabelQuickfixTest.class,
DotHtmlLabelRenameRefactoringTest.class,
DotHtmlLabelHighlightingLexerTest.class,
DotHtmlLabelIndentationHighlightingTest.class,
DotHtmlLabelQuickfixTest.class, DotHtmlLabelRenameRefactoringTest.class,
DotHtmlLabelTokenTypeToPartitionMapperTest.class,
DotHyperlinkingTest.class, DotLabelProviderTest.class,
DotMarkingOccurrencesTest.class, DotMultiQuickfixTest.class,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
/*******************************************************************************
* Copyright (c) 2020 itemis AG and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Tamas Miklossy (itemis AG) - initial API and implementation
*******************************************************************************/
package org.eclipse.gef.dot.tests

import java.util.List
import org.eclipse.core.resources.IFile
import org.eclipse.gef.dot.tests.ui.DotUiInjectorProvider
import org.eclipse.jface.text.IRegion
import org.eclipse.jface.text.Region
import org.eclipse.swt.SWT
import org.eclipse.swt.custom.StyledText
import org.eclipse.swt.graphics.Color
import org.eclipse.swt.widgets.Display
import org.eclipse.xtext.testing.InjectWith
import org.eclipse.xtext.testing.XtextRunner
import org.eclipse.xtext.ui.testing.AbstractHighlightingTest
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(XtextRunner)
@InjectWith(DotUiInjectorProvider)
class DotHtmlLabelIndentationHighlightingTest extends AbstractHighlightingTest {

// position marker
val c = '''<|>'''

List<IRegion> highlightingRegions = null

@Test def test001(){
'''
graph {
1 [label = <
«c» Text
>]
}
'''.testHtmlIndentationHighlighting
}

@Test def test002(){
'''
graph {
1 [
label = <
«c» Text
>]
}
'''.testHtmlIndentationHighlighting
}

@Test def test003(){
'''
graph {
1 [label=
<
«c» Text
>]
}
'''.testHtmlIndentationHighlighting
}

@Test def test004(){
'''
graph {
1 [label=
<
«c» Text
>]
}
'''.testHtmlIndentationHighlighting
}

@Test def test005(){
'''
graph {
1 [label=
<
«c» <TABLE>
«c» <TR>
«c» <TD>Text</TD>
«c» </TR>
«c» </TABLE>
>]
}
'''.testHtmlIndentationHighlighting
}

@Test def test006(){
'''
graph {
1 [label=
<
«c» <TABLE>
«c» <TR>
«c» <TD>Text</TD>
«c» </TR>
«c» </TABLE>
>]
}
'''.testHtmlIndentationHighlighting
}

private def testHtmlIndentationHighlighting(CharSequence text) {
text.calculateHighlightingRegions
val content = text.toString.replace(c, "")
testHighlighting(content, null, SWT.NORMAL, 0, 0, 0, 220, 220, 220)
}

protected override testHighlighting(StyledText styledText, String text, int fontStyle,
int foregroundR, int foregroundG, int foregroundB,
int backgroundR, int backgroundG, int backgroundB) {

val expectedForegroundColor = new Color(null, foregroundR, foregroundG, foregroundB)
val expectedBackgroundColor = new Color(null, backgroundR, backgroundG, backgroundB)

for(highlightingRegion : highlightingRegions) {
val offset = highlightingRegion.offset

for (var i = 0; i < highlightingRegion.length; i++) {
val currentPosition = offset + i
val character = styledText.getTextRange(currentPosition, 1)
val styleRange = styledText.getStyleRangeAtOffset(currentPosition)
if (character.isRelevant) {
styleRange => [
assertFontStyle(character, fontStyle)
assertForegroundColor(character, expectedForegroundColor)
assertBackgroundColor(character, expectedBackgroundColor)
]
} else {
Assert.fail("Non relevant character '" + character + "' found!")
}
}
}
}

override protected isRelevant(String character) {
// consider only whitespace characters
Character.isWhitespace(character.charAt(0))
}

private def void calculateHighlightingRegions(CharSequence input) {
highlightingRegions = newArrayList

val text = input.toString

var fromIndex = 0

while (fromIndex < text.lastIndexOf(c)) {
val first = text.indexOf(c, fromIndex)

if (first==-1) {
fail('''Can't locate the first position symbol '«c»' in the input text''')
}
val second = text.getIndexOfFirstNonWhitespaceCharacter(first+c.length)
if (second==-1) {
fail('''Can't locate non-whitespace characters after the position symbol '«c»' in the input text''')
}

val offset = first - (highlightingRegions.length/*-1*/)*c.length
val length = second - first - c.length
val highlightingRegion = new Region(offset, length)
highlightingRegions.add(highlightingRegion)

fromIndex = second + c.length
}
}

private def int getIndexOfFirstNonWhitespaceCharacter(String text, int fromIndex) {
for(var i=fromIndex; i<text.length; i++) {
if (!Character.isWhitespace(text.charAt(i))) {
return i
}
}
return -1
}

/**
* This derived class includes the fix
* https://github.com/eclipse/xtext-eclipse/commit/9c63ca2ed24050d4fa9fba431f7442f0e903925a
* available from Xtext Version 2.18 (Eclipse 2019-06).
* TODO: remove this workaround as soon as Eclipse 2019-06 will be the minimum platform supported by GEF DOT.
*/
protected override openInEditor(IFile dslFile) {
val editor = dslFile.openEditor

waitForEventProcessingWorkaround

editor.internalSourceViewer.textWidget
}

protected def waitForEventProcessingWorkaround() {
while (Display.^default.readAndDispatch) { }
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public class DotHighlightingConfiguration
public static final String HTML_ATTRIBUTE_VALUE = "html_attribute_value"; //$NON-NLS-1$
public static final String HTML_CONTENT = "html_content"; //$NON-NLS-1$
public static final String HTML_COMMENT = "html_comment"; //$NON-NLS-1$
public static final String HTML_INDENTATION = "html_indentation"; //$NON-NLS-1$

public static final String DEPRECATED_ATTRIBUTE_VALUE = "deprecated_attribute_value"; //$NON-NLS-1$
public static final String QUOTED_SUFFIX = "_quoted"; //$NON-NLS-1$
Expand Down Expand Up @@ -97,6 +98,8 @@ public void configure(IHighlightingConfigurationAcceptor acceptor) {
htmlContentStyle());
acceptor.acceptDefaultHighlighting(HTML_COMMENT, "Html Comment", //$NON-NLS-1$
htmlCommentStyle());
acceptor.acceptDefaultHighlighting(HTML_INDENTATION, "Html Indentation", //$NON-NLS-1$
htmlIndentationStyle());

// deprecated highlighting
acceptor.acceptDefaultHighlighting(DEPRECATED_ATTRIBUTE_VALUE,
Expand Down Expand Up @@ -192,6 +195,12 @@ private TextStyle htmlCommentStyle() {
return textStyle;
}

private TextStyle htmlIndentationStyle() {
TextStyle textStyle = defaultTextStyle().copy();
textStyle.setBackgroundColor(new RGB(220, 220, 220)); // grey
return textStyle;
}

private TextStyle deprecatedStyle() {
TextStyle textStyle = stringTextStyle().copy();
textStyle.setStyle(TextAttribute.STRIKETHROUGH);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
*******************************************************************************/
package org.eclipse.gef.dot.internal.ui.language.highlighting;

import java.util.List;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.gef.dot.internal.DotAttributes;
import org.eclipse.gef.dot.internal.language.dot.Attribute;
Expand Down Expand Up @@ -41,6 +43,9 @@ public void doProvideHighlightingFor(XtextResource resource,

// It gets a node model.
INode root = resource.getParseResult().getRootNode();

String dotText = root.getText();

for (INode node : root.getAsTreeIterable()) {
EObject grammarElement = node.getGrammarElement();
if (grammarElement instanceof RuleCall) {
Expand Down Expand Up @@ -91,7 +96,7 @@ public void doProvideHighlightingFor(XtextResource resource,
DotHighlightingConfiguration.EDGE_OP_ID);
}
if (r.getName().equals("HTML_STRING")) { //$NON-NLS-1$
provideHighlightingForHtmlString(node, acceptor);
provideHighlightingForHtmlString(node, dotText, acceptor);
}
}
}
Expand Down Expand Up @@ -122,7 +127,7 @@ private void provideHighlightingForArrowTypeString(INode node,
acceptor, suffix);
}

private void provideHighlightingForHtmlString(INode node,
private void provideHighlightingForHtmlString(INode node, String dotText,
IHighlightedPositionAcceptor acceptor) {
// highlight the leading '<' symbol
int openingSymbolOffset = node.getOffset();
Expand All @@ -136,14 +141,44 @@ private void provideHighlightingForHtmlString(INode node,
DotHighlightingConfiguration.HTML_TAG);

// trim the leading '<' and trailing '>' symbols
String htmlString = node.getText().substring(1,
node.getText().length() - 1);
String htmlText = node.getText();

// highlight the html indentations
List<TextLine> htmlTextLines = TextLines.splitString(htmlText);
int htmlTextStartOffset = node.getOffset();
int indentationLength = getIndentationLength(node, dotText);
/*
* do not hightlight the leading '<' and trailing '>' symbols, skipping
* the first and the last line
*/
for (int i = 1; i < htmlTextLines.size() - 1; i++) {
TextLine htmlTextLine = htmlTextLines.get(i);
int offset = htmlTextStartOffset + htmlTextLine.getRelativeOffset()
+ indentationLength;
int length = htmlTextLine.getLeadingWhiteSpace().length()
- indentationLength;
acceptor.addPosition(offset, length,
DotHighlightingConfiguration.HTML_INDENTATION);
}

// delegate the highlighting of the the html-label substring to the
// corresponding sub-grammar highlighter
String htmlString = htmlText.substring(1, htmlText.length() - 1);
DotSubgrammarHighlighter htmlLabelHighlighter = new DotSubgrammarHighlighter(
DotActivator.ORG_ECLIPSE_GEF_DOT_INTERNAL_LANGUAGE_DOTHTMLLABEL);
htmlLabelHighlighter.provideHightlightingFor(htmlString,
node.getOffset() + 1, acceptor);
}

/**
* Get the indentation length of the line containing the leading '<' symbol.
*/
private int getIndentationLength(INode htmlTextNode, String dotText) {
int htmlTextStartLine = htmlTextNode.getStartLine();
List<TextLine> dotTextLines = TextLines.splitString(dotText);
TextLine lineContainingTheLeadingAngleSymbol = dotTextLines
.get(htmlTextStartLine - 1);
return lineContainingTheLeadingAngleSymbol.getLeadingWhiteSpace()
.length();
}
}
Loading

0 comments on commit 3244b1b

Please sign in to comment.