From df565ff620d353f436f95090872e435919b1f832 Mon Sep 17 00:00:00 2001 From: Alexey Borokhvostov Date: Fri, 5 Dec 2025 12:23:42 +0700 Subject: [PATCH] PHP: Added CSS embedding to heredoc/nowdoc --- .../modules/editor/indent/TaskHandler.java | 7 + .../CssEmbeddingHighlightsContainer.java | 273 ++++++++++++++++++ .../embedding/CssEmbeddingProvider.java | 89 ++++++ .../EmbeddingHighlightsLayerFactory.java | 40 +++ .../modules/php/editor/lexer/GSFPHPLexer.java | 6 + .../modules/php/editor/lexer/PHPTokenId.java | 6 + .../php/editor/resources/Bundle.properties | 1 + .../php/editor/resources/fontsColors.xml | 3 + .../modules/php/editor/resources/layer.xml | 3 + .../testfiles/embedding/css_embedding_01.php | 21 ++ ...dding_01.php.testCssEmbedding_01.embedding | 6 + .../embedding/CssEmbeddingProviderTest.java | 36 +++ .../editor/embedding/EmbeddingTestBase.java | 53 ++++ 13 files changed, 544 insertions(+) create mode 100644 php/php.editor/src/org/netbeans/modules/php/editor/embedding/CssEmbeddingHighlightsContainer.java create mode 100644 php/php.editor/src/org/netbeans/modules/php/editor/embedding/CssEmbeddingProvider.java create mode 100644 php/php.editor/src/org/netbeans/modules/php/editor/embedding/EmbeddingHighlightsLayerFactory.java create mode 100644 php/php.editor/test/unit/data/testfiles/embedding/css_embedding_01.php create mode 100644 php/php.editor/test/unit/data/testfiles/embedding/css_embedding_01.php.testCssEmbedding_01.embedding create mode 100644 php/php.editor/test/unit/src/org/netbeans/modules/php/editor/embedding/CssEmbeddingProviderTest.java create mode 100644 php/php.editor/test/unit/src/org/netbeans/modules/php/editor/embedding/EmbeddingTestBase.java diff --git a/ide/editor.indent/src/org/netbeans/modules/editor/indent/TaskHandler.java b/ide/editor.indent/src/org/netbeans/modules/editor/indent/TaskHandler.java index b82db55659a0..2eef1e0df13e 100644 --- a/ide/editor.indent/src/org/netbeans/modules/editor/indent/TaskHandler.java +++ b/ide/editor.indent/src/org/netbeans/modules/editor/indent/TaskHandler.java @@ -168,17 +168,24 @@ boolean collectTasks() { } // current PHP formatter must run after HTML formatter + // For PHP files, the CSS formatter should run after the HTML formatter and JS formatter, but before the PHP formatter. if (items != null && "text/x-php5".equals(docMimeType())) { //NOI18N // Copy list, except for Ruby element, which we then add at the end List newItems = new ArrayList(items.size()); MimeItem phpItem = null; + MimeItem cssItem = null; for (MimeItem item : items) { if (item.mimePath().getPath().endsWith("text/x-php5")) { // NOI18N phpItem = item; + } else if (item.mimePath().getPath().endsWith("text/css")) { + cssItem = item; } else { newItems.add(item); } } + if (cssItem != null) { + newItems.add(cssItem); + } if (phpItem != null) { newItems.add(phpItem); } diff --git a/php/php.editor/src/org/netbeans/modules/php/editor/embedding/CssEmbeddingHighlightsContainer.java b/php/php.editor/src/org/netbeans/modules/php/editor/embedding/CssEmbeddingHighlightsContainer.java new file mode 100644 index 000000000000..4988e6749635 --- /dev/null +++ b/php/php.editor/src/org/netbeans/modules/php/editor/embedding/CssEmbeddingHighlightsContainer.java @@ -0,0 +1,273 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.netbeans.modules.php.editor.embedding; + +import java.awt.Color; +import java.util.Collection; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.text.AttributeSet; +import javax.swing.text.Document; +import javax.swing.text.SimpleAttributeSet; +import javax.swing.text.StyleConstants; +import org.netbeans.api.editor.mimelookup.MimeLookup; +import org.netbeans.api.editor.settings.AttributesUtilities; +import org.netbeans.api.editor.settings.FontColorSettings; +import org.netbeans.api.lexer.Language; +import org.netbeans.api.lexer.LanguagePath; +import org.netbeans.api.lexer.TokenHierarchy; +import org.netbeans.api.lexer.TokenHierarchyEvent; +import org.netbeans.api.lexer.TokenHierarchyListener; +import org.netbeans.api.lexer.TokenSequence; +import static org.netbeans.modules.php.api.util.FileUtils.PHP_MIME_TYPE; +import org.netbeans.spi.editor.highlighting.HighlightsSequence; +import org.netbeans.spi.editor.highlighting.support.AbstractHighlightsContainer; +import org.openide.util.Lookup.Result; +import org.openide.util.LookupEvent; +import org.openide.util.LookupListener; +import org.openide.util.WeakListeners; + +/** + * The class {@link org.netbeans.modules.html.editor.coloring.EmbeddingHighlightsContainer} is taken as a basis + */ +public class CssEmbeddingHighlightsContainer extends AbstractHighlightsContainer implements TokenHierarchyListener { + + private static final Logger LOG = Logger.getLogger(CssEmbeddingHighlightsContainer.class.getName()); + + private static final String CSS_BACKGROUND_TOKEN_NAME = "css-embedding"; //NOI18N + private static final String CSS_MIME_TYPE = "text/css"; //NOI18N + + private final Document document; + private AttributeSet cssBackground; + private TokenHierarchy hierarchy = null; + private long version = 0; + + private Result lookupResult; + private LookupListener lookupListener; + + CssEmbeddingHighlightsContainer(Document document) { + this.document = document; + + lookupResult = MimeLookup.getLookup(PHP_MIME_TYPE).lookupResult(FontColorSettings.class); + lookupResult.addLookupListener(WeakListeners.create(LookupListener.class, + lookupListener = new LookupListener() { + @Override + public void resultChanged(LookupEvent ev) { + refreshColorings(); + } + }, lookupResult)); + refreshColorings(); + } + + private void refreshColorings() { + Collection allInstances = lookupResult.allInstances(); + assert allInstances.size() > 0; + + FontColorSettings fcs = allInstances.iterator().next(); + Color cssBC = null; + if (fcs != null) { + cssBC = getColoring(fcs, CSS_BACKGROUND_TOKEN_NAME); + } + + cssBackground = cssBC == null ? SimpleAttributeSet.EMPTY : AttributesUtilities.createImmutable( + StyleConstants.Background, cssBC, + ATTR_EXTENDS_EOL, Boolean.TRUE); + } + + @Override + public HighlightsSequence getHighlights(int startOffset, int endOffset) { + synchronized (this) { + if (cssBackground != null) { + if (hierarchy == null) { + hierarchy = TokenHierarchy.get(document); + if (hierarchy != null) { + hierarchy.addTokenHierarchyListener(WeakListeners.create(TokenHierarchyListener.class, this, hierarchy)); + } + } + + if (hierarchy != null) { + return new Highlights(version, hierarchy, startOffset, endOffset); + } + } + return HighlightsSequence.EMPTY; + } + } + + // ---------------------------------------------------------------------- + // TokenHierarchyListener implementation + // ---------------------------------------------------------------------- + + @Override + public void tokenHierarchyChanged(TokenHierarchyEvent evt) { + synchronized (this) { + version++; + } + + fireHighlightsChange(evt.affectedStartOffset(), evt.affectedEndOffset()); + } + + // ---------------------------------------------------------------------- + // Private implementation + // ---------------------------------------------------------------------- + + private static Color getColoring(FontColorSettings fcs, String tokenName) { + AttributeSet as = fcs.getTokenFontColors(tokenName); + if (as != null) { + return (Color) as.getAttribute(StyleConstants.Background); //NOI18N + } + return null; + } + + private class Highlights implements HighlightsSequence { + + private final long version; + private final TokenHierarchy scanner; + private final int startOffsetBoundary; + private final int endOffsetBoundary; + + private List> tokenSequenceList = null; + private int startOffset; + private int endOffset; + private int realEndOffset; + private AttributeSet attributeSet; + private boolean finished = false; + + private Highlights(long version, TokenHierarchy scanner, int startOffset, int endOffset) { + this.version = version; + this.scanner = scanner; + this.startOffsetBoundary = startOffset; + this.endOffsetBoundary = endOffset; + } + + private boolean _moveNext() { + if (tokenSequenceList == null) { + // initialize + this.startOffset = startOffsetBoundary; + this.endOffset = startOffsetBoundary; + this.realEndOffset = startOffsetBoundary; + + String mimeType = (String) document.getProperty ("mimeType"); //NOI18N + Language language = Language.find(mimeType); + if (language != null) { + //get php token sequence list + LanguagePath topLevelLanguagePath = LanguagePath.get(language); + if (mimeType.equals(PHP_MIME_TYPE)) { + tokenSequenceList = scanner.tokenSequenceList(topLevelLanguagePath, startOffsetBoundary, endOffsetBoundary); + } + } else { + LOG.log(Level.WARNING, "Language " + mimeType + " obtained from the document mimeType property cannot be found!"); //NOI18N + } + } + + if (tokenSequenceList != null) { + for (TokenSequence tokenSequence : tokenSequenceList) { + assert tokenSequence.language().mimeType().equals(PHP_MIME_TYPE); + tokenSequence.move(realEndOffset); + while (tokenSequence.moveNext() && tokenSequence.offset() < endOffsetBoundary) { + TokenSequence eTokenSequence = tokenSequence.embedded(); + + if (eTokenSequence == null || !eTokenSequence.moveNext()) { + continue; + } + + String embeddedMimeType = eTokenSequence.language().mimeType(); + if ((CSS_MIME_TYPE).equals(embeddedMimeType)) { + eTokenSequence.move(realEndOffset); + if(eTokenSequence.moveNext()) { + startOffset = eTokenSequence.offset(); + do { + endOffset = eTokenSequence.offset() + eTokenSequence.token().length(); + } while (eTokenSequence.moveNext()); + realEndOffset = endOffset > realEndOffset ? endOffset : realEndOffset + 1; + + attributeSet = cssBackground; + if (attributeSet != null) { + return true; + } + } + } + } + attributeSet = cssBackground; + if (attributeSet != null) { + return true; + } + } + } + + return false; + } + + @Override + public boolean moveNext() { + synchronized (CssEmbeddingHighlightsContainer.this) { + if (checkVersion()) { + if (_moveNext()) { + return true; + } + } + } + + finished = true; + return false; + } + + @Override + public int getStartOffset() { + synchronized (CssEmbeddingHighlightsContainer.this) { + if (finished) { + throw new NoSuchElementException(); + } else { + assert tokenSequenceList != null : "Sequence not initialized, call moveNext() first."; //NOI18N + return startOffset; + } + } + } + + @Override + public int getEndOffset() { + synchronized (CssEmbeddingHighlightsContainer.this) { + if (finished) { + throw new NoSuchElementException(); + } else { + assert tokenSequenceList != null : "Sequence not initialized, call moveNext() first."; //NOI18N + return endOffset; + } + } + } + + @Override + public AttributeSet getAttributes() { + synchronized (CssEmbeddingHighlightsContainer.this) { + if (finished) { + throw new NoSuchElementException(); + } else { + assert tokenSequenceList != null : "Sequence not initialized, call moveNext() first."; //NOI18N + return attributeSet; + } + } + } + + private boolean checkVersion() { + return this.version == CssEmbeddingHighlightsContainer.this.version; + } + } +} diff --git a/php/php.editor/src/org/netbeans/modules/php/editor/embedding/CssEmbeddingProvider.java b/php/php.editor/src/org/netbeans/modules/php/editor/embedding/CssEmbeddingProvider.java new file mode 100644 index 000000000000..a5b14b280f12 --- /dev/null +++ b/php/php.editor/src/org/netbeans/modules/php/editor/embedding/CssEmbeddingProvider.java @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.php.editor.embedding; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.netbeans.api.lexer.Token; +import org.netbeans.api.lexer.TokenHierarchy; +import org.netbeans.api.lexer.TokenId; +import org.netbeans.api.lexer.TokenSequence; +import org.netbeans.modules.parsing.api.Embedding; +import org.netbeans.modules.parsing.api.Snapshot; +import org.netbeans.modules.parsing.spi.EmbeddingProvider; +import static org.netbeans.modules.php.api.util.FileUtils.PHP_MIME_TYPE; +import static org.netbeans.modules.php.editor.embedding.CssEmbeddingProvider.TARGET_MIME_TYPE; +import static org.netbeans.modules.php.editor.lexer.PHPTokenId.T_EMBEDDED_CSS; + +/** + * This class is a copy of the {@link org.netbeans.modules.javascript2.vue.editor.embedding.VueCssEmbeddingProvider} + * with minor changes + */ +@EmbeddingProvider.Registration( + mimeType = PHP_MIME_TYPE, + targetMimeType = TARGET_MIME_TYPE) +public class CssEmbeddingProvider extends EmbeddingProvider { + + public static final String TARGET_MIME_TYPE = "text/css"; //NOI18N + + private volatile boolean cancelled = true; + + @Override + public List getEmbeddings(Snapshot snapshot) { + cancelled = false; + TokenHierarchy tokenHierarchy = snapshot.getTokenHierarchy(); + TokenSequence ts = tokenHierarchy.tokenSequence(); + + if (ts == null || !ts.isValid()) { + return Collections.emptyList(); + } + + ts.moveStart(); + + List embeddings = new ArrayList<>(); + + while (ts.moveNext()) { + if (cancelled) { + embeddings.clear(); + break; + } + Token token = ts.token(); + TokenId id = token.id(); + if (id.equals(T_EMBEDDED_CSS)) { + embeddings.add(snapshot.create(ts.offset(), token.length(), TARGET_MIME_TYPE)); + } + } + + if (embeddings.isEmpty()) { + return Collections.emptyList(); + } + return Collections.singletonList(Embedding.create(embeddings)); + } + + @Override + public int getPriority() { + return 200; + } + + @Override + public void cancel() { + cancelled = true; + } +} diff --git a/php/php.editor/src/org/netbeans/modules/php/editor/embedding/EmbeddingHighlightsLayerFactory.java b/php/php.editor/src/org/netbeans/modules/php/editor/embedding/EmbeddingHighlightsLayerFactory.java new file mode 100644 index 000000000000..7278d661a0b6 --- /dev/null +++ b/php/php.editor/src/org/netbeans/modules/php/editor/embedding/EmbeddingHighlightsLayerFactory.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.netbeans.modules.php.editor.embedding; + +import org.netbeans.spi.editor.highlighting.HighlightsLayer; +import org.netbeans.spi.editor.highlighting.HighlightsLayerFactory; +import org.netbeans.spi.editor.highlighting.ZOrder; + +/** + * This class is a copy of the {@link org.netbeans.modules.html.editor.coloring.EmbeddingHighlightsLayerFactory} + * with minor changes + */ +public class EmbeddingHighlightsLayerFactory implements HighlightsLayerFactory { + + @Override + public HighlightsLayer[] createLayers(Context context) { + return new HighlightsLayer[]{HighlightsLayer.create("css-php-embedding-highlight-layer", + ZOrder.BOTTOM_RACK.forPosition(200), //we need to have lower priority than the default syntax from options - 0 + true, + new CssEmbeddingHighlightsContainer(context.getDocument()))}; //NOI18N + } + +} diff --git a/php/php.editor/src/org/netbeans/modules/php/editor/lexer/GSFPHPLexer.java b/php/php.editor/src/org/netbeans/modules/php/editor/lexer/GSFPHPLexer.java index a938fbf239d1..36bc843d0909 100644 --- a/php/php.editor/src/org/netbeans/modules/php/editor/lexer/GSFPHPLexer.java +++ b/php/php.editor/src/org/netbeans/modules/php/editor/lexer/GSFPHPLexer.java @@ -65,6 +65,12 @@ public Token nextToken() { PHPTokenId tokenId = scanner.nextToken(); Token token = null; if (tokenId != null) { + if (tokenId == PHPTokenId.PHP_CONSTANT_ENCAPSED_STRING) { + PHP5ColoringLexer.LexerState state = scanner.getState(); + if (state.heredoc != null && state.heredoc.equals("CSS")) { + tokenId = PHPTokenId.T_EMBEDDED_CSS; + } + } token = tokenFactory.createToken(tokenId); } return token; diff --git a/php/php.editor/src/org/netbeans/modules/php/editor/lexer/PHPTokenId.java b/php/php.editor/src/org/netbeans/modules/php/editor/lexer/PHPTokenId.java index 14c8356e0fd9..ce95be4eb1b8 100644 --- a/php/php.editor/src/org/netbeans/modules/php/editor/lexer/PHPTokenId.java +++ b/php/php.editor/src/org/netbeans/modules/php/editor/lexer/PHPTokenId.java @@ -41,6 +41,7 @@ public enum PHPTokenId implements TokenId { T_INLINE_HTML(null, "php"), // NOI18N + T_EMBEDDED_CSS(null, "php"), // NOI18N PHP_OPENTAG(null, "phpopenclose"), //NOI18N T_OPEN_TAG_WITH_ECHO(null, "phpopenclose"), PHP_CLOSETAG(null, "phpopenclose"), //NOI18N @@ -237,6 +238,11 @@ protected LanguageEmbedding embedding(Token token, return LanguageEmbedding.create(HTMLTokenId.language(), 0, 0, true); } else if (id == PHPDOC_COMMENT) { return LanguageEmbedding.create(PHPDocCommentTokenId.language(), 0, 0); + } else if (id == T_EMBEDDED_CSS) { + Language jsLanguage = Language.find("text/css"); + if (jsLanguage != null) { + return LanguageEmbedding.create(jsLanguage, 0, 0, true); + } } return null; // No embedding diff --git a/php/php.editor/src/org/netbeans/modules/php/editor/resources/Bundle.properties b/php/php.editor/src/org/netbeans/modules/php/editor/resources/Bundle.properties index ab10fc5075b1..1affca6ecc06 100644 --- a/php/php.editor/src/org/netbeans/modules/php/editor/resources/Bundle.properties +++ b/php/php.editor/src/org/netbeans/modules/php/editor/resources/Bundle.properties @@ -49,6 +49,7 @@ constant=Magic Constants heredocdelimiter=HereDoc Delimiter number=Number htmltag=HTML Tag +css-embedding=CSS Embedded in heredoc or nowdoc mod-unused=Unused Element mod-field=Field diff --git a/php/php.editor/src/org/netbeans/modules/php/editor/resources/fontsColors.xml b/php/php.editor/src/org/netbeans/modules/php/editor/resources/fontsColors.xml index fb0698b5bbc1..f4a3adf4a711 100644 --- a/php/php.editor/src/org/netbeans/modules/php/editor/resources/fontsColors.xml +++ b/php/php.editor/src/org/netbeans/modules/php/editor/resources/fontsColors.xml @@ -70,4 +70,7 @@ + + + diff --git a/php/php.editor/src/org/netbeans/modules/php/editor/resources/layer.xml b/php/php.editor/src/org/netbeans/modules/php/editor/resources/layer.xml index 54978d485c2e..af339d70c661 100644 --- a/php/php.editor/src/org/netbeans/modules/php/editor/resources/layer.xml +++ b/php/php.editor/src/org/netbeans/modules/php/editor/resources/layer.xml @@ -66,6 +66,9 @@ + + + diff --git a/php/php.editor/test/unit/data/testfiles/embedding/css_embedding_01.php b/php/php.editor/test/unit/data/testfiles/embedding/css_embedding_01.php new file mode 100644 index 000000000000..38255f6a4347 --- /dev/null +++ b/php/php.editor/test/unit/data/testfiles/embedding/css_embedding_01.php @@ -0,0 +1,21 @@ + + + diff --git a/php/php.editor/test/unit/data/testfiles/embedding/css_embedding_01.php.testCssEmbedding_01.embedding b/php/php.editor/test/unit/data/testfiles/embedding/css_embedding_01.php.testCssEmbedding_01.embedding new file mode 100644 index 000000000000..26216d32f34f --- /dev/null +++ b/php/php.editor/test/unit/data/testfiles/embedding/css_embedding_01.php.testCssEmbedding_01.embedding @@ -0,0 +1,6 @@ + .fa-4x { + font-size: 4em; + } + .fa-4x { + font-size: 4em; + } diff --git a/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/embedding/CssEmbeddingProviderTest.java b/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/embedding/CssEmbeddingProviderTest.java new file mode 100644 index 000000000000..dff82947acbf --- /dev/null +++ b/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/embedding/CssEmbeddingProviderTest.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.php.editor.embedding; + + +public class CssEmbeddingProviderTest extends EmbeddingTestBase { + + public CssEmbeddingProviderTest(String testName) { + super(testName); + } + + private void checkCssEmbedding(final String relFilePath) throws Exception { + checkEmbedding(relFilePath, new CssEmbeddingProvider()); + } + + public void testCssEmbedding_01() throws Exception { + checkCssEmbedding("css_embedding_01"); + } + +} diff --git a/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/embedding/EmbeddingTestBase.java b/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/embedding/EmbeddingTestBase.java new file mode 100644 index 000000000000..6df01cc90678 --- /dev/null +++ b/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/embedding/EmbeddingTestBase.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.php.editor.embedding; + +import java.util.List; +import static junit.framework.TestCase.assertNotNull; +import org.netbeans.modules.parsing.api.Embedding; +import org.netbeans.modules.parsing.api.Source; +import org.netbeans.modules.parsing.spi.EmbeddingProvider; +import org.netbeans.modules.php.editor.PHPTestBase; + +/** + * This class is a copy of the {@link org.netbeans.modules.javascript2.vue.editor.embedding.EmbeddingTestBase} + * with minor changes + */ +public class EmbeddingTestBase extends PHPTestBase { + + public EmbeddingTestBase(String name) { + super(name); + } + + protected void checkEmbedding(final String relFilePath, EmbeddingProvider embeddingProvider) throws Exception { + assertNotNull(embeddingProvider); + String testedFilePath = "testfiles/embedding/" + relFilePath + ".php"; + Source testSource = getTestSource(getTestFile(testedFilePath)); + List embeddings = embeddingProvider.getEmbeddings(testSource.createSnapshot()); + assertDescriptionMatches(testedFilePath, serializableEmbeddings(embeddings), true, ".embedding"); + } + + protected String serializableEmbeddings(List embeddings) { + StringBuilder sb = new StringBuilder(); + for (Embedding embedding : embeddings) { + sb.append(embedding.getSnapshot().getText()); + } + return sb.toString(); + } +}