blob: 79b533e28edeb05ed0f1f9bcfe1ef380b98cde3a [file] [log] [blame]
/*******************************************************************************
* 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;
}
}