blob: 1448cdd500076acdd5a241bf5f5db5e9e1175e69 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2003, 2016 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ui.internal.intro.impl.presentations;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.browser.LocationEvent;
import org.eclipse.swt.browser.LocationListener;
import org.eclipse.ui.internal.intro.impl.model.AbstractIntroPage;
import org.eclipse.ui.internal.intro.impl.model.IntroModelRoot;
import org.eclipse.ui.internal.intro.impl.model.url.IntroURL;
import org.eclipse.ui.internal.intro.impl.model.url.IntroURLParser;
/**
* A Location Listener that knows how to intercept OOBE action URLs. It also
* knows how to update UI navigation hisutory.
*/
public class BrowserIntroPartLocationListener implements LocationListener {
private BrowserIntroPartImplementation implementation;
/**
* Takes the implementation as an input.
*/
public BrowserIntroPartLocationListener(
BrowserIntroPartImplementation implementation) {
this.implementation = implementation;
}
@Override
public void changed(LocationEvent event) {
String url = event.location;
if (url == null)
return;
// guard against unnecessary History updates.
Browser browser = (Browser) event.getSource();
if (browser.getData("navigation") != null //$NON-NLS-1$
&& browser.getData("navigation").equals("true")) //$NON-NLS-1$ //$NON-NLS-2$
return;
IntroModelRoot model = implementation.getModel();
IntroURLParser parser = new IntroURLParser(url);
if (!parser.hasProtocol() || parser.getHost() == null
|| parser.getHost().equals("")) //$NON-NLS-1$
// This will filter out two navigation events fired by the browser
// on a setText. (about:blank and
// res://C:\WINDOWS\System32\shdoclc.dll/navcancl.htm on windows,
// and file:/// on Linux)
return;
if (model.isDynamic()) {
// Update the history even with real URLs. Note that if we have
// multiple embedded URL navigations due to frames, the
// frameNavigation flag filters them. This flag is set here, and is
// cleared by a progress listener, when all the frame navigation is
// completed. We need to update history only in dynamic case. In
// static case, the browser keeps the history.
if (browser.getData("frameNavigation") != null) { //$NON-NLS-1$
// this is at least the second frame navigation, remove last
// history since it was added just as a filler.
if (event.top == false && browser.getData("tempUrl") != null //$NON-NLS-1$
&& browser.getData("tempUrl").equals("true")) { //$NON-NLS-1$ //$NON-NLS-2$
implementation.getHistory().removeLastHistory();
flagRemovedTempUrl();
}
}
if (event.top == true) {
// we are navigating to a regular fully qualified URL. Event.top
// is true.
flagStartOfFrameNavigation();
implementation.updateHistory(url);
}
if (browser.getData("frameNavigation") == null //$NON-NLS-1$
&& event.top == false) {
// a new url navigation that is not in a top frame. It can
// be a navigation url due to frames, it can be due to a true
// single Frame navigation (when you click on a link inside a
// Frame) or it is an embedded Help System topic navigation.
AbstractIntroPage currentPage = model.getCurrentPage();
if (currentPage.isIFramePage()) {
// it is an embedded Help System topic navigation. we are
// navigating to an injected iframe since event.top is
// false. Set the iframe url of the current iframe page, and
// add it
// to history.
currentPage.setIFrameURL(url);
implementation.updateHistory(currentPage);
} else {
flagStartOfFrameNavigation();
flagStoredTempUrl();
implementation.updateHistory(url);
}
}
}
return;
}
/**
* Intercept any LocationEvents on the browser. If the event location is a
* valid IntroURL, cancel the event and execute the intro action that is
* embedded in the URL
*/
@Override
public void changing(LocationEvent event) {
String url = event.location;
if (url == null)
return;
IntroModelRoot model = implementation.getModel();
IntroURLParser parser = new IntroURLParser(url);
if (parser.hasIntroUrl()) {
// stop URL first.
event.doit = false;
// execute the action embedded in the IntroURL
IntroURL introURL = parser.getIntroURL();
introURL.execute();
// In the case of dynamic Intro, guard against extra Frame
// navigations. This can happen in the case of intro injected
// IFrames or Frames included through intro xml content.
// INTRO: user defined iframes in Intro pages are not properly
// supported here, only Help system injected iframes.
if (model.isDynamic()) {
if ((introURL.getParameter(IntroURL.KEY_EMBED_TARGET) != null)
&& introURL.getAction().equals(IntroURL.SHOW_PAGE))
flagStartOfNavigation();
}
return;
}
}
public void flagStartOfFrameNavigation() {
if (implementation.getBrowser().getData("frameNavigation") == null) //$NON-NLS-1$
implementation.getBrowser().setData("frameNavigation", "true"); //$NON-NLS-1$ //$NON-NLS-2$
}
public void flagEndOfFrameNavigation() {
implementation.getBrowser().setData("frameNavigation", null); //$NON-NLS-1$
}
public void flagStartOfNavigation() {
if (implementation.getBrowser().getData("navigation") == null) //$NON-NLS-1$
implementation.getBrowser().setData("navigation", "true"); //$NON-NLS-1$ //$NON-NLS-2$
}
public void flagEndOfNavigation() {
implementation.getBrowser().setData("navigation", null); //$NON-NLS-1$
}
public void flagStoredTempUrl() {
if (implementation.getBrowser().getData("tempUrl") == null) //$NON-NLS-1$
implementation.getBrowser().setData("tempUrl", "true"); //$NON-NLS-1$ //$NON-NLS-2$
}
public void flagRemovedTempUrl() {
implementation.getBrowser().setData("tempUrl", null); //$NON-NLS-1$
}
}