| /******************************************************************************* |
| * Copyright (c) 2010 xored software, Inc. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0. |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * xored software, Inc. - initial API and Implementation (Alex Panchenko) |
| *******************************************************************************/ |
| package org.eclipse.dltk.javascript.internal.ui.text.folding; |
| |
| import java.util.List; |
| |
| import org.eclipse.dltk.javascript.internal.ui.text.JSPartitioningProvider; |
| import org.eclipse.dltk.javascript.ui.text.IJavaScriptPartitions; |
| import org.eclipse.dltk.ui.text.folding.IFoldingBlockKind; |
| import org.eclipse.dltk.ui.text.folding.IFoldingContent; |
| import org.eclipse.dltk.ui.text.folding.PartitioningFoldingBlockProvider; |
| import org.eclipse.jface.text.BadLocationException; |
| import org.eclipse.jface.text.Document; |
| import org.eclipse.jface.text.IDocument; |
| import org.eclipse.jface.text.IRegion; |
| |
| public class JavaScriptCommentFoldingBlockProvider extends |
| PartitioningFoldingBlockProvider { |
| |
| public JavaScriptCommentFoldingBlockProvider() { |
| super(JSPartitioningProvider.getInstance()); |
| } |
| |
| public void computeFoldableBlocks(IFoldingContent content) { |
| if (isFoldingComments()) { |
| computeBlocksForPartitionType(content, |
| IJavaScriptPartitions.JS_SINGLE_LINE_COMMENT, |
| JavaScriptFoldingBlockKind.COMMENT, isCollapseComments()); |
| computeBlocksForPartitionType(content, |
| IJavaScriptPartitions.JS_MULTI_LINE_COMMENT, |
| JavaScriptFoldingBlockKind.COMMENT, isCollapseComments()); |
| } |
| if (isFoldingDocs()) |
| computeBlocksForPartitionType(content, |
| IJavaScriptPartitions.JS_DOC, |
| JavaScriptFoldingBlockKind.JSDOC, isCollapseDocs()); |
| } |
| |
| @Override |
| protected void reportRegions(Document document, List<IRegion> regions, |
| IFoldingBlockKind kind, boolean collapse) |
| throws BadLocationException { |
| if ((kind == JavaScriptFoldingBlockKind.COMMENT || kind == JavaScriptFoldingBlockKind.JSDOC) |
| && collapse != isCollapseHeaderComment() && !regions.isEmpty()) { |
| final IRegion first = regions.get(0); |
| if (first.getOffset() == 0 && isFileHeader(document, first)) { |
| requestor.acceptBlock(first.getOffset(), first.getOffset() |
| + first.getLength(), kind, null /* no element */, |
| isCollapseHeaderComment()); |
| super.reportRegions(document, |
| regions.subList(1, regions.size()), kind, collapse); |
| return; |
| } |
| } |
| super.reportRegions(document, regions, kind, collapse); |
| } |
| |
| private boolean isFileHeader(IDocument document, IRegion region) |
| throws BadLocationException { |
| int endPos = region.getOffset() + region.getLength(); |
| String txtAfterComment = document.get(endPos, |
| Math.min(20, document.getLength() - endPos)); |
| int lineDelimiterCount = 0; |
| for (int i = 0; i < txtAfterComment.length(); i++) { |
| char c = txtAfterComment.charAt(i); |
| if (c == 'f') { |
| if (txtAfterComment.substring(i).startsWith("function")) |
| return false; |
| } else if (c == 'v') { |
| if (txtAfterComment.substring(i).startsWith("var")) |
| return false; |
| } else if (lineDelimiterCount == 1) { |
| // if after 1 line delimiter still no function |
| // or var is found then it is a header. |
| return true; |
| } else if (c == '\n') { |
| lineDelimiterCount++; |
| } else if (c == '\r') { |
| lineDelimiterCount++; |
| if (i + 1 < txtAfterComment.length() |
| && txtAfterComment.charAt(i + 1) == '\n') |
| i++; // skip \r\n |
| } |
| if (lineDelimiterCount == 2) { |
| return true; |
| } |
| } |
| return false; |
| } |
| } |