content: /*******************************************************************************
   * Copyright (c) 2000, 2015 IBM Corporation and others.
   * All rights reserved. This program and the accompanying materials
   * are made available under the terms of the Eclipse Public License v1.0
   * which accompanies this distribution, and is available at
   * http://www.eclipse.org/legal/epl-v10.html
   *
   * Contributors:
   *     IBM Corporation - initial API and implementation
   *******************************************************************************/
  package org.eclipse.wst.jsdt.internal.ui.infoviews;
  
  import java.io.BufferedReader;
  import java.io.IOException;
  import java.io.InputStreamReader;
  import java.io.Reader;
  import java.io.StringReader;
  import java.net.URL;
  
  import org.eclipse.core.runtime.Assert;
  import org.eclipse.core.runtime.FileLocator;
  import org.eclipse.core.runtime.ListenerList;
  import org.eclipse.core.runtime.Platform;
  import org.eclipse.jface.action.Action;
  import org.eclipse.jface.action.IAction;
  import org.eclipse.jface.dialogs.MessageDialogWithToggle;
  import org.eclipse.jface.preference.IPreferenceStore;
  import org.eclipse.jface.resource.JFaceResources;
  import org.eclipse.jface.text.BadLocationException;
  import org.eclipse.jface.text.BadPartitioningException;
  import org.eclipse.jface.text.DefaultInformationControl;
  import org.eclipse.jface.text.Document;
  import org.eclipse.jface.text.IDocument;
  import org.eclipse.jface.text.IDocumentExtension3;
  import org.eclipse.jface.text.ITextSelection;
  import org.eclipse.jface.text.ITypedRegion;
  import org.eclipse.jface.text.TextPresentation;
  import org.eclipse.jface.text.TextSelection;
  import org.eclipse.jface.text.TextUtilities;
  import org.eclipse.jface.util.IPropertyChangeListener;
  import org.eclipse.jface.util.PropertyChangeEvent;
  import org.eclipse.jface.viewers.ISelection;
  import org.eclipse.jface.viewers.ISelectionChangedListener;
  import org.eclipse.jface.viewers.ISelectionProvider;
  import org.eclipse.jface.viewers.SelectionChangedEvent;
  import org.eclipse.jface.viewers.StructuredSelection;
  import org.eclipse.jface.window.Window;
  import org.eclipse.swt.SWT;
  import org.eclipse.swt.SWTError;
  import org.eclipse.swt.browser.Browser;
  import org.eclipse.swt.custom.StyledText;
  import org.eclipse.swt.events.ControlAdapter;
  import org.eclipse.swt.events.ControlEvent;
  import org.eclipse.swt.events.SelectionAdapter;
  import org.eclipse.swt.events.SelectionEvent;
  import org.eclipse.swt.graphics.Color;
  import org.eclipse.swt.graphics.FontData;
  import org.eclipse.swt.graphics.RGB;
  import org.eclipse.swt.graphics.Rectangle;
  import org.eclipse.swt.widgets.Composite;
  import org.eclipse.swt.widgets.Control;
  import org.eclipse.swt.widgets.Display;
  import org.eclipse.ui.IWorkbenchPart;
  import org.eclipse.ui.PlatformUI;
  import org.eclipse.ui.texteditor.IAbstractTextEditorHelpContextIds;
  import org.eclipse.ui.texteditor.IDocumentProvider;
  import org.eclipse.ui.texteditor.ITextEditor;
  import org.eclipse.wst.jsdt.core.IClassFile;
  import org.eclipse.wst.jsdt.core.IJavaScriptElement;
  import org.eclipse.wst.jsdt.core.IJavaScriptUnit;
  import org.eclipse.wst.jsdt.core.ILocalVariable;
  import org.eclipse.wst.jsdt.core.IMember;
  import org.eclipse.wst.jsdt.core.IOpenable;
  import org.eclipse.wst.jsdt.core.IPackageFragmentRoot;
  import org.eclipse.wst.jsdt.core.JavaScriptModelException;
  import org.eclipse.wst.jsdt.internal.corext.javadoc.JavaDocLocations;
  import org.eclipse.wst.jsdt.internal.ui.IJavaHelpContextIds;
  import org.eclipse.wst.jsdt.internal.ui.JavaScriptPlugin;
  import org.eclipse.wst.jsdt.internal.ui.javaeditor.JavaEditor;
  import org.eclipse.wst.jsdt.internal.ui.text.html.HTMLPrinter;
  import org.eclipse.wst.jsdt.internal.ui.text.html.HTMLTextPresenter;
  import org.eclipse.wst.jsdt.ui.JSdocContentAccess;
  import org.eclipse.wst.jsdt.ui.JavaScriptElementLabels;
  import org.eclipse.wst.jsdt.ui.PreferenceConstants;
  import org.eclipse.wst.jsdt.ui.text.IJavaScriptPartitions;
  import org.osgi.framework.Bundle;
  
  /**
   * View which shows Javadoc for a given Java element.
   *
   * FIXME: As of 3.0 selectAll() and getSelection() is not working
   *			see https://bugs.eclipse.org/bugs/show_bug.cgi?id=63022
   *
   * 
   */
  public class JavadocView extends AbstractInfoView {
  
  	/**
  	 * Preference key for the preference whether to show a dialog
  	 * when the SWT Browser widget is not available.
  	 * 
  	 */
  	private static final String DO_NOT_WARN_PREFERENCE_KEY= "JavadocView.error.doNotWarn"; //$NON-NLS-1$
  	
  	// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=73558
  	private static final boolean WARNING_DIALOG_ENABLED= false;
  
  	/** Flags used to render a label in the text widget. */
  	private static final long LABEL_FLAGS=  JavaScriptElementLabels.ALL_FULLY_QUALIFIED
  		| JavaScriptElementLabels.M_PRE_RETURNTYPE | JavaScriptElementLabels.M_PARAMETER_TYPES | JavaScriptElementLabels.M_PARAMETER_NAMES | JavaScriptElementLabels.M_EXCEPTIONS
  		| JavaScriptElementLabels.F_PRE_TYPE_SIGNATURE | JavaScriptElementLabels.T_TYPE_PARAMETERS;
  
  
  	/** The HTML widget. */
  	private Browser fBrowser;
  	/** The text widget. */
  	private StyledText fText;
  	/** The information presenter. */
  	private DefaultInformationControl.IInformationPresenter fPresenter;
  	/** The text presentation. */
  	private TextPresentation fPresentation= new TextPresentation();
  	/** The select all action */
  	private SelectAllAction fSelectAllAction;
  	/** The style sheet (css) */
  	private static String fgStyleSheet;
  	/**
  	 * <code>true</code> once the style sheet has been loaded.
  	 * 
  	 */
  	private static boolean fgStyleSheetLoaded= false;
  
  	/** The Browser widget */
  	private boolean fIsUsingBrowserWidget;
  
  	private RGB fBackgroundColorRGB;
  	/**
  	 * The font listener.
  	 * 
  	 */
  	private IPropertyChangeListener fFontListener;
  
  	
  	/**
  	 * The Javadoc view's select all action.
  	 */
  	private class SelectAllAction extends Action {
  
  		/** The control. */
  		private Control fControl;
  		/** The selection provider. */
  		private SelectionProvider fSelectionProvider;
  
  		/**
  		 * Creates the action.
  		 *
  		 * @param control the widget
  		 * @param selectionProvider the selection provider
  		 */
  		public SelectAllAction(Control control, SelectionProvider selectionProvider) {
  			super("selectAll"); //$NON-NLS-1$
  
  			Assert.isNotNull(control);
  			Assert.isNotNull(selectionProvider);
  			fControl= control;
  			fSelectionProvider= selectionProvider;
  
  			// FIXME: see https://bugs.eclipse.org/bugs/show_bug.cgi?id=63022
  			setEnabled(!fIsUsingBrowserWidget);
  
  			setText(InfoViewMessages.SelectAllAction_label);
  			setToolTipText(InfoViewMessages.SelectAllAction_tooltip);
  			setDescription(InfoViewMessages.SelectAllAction_description);
  
  			PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IAbstractTextEditorHelpContextIds.SELECT_ALL_ACTION);
  		}
  
  		/**
  		 * Selects all in the view.
  		 */
  		public void run() {
  			if (fControl instanceof StyledText)
  		        ((StyledText)fControl).selectAll();
  			else {
  				// FIXME: see https://bugs.eclipse.org/bugs/show_bug.cgi?id=63022
  //				((Browser)fControl).selectAll();
  				if (fSelectionProvider != null)
  					fSelectionProvider.fireSelectionChanged();
  			}
  		}
  	}
  
  	/**
  	 * The Javadoc view's selection provider.
  	 */
  	private static class SelectionProvider implements ISelectionProvider {
  
  		/** The selection changed listeners. */
  		private ListenerList fListeners= new ListenerList(ListenerList.IDENTITY);
  		/** The widget. */
  		private Control fControl;
  
  		/**
  		 * Creates a new selection provider.
  		 *
  		 * @param control	the widget
  		 */
  		public SelectionProvider(Control control) {
  		    Assert.isNotNull(control);
  			fControl= control;
  			if (fControl instanceof StyledText) {
  			    ((StyledText)fControl).addSelectionListener(new SelectionAdapter() {
  					public void widgetSelected(SelectionEvent e) {
  					    fireSelectionChanged();
  					}
  			    });
  			} else {
  				// FIXME: see https://bugs.eclipse.org/bugs/show_bug.cgi?id=63022
  //				((Browser)fControl).addSelectionListener(new SelectionAdapter() {
  //					public void widgetSelected(SelectionEvent e) {
  //						fireSelectionChanged();
  //					}
  //				});
  			}
  		}
  
  		/**
  		 * Sends a selection changed event to all listeners.
  		 */
  		public void fireSelectionChanged() {
  			ISelection selection= getSelection();
  			SelectionChangedEvent event= new SelectionChangedEvent(this, selection);
  			Object[] selectionChangedListeners= fListeners.getListeners();
  			for (int i= 0; i < selectionChangedListeners.length; i++)
  				((ISelectionChangedListener)selectionChangedListeners[i]).selectionChanged(event);
  		}
  
  		/*
  		 * @see org.eclipse.jface.viewers.ISelectionProvider#addSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
  		 */
  		public void addSelectionChangedListener(ISelectionChangedListener listener) {
  			fListeners.add(listener);
  		}
  
  		/*
  		 * @see org.eclipse.jface.viewers.ISelectionProvider#getSelection()
  		 */
  		public ISelection getSelection() {
  			if (fControl instanceof StyledText) {
  				IDocument document= new Document(((StyledText)fControl).getSelectionText());
  				return new TextSelection(document, 0, document.getLength());
  			} else {
  				// FIXME: see https://bugs.eclipse.org/bugs/show_bug.cgi?id=63022
  				return StructuredSelection.EMPTY;
  			}
  		}
  
  		/*
  		 * @see org.eclipse.jface.viewers.ISelectionProvider#removeSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
  		 */
  		public void removeSelectionChangedListener(ISelectionChangedListener listener) {
  			fListeners.remove(listener);
  		}
  
  		/*
  		 * @see org.eclipse.jface.viewers.ISelectionProvider#setSelection(org.eclipse.jface.viewers.ISelection)
  		 */
  		public void setSelection(ISelection selection) {
  			// not supported
  		}
  	}
  
  	/*
  	 * @see AbstractInfoView#internalCreatePartControl(Composite)
  	 */
  	protected void internalCreatePartControl(Composite parent) {
  		try {
  			fBrowser= new Browser(parent, SWT.NONE);
  			fIsUsingBrowserWidget= true;
  			
  		} catch (SWTError er) {
  
  			/* The Browser widget throws an SWTError if it fails to
  			 * instantiate properly. Application code should catch
  			 * this SWTError and disable any feature requiring the
  			 * Browser widget.
  			 * Platform requirements for the SWT Browser widget are available
  			 * from the SWT FAQ web site.
  			 */
  
  			IPreferenceStore store= JavaScriptPlugin.getDefault().getPreferenceStore();
  			boolean doNotWarn= store.getBoolean(DO_NOT_WARN_PREFERENCE_KEY);
  			if (WARNING_DIALOG_ENABLED && !doNotWarn) {
  				String title= InfoViewMessages.JavadocView_error_noBrowser_title;
  				String message= InfoViewMessages.JavadocView_error_noBrowser_message;
  				String toggleMessage= InfoViewMessages.JavadocView_error_noBrowser_doNotWarn;
  				MessageDialogWithToggle dialog= MessageDialogWithToggle.openError(parent.getShell(), title, message, toggleMessage, false, null, null); 
  				if (dialog.getReturnCode() == Window.OK)
  					store.setValue(DO_NOT_WARN_PREFERENCE_KEY, dialog.getToggleState());
  			}
  
  			fIsUsingBrowserWidget= false;
  		}
  
  		if (!fIsUsingBrowserWidget) {
  			fText= new StyledText(parent, SWT.V_SCROLL | SWT.H_SCROLL);
  			fText.setEditable(false);
  			fPresenter= new HTMLTextPresenter(false);
  
  			fText.addControlListener(new ControlAdapter() {
  				/*
  				 * @see org.eclipse.swt.events.ControlAdapter#controlResized(org.eclipse.swt.events.ControlEvent)
  				 */
  				public void controlResized(ControlEvent e) {
  					setInput(fText.getText());
  				}
  			});
  		}
  
  		initStyleSheet();
  		listenForFontChanges();
  		getViewSite().setSelectionProvider(new SelectionProvider(getControl()));
  	}
  
  	/**
  	 * Registers a listener for the Java editor font.
  	 * 
  	 * 
  	 */
  	private void listenForFontChanges() {
  		fFontListener= new IPropertyChangeListener() {
  			public void propertyChange(PropertyChangeEvent event) {
  				if (PreferenceConstants.APPEARANCE_JAVADOC_FONT.equals(event.getProperty())) {
  					fgStyleSheetLoaded= false;
  					// trigger reloading, but make sure other listeners have already run, so that
  					// the style sheet gets reloaded only once.
  					final Display display= getSite().getPage().getWorkbenchWindow().getWorkbench().getDisplay();
  					if (!display.isDisposed()) {
  						display.asyncExec(new Runnable() {
  							public void run() {
  								if (!display.isDisposed()) {
  									initStyleSheet();
  									refresh();
  								}
  							}
  						});
  					}
  				}
  			}
  		};
  		JFaceResources.getFontRegistry().addListener(fFontListener);
  	}
  	
  	private static void initStyleSheet() {
  		if (fgStyleSheetLoaded)
  			return;
  		fgStyleSheetLoaded= true;
  		fgStyleSheet= loadStyleSheet();
  	}
  	
  	private static String loadStyleSheet() {
  		Bundle bundle= Platform.getBundle(JavaScriptPlugin.getPluginId());
  		URL styleSheetURL= bundle.getEntry("/JavadocViewStyleSheet.css"); //$NON-NLS-1$
  		if (styleSheetURL == null)
  			return null;
  
  		try {
  			styleSheetURL= FileLocator.toFileURL(styleSheetURL);
  			StringBuffer buffer= new StringBuffer(200);
  			BufferedReader reader= new BufferedReader(new InputStreamReader(styleSheetURL.openStream()));
  			try {
  				String line= reader.readLine();
  				while (line != null) {
  					buffer.append(line);
  					buffer.append('\n');
  					line= reader.readLine();
  				}
  			} finally {
  				reader.close();
  			}
  			FontData fontData= JFaceResources.getFontRegistry().getFontData(PreferenceConstants.APPEARANCE_JAVADOC_FONT)[0];
  			return HTMLPrinter.convertTopLevelFont(buffer.toString(), fontData);
  		} catch (IOException ex) {
  			JavaScriptPlugin.log(ex);
  			return null;
  		}
  	}
  
  	/*
  	 * @see AbstractInfoView#createActions()
  	 */
  	protected void createActions() {
  		super.createActions();
  		fSelectAllAction= new SelectAllAction(getControl(), (SelectionProvider)getSelectionProvider());
  	}
  
  
  	/*
  	 * @see org.eclipse.wst.jsdt.internal.ui.infoviews.AbstractInfoView#getSelectAllAction()
  	 * 
  	 */
  	protected IAction getSelectAllAction() {
  		// FIXME: see https://bugs.eclipse.org/bugs/show_bug.cgi?id=63022
  		if (fIsUsingBrowserWidget)
  			return null;
  
  		return fSelectAllAction;
  	}
  
  	/*
  	 * @see org.eclipse.wst.jsdt.internal.ui.infoviews.AbstractInfoView#getCopyToClipboardAction()
  	 * 
  	 */
  	protected IAction getCopyToClipboardAction() {
  		// FIXME: see https://bugs.eclipse.org/bugs/show_bug.cgi?id=63022
  		if (fIsUsingBrowserWidget)
  			return null;
  
  		return super.getCopyToClipboardAction();
  	}
  
  	/*
   	 * @see AbstractInfoView#setForeground(Color)
   	 */
  	protected void setForeground(Color color) {
  		getControl().setForeground(color);
  	}
  
  	/*
  	 * @see AbstractInfoView#setBackground(Color)
  	 */
  	protected void setBackground(Color color) {
  		getControl().setBackground(color);
  		fBackgroundColorRGB= color.getRGB();
  		refresh();
  	}
  
  	/**
  	 * Refreshes the view.
  	 *
  	 * 
  	 */
  	private void refresh() {
  		IJavaScriptElement input= getInput();
  		if (input == null) {
  			StringBuffer buffer= new StringBuffer(""); //$NON-NLS-1$
  			HTMLPrinter.insertPageProlog(buffer, 0, fBackgroundColorRGB, fgStyleSheet);
  			setInput(buffer.toString());
  		} else {
  			setInput(computeInput(input));
  		}
  	}
  	
  	/*
  	 * @see org.eclipse.wst.jsdt.internal.ui.infoviews.AbstractInfoView#getBackgroundColorKey()
  	 * 
  	 */
  	protected String getBackgroundColorKey() {
  		return "org.eclipse.wst.jsdt.ui.JavadocView.backgroundColor";		 //$NON-NLS-1$
  	}
  
  	/*
  	 * @see AbstractInfoView#internalDispose()
  	 */
  	protected void internalDispose() {
  		fText= null;
  		fBrowser= null;
  		if (fFontListener != null) {
  			JFaceResources.getFontRegistry().removeListener(fFontListener);
  			fFontListener= null;
  		}
  	}
  
  	/*
  	 * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
  	 */
  	public void setFocus() {
  		getControl().setFocus();
  	}
  
  	/*
  	 * @see AbstractInfoView#computeInput(Object)
  	 */
  	protected Object computeInput(Object input) {
  		if (getControl() == null || ! (input instanceof IJavaScriptElement))
  			return null;
  
  		IJavaScriptElement je= (IJavaScriptElement)input;
  		String javadocHtml;
  
  		switch (je.getElementType()) {
  			case IJavaScriptElement.JAVASCRIPT_UNIT:
  				try {
  					javadocHtml= getJavadocHtml(((IJavaScriptUnit)je).getTypes());
  				} catch (JavaScriptModelException ex) {
  					javadocHtml= null;
  				}
  				break;
  			case IJavaScriptElement.CLASS_FILE:
  				javadocHtml= getJavadocHtml(new IJavaScriptElement[] {((IClassFile)je).getType()});
  				break;
  			default:
  				javadocHtml= getJavadocHtml(new IJavaScriptElement[] { je });
  		}
  		
  		if (javadocHtml == null)
  			return ""; //$NON-NLS-1$
  		
  		return javadocHtml;
  	}
  
  	/*
  	 * @see AbstractInfoView#setInput(Object)
  	 */
  	protected void setInput(Object input) {
  		String javadocHtml= (String)input;
  
  		if (fIsUsingBrowserWidget) {
  			if (javadocHtml != null && javadocHtml.length() > 0) {
  				boolean RTL= (getSite().getShell().getStyle() & SWT.RIGHT_TO_LEFT) != 0;
  				if (RTL) {
  					StringBuffer buffer= new StringBuffer(javadocHtml);
  					HTMLPrinter.insertStyles(buffer, new String[] { "direction:rtl" } ); //$NON-NLS-1$
  					javadocHtml= buffer.toString();
  				}
  			}
  			fBrowser.setText(javadocHtml);
  		} else {
  			fPresentation.clear();
  			Rectangle size=  fText.getClientArea();
  
  			try {
  				javadocHtml= ((DefaultInformationControl.IInformationPresenterExtension)fPresenter).updatePresentation(getSite().getShell(), javadocHtml, fPresentation, size.width, size.height);
  			} catch (IllegalArgumentException ex) {
  				// the javadoc might no longer be valid
  				return;
  			}
  			fText.setText(javadocHtml);
  			TextPresentation.applyTextPresentation(fPresentation, fText);
  		}
  	}
  	
  	/**
  	 * Returns the Javadoc in HTML format.
  	 *
  	 * @param result the Java elements for which to get the Javadoc
  	 * @return a string with the Javadoc in HTML format.
  	 */
  	private String getJavadocHtml(IJavaScriptElement[] result) {
  		StringBuffer buffer= new StringBuffer();
  		int nResults= result.length;
  
  		if (nResults == 0)
  			return null;
  
  		if (nResults > 1) {
  
  			for (int i= 0; i < result.length; i++) {
  				HTMLPrinter.startBulletList(buffer);
  				IJavaScriptElement curr= result[i];
  				if (curr instanceof IMember)
  					HTMLPrinter.addBullet(buffer, getInfoText((IMember) curr));
  				HTMLPrinter.endBulletList(buffer);
  			}
  
  		} else {
  
  			IJavaScriptElement curr= result[0];
  			if (curr instanceof IMember) {
  				IMember member= (IMember) curr;
  //				HTMLPrinter.addSmallHeader(buffer, getInfoText(member));
  				Reader reader;
  				try {
  					reader= JSdocContentAccess.getHTMLContentReader(member, true, true);
  					
  					// Provide hint why there's no Javadoc
  					if (reader == null && member.isBinary()) {
  						boolean hasAttachedJavadoc= JavaDocLocations.getJavadocBaseLocation(member) != null;
  						IPackageFragmentRoot root= (IPackageFragmentRoot)member.getAncestor(IJavaScriptElement.PACKAGE_FRAGMENT_ROOT);
  						boolean hasAttachedSource= root != null && root.getSourceAttachmentPath() != null;
  						IOpenable openable= member.getOpenable();
  						boolean hasSource= openable.getBuffer() != null;
  						
  						if (!hasAttachedSource && !hasAttachedJavadoc)
  							reader= new StringReader(InfoViewMessages.JavadocView_noAttachments);
  						else if (!hasAttachedJavadoc && !hasSource)
  							reader= new StringReader(InfoViewMessages.JavadocView_noAttachedJavadoc);
  						else if (!hasAttachedSource)
  							reader= new StringReader(InfoViewMessages.JavadocView_noAttachedSource);
  						else if (!hasSource)
  							reader= new StringReader(InfoViewMessages.JavadocView_noInformation);
  					}
  					
  				} catch (JavaScriptModelException ex) {
  					reader= new StringReader(InfoViewMessages.JavadocView_error_gettingJavadoc);
  					JavaScriptPlugin.log(ex.getStatus());
  				}
  				if (reader != null) {
  					HTMLPrinter.addParagraph(buffer, reader);
  				}
  			} else if (curr != null && curr.getElementType() == IJavaScriptElement.LOCAL_VARIABLE) {
  				Reader reader = null;
  				try {
  					reader= JSdocContentAccess.getHTMLContentReader((ILocalVariable)curr, false, true);
  				}
  				catch (JavaScriptModelException e) {
  					reader= new StringReader(InfoViewMessages.JavadocView_error_gettingJavadoc);
  					JavaScriptPlugin.log(e.getStatus());
  				}
  				if (reader != null) {
  					HTMLPrinter.addParagraph(buffer, reader);
  				}
  				else {
  					HTMLPrinter.addSmallHeader(buffer, InfoViewMessages.JavadocView_noInformation);
  				}
  			}
  		}
  
  		boolean flushContent= true;
  		if (buffer.length() > 0 || flushContent) {
  			HTMLPrinter.insertPageProlog(buffer, 0, fBackgroundColorRGB, fgStyleSheet);
  			HTMLPrinter.addPageEpilog(buffer);
  			return buffer.toString();
  		}
  
  		return null;
  	}
  
  	/**
  	 * Gets the label for the given member.
  	 *
  	 * @param member the Java member
  	 * @return a string containing the member's label
  	 */
  	private String getInfoText(IMember member) {
  		return JavaScriptElementLabels.getElementLabel(member, LABEL_FLAGS);
  	}
  
  	/*
  	 * @see org.eclipse.wst.jsdt.internal.ui.infoviews.AbstractInfoView#isIgnoringNewInput(org.eclipse.wst.jsdt.core.IJavaScriptElement, org.eclipse.jface.viewers.ISelection)
  	 * 
  	 */
  	protected boolean isIgnoringNewInput(IJavaScriptElement je, IWorkbenchPart part, ISelection selection) {
  		if (super.isIgnoringNewInput(je, part, selection)
  				&& part instanceof ITextEditor
  				&& selection instanceof ITextSelection) {
  			
  			ITextEditor editor= (ITextEditor)part;
  			IDocumentProvider docProvider= editor.getDocumentProvider();
  			if (docProvider == null)
  				return false;
  			
  			IDocument document= docProvider.getDocument(editor.getEditorInput());
  			if (!(document instanceof IDocumentExtension3))
  				return false;
  			
  			try {
  				int offset= ((ITextSelection)selection).getOffset();
  				String partition= ((IDocumentExtension3)document).getContentType(IJavaScriptPartitions.JAVA_PARTITIONING, offset, false);
  				return  partition != IJavaScriptPartitions.JAVA_DOC;
  			} catch (BadPartitioningException ex) {
  				return false;
  			} catch (BadLocationException ex) {
  				return false;
  			}
  
  		}
  		return false;
  	}
  
  	/*
  	 * @see AbstractInfoView#findSelectedJavaElement(IWorkbenchPart)
  	 */
  	protected IJavaScriptElement findSelectedJavaElement(IWorkbenchPart part, ISelection selection) {
  		IJavaScriptElement element;
  		try {
  			element= super.findSelectedJavaElement(part, selection);
  
  			if (element == null && part instanceof JavaEditor && selection instanceof ITextSelection) {
  
  				JavaEditor editor= (JavaEditor)part;
  				ITextSelection textSelection= (ITextSelection)selection;
  
  				IDocumentProvider documentProvider= editor.getDocumentProvider();
  				if (documentProvider == null)
  					return null;
  
  				IDocument document= documentProvider.getDocument(editor.getEditorInput());
  				if (document == null)
  					return null;
  
  				ITypedRegion typedRegion= TextUtilities.getPartition(document, IJavaScriptPartitions.JAVA_PARTITIONING, textSelection.getOffset(), false);
  				if (IJavaScriptPartitions.JAVA_DOC.equals(typedRegion.getType()))
  					return TextSelectionConverter.getElementAtOffset((JavaEditor)part, textSelection);
  				else
  					return null;
  			} else
  				return element;
  		} catch (JavaScriptModelException e) {
  			return null;
  		} catch (BadLocationException e) {
  			return null;
  		}
  	}
  
  	/*
  	 * @see AbstractInfoView#getControl()
  	 */
  	protected Control getControl() {
  		if (fIsUsingBrowserWidget)
  			return fBrowser;
  		else
  			return fText;
  	}
  
  	/*
  	 * @see org.eclipse.wst.jsdt.internal.ui.infoviews.AbstractInfoView#getHelpContextId()
  	 * 
  	 */
  	protected String getHelpContextId() {
  		return IJavaHelpContextIds.JAVADOC_VIEW;
  	}
  }
  