### Eclipse Workspace Patch 1.0
#P org.jboss.tools.vpe
Index: src/org/jboss/tools/vpe/editor/VpeController.java
===================================================================
--- src/org/jboss/tools/vpe/editor/VpeController.java	(revision 38159)
+++ src/org/jboss/tools/vpe/editor/VpeController.java	(working copy)
@@ -56,6 +56,7 @@
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Event;
 import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.ScrollBar;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.ui.IEditorInput;
 import org.eclipse.ui.IFileEditorInput;
@@ -158,9 +159,12 @@
 import org.mozilla.interfaces.nsIDOMMutationEvent;
 import org.mozilla.interfaces.nsIDOMNSUIEvent;
 import org.mozilla.interfaces.nsIDOMNode;
+import org.mozilla.interfaces.nsIDOMWindow;
+import org.mozilla.interfaces.nsIDOMWindowInternal;
 import org.mozilla.interfaces.nsISelection;
 import org.mozilla.interfaces.nsISelectionDisplay;
 import org.mozilla.interfaces.nsISelectionListener;
+import org.mozilla.interfaces.nsIWebBrowser;
 import org.w3c.dom.Attr;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
@@ -175,6 +179,15 @@
 		MozillaContextMenuListener, MozillaResizeListener,
 		MozillaAfterPaintListener, MozillaScrollListener {
 
+	/*
+	 * https://issues.jboss.org/browse/JBIDE-8701
+	 * Scroll listeners staff.
+	 */
+	private SelectionListener sourceScrollSelectionListener;
+	private ScrollBar sourceEditorVerticalScrollBar;
+	private boolean sourceScrollEventFlag = false;
+	private boolean visualScrollEventFlag = false;
+	
 	public static final int DEFAULT_UPDATE_DELAY_TIME = 400;
 	private boolean visualEditorVisible = true;
 	private boolean synced = true;
@@ -335,12 +348,60 @@
 		// sourceEditor.getViewerSelectionManager();
 		// selectionManager.addNodeSelectionListener(this);
 		// selectionManager.addTextSelectionListener(this);
-		StyledText textWidget = SelectionHelper
-				.getSourceTextWidget(sourceEditor);
+		final StyledText textWidget = SelectionHelper.getSourceTextWidget(sourceEditor);
 		if (textWidget != null) {
 			textWidget.addSelectionListener(this);
 		}
-
+		/*
+		 * https://issues.jboss.org/browse/JBIDE-8701
+		 * Add Source ScrollBar Listener
+		 */
+		if ((visualEditor != null) && (sourceEditor != null)) {
+			sourceEditorVerticalScrollBar = textWidget.getVerticalBar();
+			if (sourceEditorVerticalScrollBar != null) {
+				if (visualEditor.getXulRunnerEditor() != null) {
+					nsIWebBrowser webBrowser = visualEditor.getXulRunnerEditor().getWebBrowser();
+					if (webBrowser != null) {
+						/*
+						 * Initialize mozilla browser content window
+						 */
+						final nsIDOMWindow domWindow = webBrowser.getContentDOMWindow();
+						final nsIDOMWindowInternal windowInternal = org.jboss.tools.vpe.xulrunner.util.XPCOM
+								.queryInterface(domWindow, nsIDOMWindowInternal.class);
+						/*
+						 * Adding source listener
+						 */
+						sourceScrollSelectionListener = new SelectionListener() {
+							@Override
+							public void widgetSelected(SelectionEvent e) {
+								if (!visualScrollEventFlag && !selectionManager.isUpdateSelectionEventPerformed()) { // ignore internal visual scroll event
+									sourceScrollEventFlag = true;
+									ScrollBar sb = (ScrollBar)e.widget;
+									int pageYOffsetSrc = sb.getSelection();
+									int scrollMaxYSrc = sb.getMaximum() - sb.getThumb();
+									float percentsSrc = ((float)pageYOffsetSrc/scrollMaxYSrc);
+									if (windowInternal.getScrollbars().getVisible()) {
+										int scrollMaxYVisual = -1;
+										scrollMaxYVisual = windowInternal.getScrollMaxY();
+										if (scrollMaxYVisual != 0 && scrollMaxYVisual != -1) {
+											// there is a visual scroll bar
+											int posY = ((int) (scrollMaxYVisual*percentsSrc));
+											domWindow.scrollTo(windowInternal.getPageXOffset(),posY);
+										}
+									}
+								} else {
+									visualScrollEventFlag = false;
+									selectionManager.setUpdateSelectionEventFlag(false);
+								}
+							}
+							@Override
+							public void widgetDefaultSelected(SelectionEvent e) { }
+						};
+						sourceEditorVerticalScrollBar.addSelectionListener(sourceScrollSelectionListener);
+					}
+				}
+			}
+		} // End of fix JBIDE-8701
 		registerEventTargets();
 
 		if (optionsListener == null) {
@@ -356,12 +417,10 @@
 		taglibReferenceListListener = TaglibReferenceList.getInstance();
 		taglibReferenceListListener.addChangeListener(this);
 
-		absoluteFolderReferenceListListener = AbsoluteFolderReferenceList
-				.getInstance();
+		absoluteFolderReferenceListListener = AbsoluteFolderReferenceList.getInstance();
 		absoluteFolderReferenceListListener.addChangeListener(this);
 
-		relativeFolderReferenceListListener = RelativeFolderReferenceList
-				.getInstance();
+		relativeFolderReferenceListListener = RelativeFolderReferenceList.getInstance();
 		relativeFolderReferenceListListener.addChangeListener(this);
 
 		elReferenceListListener = ELReferenceList.getInstance();
@@ -376,8 +435,28 @@
 		// JBIDE-4037)
 		sourceSelectionChanged(true);
 		refreshCommands();
+		/*
+		 * Reset the flag, to enable scroll synchronizing right after init
+		 */
+		selectionManager.setUpdateSelectionEventFlag(false);
 	}
 
+	private ScrollBar getSourceEditorVerticalScrollBar() {
+		return sourceEditorVerticalScrollBar;
+	}
+	
+	private void removeSourceScrollListener() {
+		if (sourceEditorVerticalScrollBar != null && sourceScrollSelectionListener != null) {
+			sourceEditorVerticalScrollBar.removeSelectionListener(sourceScrollSelectionListener);
+		}
+	}
+
+	private void addSourceScrollListener() {
+		if (sourceEditorVerticalScrollBar != null && sourceScrollSelectionListener != null) {
+			sourceEditorVerticalScrollBar.addSelectionListener(sourceScrollSelectionListener);
+		}
+	}
+
 	public void dispose() {
 		if (job != null) {
 			job.cancel();
@@ -958,7 +1037,6 @@
 		}
 		onRefresh();
 	}
-
 
 	public boolean isKeyBinding(Event keyboardEvent) {
 		boolean keyBindingPressed = false;
@@ -1007,7 +1085,43 @@
 	}
 	
 	public void editorScrolled(nsIDOMEvent domEvent) {
+		/*
+		 * Redraw selection rectangle
+		 */
 		onRefresh();
+		/*
+		 * https://issues.jboss.org/browse/JBIDE-8701
+		 * Perform visual and source scroll synchronizing.
+		 * The idea of visual scroll listener is to scroll src part when it is required 
+		 * (when src hasn't been scrolled to a proper position).  
+		 */
+		if (!sourceScrollEventFlag && !selectionManager.isUpdateSelectionEventPerformed()) { // ignore internal event from source
+			if (visualEditor.getXulRunnerEditor() != null) {
+				visualScrollEventFlag = true;
+				final nsIWebBrowser webBrowser = visualEditor.getXulRunnerEditor().getWebBrowser();
+				removeSourceScrollListener();
+				final StyledText textWidget = SelectionHelper.getSourceTextWidget(sourceEditor);
+				final nsIDOMWindow domWindow = webBrowser.getContentDOMWindow();
+				nsIDOMWindowInternal windowInternal = org.jboss.tools.vpe.xulrunner.util.XPCOM
+						.queryInterface(domWindow, nsIDOMWindowInternal.class); 
+				int pageYOffsetVisual = windowInternal.getPageYOffset();
+				int scrollMaxYVisual = windowInternal.getScrollMaxY();
+				float percentsVisual = ((float)pageYOffsetVisual/scrollMaxYVisual);
+				ScrollBar sb = getSourceEditorVerticalScrollBar();
+				if ((sb != null) && (sb.getMaximum() != 1)) {
+					int srcLinesCount = textWidget.getLineCount();
+					// there is a source scroll bar
+					if (srcLinesCount != 1) {
+						int posLines = ((int) (srcLinesCount*percentsVisual));
+						textWidget.setTopIndex(posLines);
+					}
+				}
+				addSourceScrollListener();
+			}
+		} else {
+			sourceScrollEventFlag = false;
+			selectionManager.setUpdateSelectionEventFlag(false);
+		} // End of fix JBIDE-8701
 	}
 
 	/**
@@ -1768,10 +1882,8 @@
 
 	public void setZoomEventManager(IZoomEventManager zoomEventManager) {
 		this.zoomEventManager = zoomEventManager;
-	}
+	}
 
-
-
 	public VpeDropWindow getDropWindow() {
 		return dropWindow;
 	}
Index: src/org/jboss/tools/vpe/editor/template/SelectionManager.java
===================================================================
--- src/org/jboss/tools/vpe/editor/template/SelectionManager.java	(revision 38159)
+++ src/org/jboss/tools/vpe/editor/template/SelectionManager.java	(working copy)
@@ -40,6 +40,11 @@
 public class SelectionManager implements ISelectionManager {
 	
 	/**
+	 * Flag indicates that the source and visual selection is updating. 
+	 */
+	public static boolean updateSelectionEventFlag = false;
+	
+	/**
 	 * pageContext keeps information about page
 	 */
 	private VpePageContext pageContext;
@@ -62,7 +67,18 @@
 		this.selectionController = selectionController;
 	}
 
+	@Override
+	public boolean isUpdateSelectionEventPerformed() {
+		return updateSelectionEventFlag;
+	}
+
+	@Override
+	public void setUpdateSelectionEventFlag(boolean isPerforming) {
+		updateSelectionEventFlag = isPerforming;
+	}
+
 	public final void setSelection(nsIDOMNode visualNode, int focusOffset, int anchorOffset) {
+		setUpdateSelectionEventFlag(true);
 		if (visualNode == null) {
 			return;
 		}
@@ -186,6 +202,7 @@
 	 * Selects text in the Visual Part Visual Part according to source selection.
 	 */
 	private void refreshVisualTextSelection() {
+		setUpdateSelectionEventFlag(true);
 		// checks for null, for case when we close editor and background
 		// update job is running
 		if (getSourceEditor().getTextViewer() == null) {
Index: src/org/jboss/tools/vpe/editor/VpeVisualDomBuilder.java
===================================================================
--- src/org/jboss/tools/vpe/editor/VpeVisualDomBuilder.java	(revision 38159)
+++ src/org/jboss/tools/vpe/editor/VpeVisualDomBuilder.java	(working copy)
@@ -529,20 +529,16 @@
 	}
 
 	protected void correctVisualAttribute(nsIDOMElement element) {
-		String styleValue = element.getAttribute(HTML.TAG_STYLE);
-		String backgroundValue = element
-				.getAttribute(VpeStyleUtil.PARAMETR_BACKGROND);
+		String styleValue = element.getAttribute(HTML.ATTR_STYLE);
+		String backgroundValue = element.getAttribute(HTML.ATTR_BACKGROUND);
 		if (styleValue != null) {
-			styleValue = VpeStyleUtil.addFullPathIntoURLValue(styleValue,
-					pageContext);
-			element.setAttribute(HTML.TAG_STYLE, styleValue);
+			styleValue = VpeStyleUtil.addFullPathIntoURLValue(styleValue, pageContext);
+			element.setAttribute(HTML.ATTR_STYLE, styleValue);
 		}
 		if (backgroundValue != null) {
-			backgroundValue = VpeStyleUtil
-					.addFullPathIntoBackgroundValue(backgroundValue,
-							pageContext.getEditPart().getEditorInput());
-			element.setAttribute(VpeStyleUtil.PARAMETR_BACKGROND,
-					backgroundValue);
+			backgroundValue = VpeStyleUtil.addFullPathIntoBackgroundValue(
+					backgroundValue, pageContext.getEditPart().getEditorInput());
+			element.setAttribute(HTML.ATTR_BACKGROUND, backgroundValue);
 		}
 		//fix for jbide-3209		
 		if(element.hasAttribute(HTML.ATTR_DIR)) {
Index: src/org/jboss/tools/vpe/editor/template/ISelectionManager.java
===================================================================
--- src/org/jboss/tools/vpe/editor/template/ISelectionManager.java	(revision 38159)
+++ src/org/jboss/tools/vpe/editor/template/ISelectionManager.java	(working copy)
@@ -32,5 +32,8 @@
 	 * to bring in correspondence visual selection and source selection
 	 */
 	public void refreshVisualSelection();
+	
+	public boolean isUpdateSelectionEventPerformed();
+	public void setUpdateSelectionEventFlag(boolean event);
 
 }
