blob: 8527efbd91f3b255dc5f925abe3d4229cea4e8cc [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2016 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.ui.internal.intro.impl.model;
import java.util.Hashtable;
import java.util.Map;
import java.util.Vector;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.help.internal.UAElement;
import org.eclipse.help.internal.UAElementFactory;
import org.eclipse.help.internal.dynamic.DocumentProcessor;
import org.eclipse.help.internal.dynamic.FilterHandler;
import org.eclipse.help.internal.dynamic.ProcessorHandler;
import org.eclipse.ui.internal.intro.impl.IIntroConstants;
import org.eclipse.ui.internal.intro.impl.model.loader.ExtensionPointManager;
import org.eclipse.ui.internal.intro.impl.model.loader.IntroContentParser;
import org.eclipse.ui.internal.intro.impl.model.loader.ModelLoaderUtil;
import org.eclipse.ui.internal.intro.impl.model.util.BundleUtil;
import org.eclipse.ui.internal.intro.impl.model.util.ModelUtil;
import org.eclipse.ui.internal.intro.impl.util.IntroEvaluationContext;
import org.eclipse.ui.internal.intro.impl.util.Log;
import org.eclipse.ui.internal.intro.impl.util.StringUtil;
import org.osgi.framework.Bundle;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* Base class for all Intro pages, inlcuding HomePage. Adds page specific
* support:
* <ul>
* <li>support for page styles, and style inheritance</li>
* <li>support for XHTML via a DOM instance var. Resolving the page is also
* handled here.</li>
* <li>a pge has the concept of being an IFramePage. This is indicated by the
* isIFrame flag. A page is an IFramePage when it is not defined in any content
* file, but instead is actually created at runtime. This is done to display a
* Help System topic embedded in any given div. The current page is cloned, its
* id is mangled with "_embedDivId", the content of the div pointed to by
* embedDivId is replaced with an IFrame that loads the Help System topic.</li>
* </ul>
*/
public abstract class AbstractIntroPage extends AbstractIntroContainer {
protected static final String TAG_PAGE = "page"; //$NON-NLS-1$
private static final String ATT_STYLE = "style"; //$NON-NLS-1$
private static final String ATT_ALT_STYLE = "alt-style"; //$NON-NLS-1$
private static final String ATT_CONTENT = "content"; //$NON-NLS-1$
private static final String ATT_SHARED_STYLE = "shared-style"; //$NON-NLS-1$
private static final String INVALID_CONTENT = "invalidPage/invalidPage.xhtml"; //$NON-NLS-1$
private static final String INVALID_CONTENT_BASE = "invalidPage"; //$NON-NLS-1$
protected static final String ATT_URL = "url"; //$NON-NLS-1$
private String style;
private String altStyle;
private String sharedStyle;
private IntroPageTitle title;
private String content;
private String url;
// if iframe is not null, this indicates that this page was cloned at
// runtime from another page whose id was "originalId".
private IntroInjectedIFrame iframe;
// id of page from which this page was cloned.
private String originalId;
// DOM representing XHTML content. DOM is only cached in the case of XHTML
// content.
private Document dom;
private DocumentProcessor domProcessor;
// set when the content file is loaded (ie: loadChildren is called)
private boolean isXHTMLPage;
// Model base attribute is stored in parent class. This base attribute here
// is to cache the initial location of the content file. When content
// attribute is defined, the base in the model becomes relative to
// new xml file. However, in the case of XHTML content, and when
// presentation is UI forms, we need to reuse initial content file location.
private String initialBase;
/**
* The vectors to hold all inhertied styles and alt styles from included
* elements. They are lazily created when children are resolved (ie:
* includes are resolved) OR when extensions are resolved and styles need to
* be added to the target page.
* <p>
* Style Rules:
* <ul>
* <li>For includes, merge-style controls wether or not the enclosing page
* inherits the styles of the target.
* <li>If a page is including a shared div, merging target styles into this
* page is ignored. Shared divs do not have styles.</li>
* <li>For extensions, if the style or alt-style is not defined, that means
* that no style inheritence is needed, and the style of the target page are
* not updated.
* <li>If an extension is extending a shared div, merging the styles of
* this extension into the target is ignored. Shared divs do not have
* styles.</li>
* <li>Shared hashtable has alt-styles as keys and bundles as values.</li>
* </ul>
*/
private Vector<String> styles;
private Map<String, Bundle> altStyles;
private boolean isDynamic = false;
protected boolean isStandbyPage;
/**
* Parent class for all pages. Make sure to set the bundle to where the
* pages are loaded from. This means that the bundle for root may be
* different from the bundle for all the other pages. Only pages do this
* logic and so other model objects might have the wrong bundle cached if
* the resource was loaded from an nl directory.
*
* @param element
*/
AbstractIntroPage(Element element, Bundle bundle, String base) {
super(element, bundle, base);
this.initialBase = base;
content = getAttribute(element, ATT_CONTENT);
if (content == null) {
//Delaying init until we have the model
// so that we can resolve theme
//init(element, bundle, base);
}
else {
// Content is not null. Resolve it. Other page attributes (style,
// alt-style...) will be loaded when xml content file is loaded
// since we need to pick them up from external xml content file. In
// the case where this external content file is XHTML and we have
// HTML presentation, page attributes are simply not loaded. In the
// case where we have XHTML in a UI forms presentation, we will need
// to load initial page attributes.
// BASE: since content is being loaded from another xml file, point
// the base of this page to be relative to the new xml file
// location.
IPath subBase = ModelUtil.getParentFolderPath(content);
this.base = new Path(base).append(subBase).toString();
content = BundleUtil.getResolvedResourceLocation(base, content,
bundle);
}
// load shared-style attribure. This is needed in the XML and in the
// XHTML cases. Default is to include shared style.
this.sharedStyle = getAttribute(element, ATT_SHARED_STYLE);
if (sharedStyle == null)
sharedStyle = "true"; //$NON-NLS-1$
url = getAttribute(element, ATT_URL);
if (url == null)
// if we do not have a URL attribute, then we have dynamic content.
isDynamic = true;
else
// check the url/standby-url attributes and update accordingly.
url = ModelUtil.resolveURL(base, url, bundle);
}
@Override
public void setParent(AbstractIntroElement parent) {
super.setParent(parent);
if (content == null)
init(element, getBundle(), initialBase);
}
/**
* Returns unresolved content value as found in the source file.
* the source file.
* @return the unresolved content value
*/
public String getRawContent() {
return getAttribute(element, ATT_CONTENT);
}
/**
* Initialize styles. Take first style in style attribute and make it the
* page style. Then put other styles in styles vectors. Make sure to resolve
* each style.
*
* @param element
* @param bundle
*/
private void init(Element element, Bundle bundle, String base) {
String[] styleValues = getAttributeList(element, ATT_STYLE);
if (styleValues != null && styleValues.length > 0) {
style = styleValues[0];
style = BundleUtil.getResolvedResourceLocation(base, style, bundle);
for (int i = 1; i < styleValues.length; i++) {
String style = styleValues[i];
style = BundleUtil.getResolvedResourceLocation(base, style,
bundle);
addStyle(style);
}
}
String[] altStyleValues = getAttributeList(element, ATT_ALT_STYLE);
if (altStyleValues != null && altStyleValues.length > 0) {
altStyle = altStyleValues[0];
altStyle = BundleUtil.getResolvedResourceLocation(base, altStyle,
bundle);
for (int i = 1; i < altStyleValues.length; i++) {
String style = altStyleValues[i];
style = BundleUtil.getResolvedResourceLocation(base, style,
bundle);
addAltStyle(style, bundle);
}
}
}
/**
* The page's title. Each page can have one title.
*
* @return Returns the title of this page.
*/
public String getTitle() {
// title is a child of the page, and so we have to load children first.
// We also have to resolve children because someone might be including a
// title. Update title instance after all includes and extensions have
// been resolved.
getChildren();
if (title == null) {
// there should only be one title child per page. safe to cast.
IntroPageTitle[] titles = (IntroPageTitle[]) getChildrenOfType(AbstractIntroElement.PAGE_TITLE);
if (titles.length > 0)
title = titles[0];
}
if (title == null)
// still null. no title.
return null;
return title.getTitle();
}
/**
* @return Returns the style.
*/
public String getStyle() {
return style;
}
/**
* @return Returns the alt_style.
*/
public String getAltStyle() {
return altStyle;
}
/**
* Gets all the inherited styles of this page. Styles can be inherited from
* includes or from configExtensions.
* <p>
* Note: this call needs to get all the children of this page, and so it
* will resolve this page. might be expensive.
*
* @return Returns all the inherited styles of this page. Returns an empty
* array if page is not expandable or does not have inherited
* styles.
*/
public String[] getStyles() {
// call get children first to resolve includes and populate styles
// vector. Resolving children will initialize the style vectors.
getChildren();
if (styles == null)
// style vector is still null because page does not have styles.
return new String[0];
String[] stylesArray = new String[styles.size()];
styles.copyInto(stylesArray);
return stylesArray;
}
/**
* Gets all the inherited alt-styles of this page (ie: styles for the SWT
* presentation). A hashtable is returned that has inhertied alt-styles as
* keys, and plugin descriptors as values. This is needed to be able to load
* resources from the inherited target plugin. Note: this call needs to get
* all the children of this page, and so its will resolve this page. might
* be expensive.
*
* @return Returns all the inherited styles of this page. Returns an empty
* hashtable if page is not expandable, does not have any includes,
* or has includes that do not merge styles.
*/
public Map<String, Bundle> getAltStyles() {
// call get children first to resolve includes and populate hashtable.
// Resolving children will initialize the style vectors.
getChildren();
return altStyles;
}
/**
* Adds the given style to the list. Style is not added if it already exists
* in the list.
*
* @param style
*/
protected void addStyle(String style) {
if (!initStyles(style))
return;
if (styles.contains(style))
return;
styles.add(style);
}
public void insertStyle(String style, int location) {
if (!initStyles(style))
return;
if (styles.contains(style))
return;
styles.add(location, style);
}
/**
* Adds the given style to the list.Style is not added if it already exists
* in the list.
*
* @param altStyle
*/
protected void addAltStyle(String altStyle, Bundle bundle) {
if (!initAltStyles(altStyle))
return;
if (altStyles.containsKey(altStyle))
return;
altStyles.put(altStyle, bundle);
}
/**
* Util method to add given styles to the list.
*
*/
protected void addStyles(String[] styles) {
if (styles == null)
return;
for (int i = 0; i < styles.length; i++)
addStyle(styles[i]);
}
/**
* Util method to add map of altstyles to list.
*/
protected void addAltStyles(Map<String, Bundle> altStyles) {
if (altStyles == null)
return;
if (this.altStyles == null)
// delay creation until needed.
this.altStyles = new Hashtable<>();
this.altStyles.putAll(altStyles);
}
private boolean initStyles(String style) {
if (style == null)
return false;
if (this.styles == null)
// delay creation until needed.
this.styles = new Vector<>();
return true;
}
private boolean initAltStyles(String style) {
if (style == null)
return false;
if (this.altStyles == null)
// delay creation until needed.
this.altStyles = new Hashtable<>();
return true;
}
@Override
public int getType() {
return AbstractIntroElement.ABSTRACT_PAGE;
}
/*
* Override parent behavior to lazily initialize styles vectors. This will
* only be called once, if resolved == false. In the case of DOM model,
* resolve this page's full DOM.
*
* @see org.eclipse.ui.internal.intro.impl.model.AbstractIntroContainer#resolveChildren()
*/
@Override
protected void resolveChildren() {
// flag would be set
if (isXHTMLPage)
resolvePage();
else
super.resolveChildren();
}
/**
* Override parent behavior to add support for HEAD & Title element in pages
* only, and not in divs.
*
* @see org.eclipse.ui.internal.intro.impl.model.AbstractIntroContainer#getModelChild(org.eclipse.core.runtime.IConfigurationElement)
*/
@Override
protected AbstractIntroElement getModelChild(Element childElement,
Bundle bundle, String base) {
AbstractIntroElement child = null;
if (childElement.getNodeName().equalsIgnoreCase(IntroHead.TAG_HEAD)) {
child = new IntroHead(childElement, bundle, base);
} else if (childElement.getNodeName().equalsIgnoreCase(
IntroPageTitle.TAG_TITLE)) {
// if we have a title, only add it as a child if we did not load one
// before. A page can only have one title.
if (title == null) {
child = new IntroPageTitle(childElement, bundle);
}
}
if (child != null)
return child;
return super.getModelChild(childElement, bundle, base);
}
/**
* Returns all head contributions in this page. There can be more than one
* head contribution in the page;
*
* @return
*/
public IntroHead[] getHTMLHeads() {
return (IntroHead[]) getChildrenOfType(AbstractIntroElement.HEAD);
}
/**
* load the children of this container. Override parent behavior because we
* want to support loading content from other xml files. The design is that
* only the id and content from the existing page are honored. All other
* attributes are what they are defined in the external paget. For XHTML
* content, all info is in the xhtml page. If we fail to load the page,
* display the Invalid Page page.
*/
@Override
protected void loadChildren() {
if (content == null) {
// no content. do regular loading.
super.loadChildren();
return;
}
// content attribute is defined. It either points to an XHTML file, or
// an introContent.xml file. Process each case. Assume it is an
// introContent file.
// INTRO: XHTML file is loaded needlessly when we have XHTML content and
// SWT presentation.
IntroContentParser parser = new IntroContentParser(content);
Document dom = parser.getDocument();
if (dom == null) {
// bad xml. This could be bad XHTML or bad intro XML. Parser would
// have logged fact. Load dom for invalid page, and make sure to
// force an extract on parent folder to enabling jarring.
Bundle introBundle = Platform.getBundle(IIntroConstants.PLUGIN_ID);
ModelUtil.ensureFileURLsExist(introBundle, INVALID_CONTENT);
String invalidContentFilePath = BundleUtil
.getResolvedResourceLocation(INVALID_CONTENT, introBundle);
parser = new IntroContentParser(invalidContentFilePath);
dom = parser.getDocument();
// make sure to override all attributes to resolve the Invalid
// Page page correctly.
content = invalidContentFilePath;
this.base = INVALID_CONTENT_BASE;
setBundle(introBundle);
}
// parse content depending on type. Make sure to set the loaded flag
// accordingly, otherwise content file will always be parsed.
if (parser.hasXHTMLContent()) {
loadXHTMLContent(dom);
// make sure to use correct base.
init(element, getBundle(), initialBase);
super.loadChildren();
} else
// load the first page with correct id, from content xml file.
loadXMLContent(dom);
}
/**
* Load the xml content from the introContent.xml file pointed to by the
* content attribute, and loaded into the passed DOM. Load the first page
* with correct id from this content file.
*
* @param dom
*/
private void loadXMLContent(Document dom) {
Element[] pages = ModelUtil.getElementsByTagName(dom,
AbstractIntroPage.TAG_PAGE);
if (pages.length == 0) {
Log.warning("Content file has no pages."); //$NON-NLS-1$
return;
}
// point the element of this page to the new element. Pick first page
// with matching id. Make sure to disable loading of children of current
// element if a matching page in the external content file is not found.
boolean foundMatchingPage = false;
for (int i = 0; i < pages.length; i++) {
Element pageElement = pages[i];
if (pageElement.getAttribute(AbstractIntroIdElement.ATT_ID).equals(
getId())) {
this.element = pageElement;
// call init on the new element. the filtering and the style-id
// are loaded by the parent class.
init(pageElement, getBundle(), base);
// INTRO: revisit. Special processing here should be made more
// general. we know id is correct.
style_id = getAttribute(element,
AbstractBaseIntroElement.ATT_STYLE_ID);
filteredFrom = getAttribute(element,
AbstractBaseIntroElement.ATT_FILTERED_FROM);
sharedStyle = getAttribute(element, ATT_SHARED_STYLE);
if (sharedStyle == null)
sharedStyle = "true"; //$NON-NLS-1$
foundMatchingPage = true;
}
}
if (foundMatchingPage)
// now do children loading as usual.
super.loadChildren();
else {
// page was not found in content file. Perform load actions, and log
// fact. init the children vector.
children = new Vector<>();
loaded = true;
// free DOM model for memory performance.
element = null;
Log.warning("Content file does not have page with id= " + getId()); //$NON-NLS-1$
}
}
private void loadXHTMLContent(Document dom) {
// no need to load any children since we use XSLT to print XHTML
// content. Simply cache DOM.
this.dom = dom;
this.isXHTMLPage = true;
// init empty children vector.
children = new Vector<>();
loaded = true;
}
/**
* Returns the DOM representing an external XHTML file. May return null if
* extension content is 3.0 format. The page is resolved before returning,
* meaning includes are resolved, and the base of the page is defined.
*
* @return
*/
public Document getResolvedDocument() {
// we need to force a getChildren to resolve the page.
getChildren();
return dom;
}
/**
* Returns the DOM representing an external XHTML file. May return null if
* extension content is 3.0 format. The page is NOT resolved before
* returning. It is retruned as given by the dom parser.
*
* @return
*/
public Document getDocument() {
// we only need to load children here.
if (!loaded)
loadChildren();
return dom;
}
/**
* Returns whether or not we have an XHTML page as the content for this
* page. The XHTML page is defined through the content attribute. This
* method forces the content file to be parsed and loaded in memory.
*
* @return
*/
public boolean isXHTMLPage() {
// we need to force loading of children since we need to determine
// content type. Load the children without resolving (for performance),
// this will set the XHTML flag at the page level.
if (!loaded)
loadChildren();
return isXHTMLPage;
}
/**
* Deep searches all children in this container's DOM for the first child
* with the given id. The element retrieved must have the passed local name.
* Note that in an XHTML file (aka DOM) elements should have a unique id
* within the scope of a document. We use local name because this allows for
* finding intro anchors, includes and dynamic content element regardless of
* whether or not an xmlns was used in the xml. note: could not have used
* inheritance from parent container because return type for parent is intro
* legacy model.
*
*/
public Element findDomChild(String id, String localElementName) {
if (!loaded)
loadChildren();
// using getElementById is tricky and we need to have intro XHTML
// modules to properly use this method.
return ModelUtil.getElementById(dom, id, localElementName);
}
/**
* Search for any element with the given id.
*
* @param id
* @return
*/
public Element findDomChild(String id) {
return findDomChild(id, "*"); //$NON-NLS-1$
}
/**
* Resolves the full page. It is called just before the page needs to be
* displayed.
* <li>adds a BASE child to the DOM HEAD element, if one is not defined.
* All intro documents must have a base defined to resolve all urls.</li>
* <li>resolves all includes in the page. This means importing target DOM.
* </li>
* <li>resolves all XHTML attributes for resources, eg: src, href
* attributes.</li>
*/
protected void resolvePage() {
// insert base meta-tag,
ModelUtil.insertBase(dom, ModelUtil.getParentFolderOSString(content));
// resolve all relative resources relative to content file. Do it before
// inserting shared style to enable comparing fully qualified styles.
ModelUtil.updateResourceAttributes(dom.getDocumentElement(), this);
// now add shared style.
IntroModelRoot modelRoot = (IntroModelRoot)getParent();
IntroPartPresentation presentation = modelRoot.getPresentation();
String [] styles = presentation!=null?presentation.getImplementationStyles():null;
if (styles != null && injectSharedStyle()) {
for (int i=0; i<styles.length; i++)
ModelUtil.insertStyle(dom, styles[i]);
}
// filter the content
if (domProcessor == null) {
domProcessor = new DocumentProcessor(new ProcessorHandler[] { new FilterHandler(IntroEvaluationContext.getContext()) });
}
UAElement element = UAElementFactory.newElement(dom.getDocumentElement());
domProcessor.process(element, null);
// and resolve includes.
resolveIncludes();
// now remove all anchors from this page.
ModelUtil.removeAllElements(dom, IntroAnchor.TAG_ANCHOR);
resolved = true;
}
/**
* Resolves all includes in this page. This means importing the DOM of the
* target path into the current page DOM, and resolving XHTML attributes for
* resources.
*/
protected void resolveIncludes() {
// get all includes elements in DOM.
NodeList includes = dom.getElementsByTagNameNS("*", //$NON-NLS-1$
IntroInclude.TAG_INCLUDE);
// get the array version of the include nodelist to work around
// replaceChild() DOM api design.
Node[] nodes = ModelUtil.getArray(includes);
for (int i = 0; i < nodes.length; i++) {
Element includeElement = (Element) nodes[i];
IntroInclude include = new IntroInclude(includeElement, getBundle());
// result[0] is target parent page, result[1] is target element.
Object[] results = findDOMIncludeTarget(include);
Element targetElement = (Element) results[1];
if (targetElement == null) {
String message = "Could not resolve following include: " //$NON-NLS-1$
+ ModelLoaderUtil.getLogString(getBundle(),
includeElement, IntroInclude.ATT_PATH);
Log.warning(message);
return;
}
// insert the target element instead of the include.
Node targetNode = dom.importNode(targetElement, true);
// update the src attribute of this node, if defined by w3
// specs.
AbstractIntroPage page = ((AbstractIntroPage) results[0]);
ModelUtil.updateResourceAttributes((Element) targetNode, page);
// use of replace API to remove include element is tricky. It
// confuses the NodeList used in the loop above. Removing an include
// removes it from the NodeList. Used cloned Array instead.
includeElement.getParentNode().replaceChild(targetNode,
includeElement);
}
}
/**
* Find the target Element pointed to by the path in the include. It is
* assumed that configId always points to an external config, and not the
* same config of the inlcude.
*
* @param include
* @param path
* @return
*/
private Object[] findDOMIncludeTarget(IntroInclude include) {
String path = include.getPath();
IntroModelRoot targetModelRoot = (IntroModelRoot) getParentPage()
.getParent();
String targetConfigID = include.getConfigId();
if (targetConfigID != null)
targetModelRoot = ExtensionPointManager.getInst().getModel(
targetConfigID);
if (targetModelRoot == null)
// if the target config was not found, skip this include.
return null;
return findDOMTarget(targetModelRoot, path);
}
/**
* Finds the child element that corresponds to the given path in the passed
* model.
*
* @param model
* model containing target path.
* @param path
* the path to look for
* @param results
* two object array that will return the target intro page as the
* first result, and the actual target DOM Element as the second
* result. It is gauranteed to not be null. Content may be null.
* @return target DOM element
*/
public Object[] findDOMTarget(IntroModelRoot model, String path) {
Object[] results = new Object[2];
// path must be pageId/anchorID in the case of of XHTML pages.
// pages.
String[] pathSegments = StringUtil.split(path, "/"); //$NON-NLS-1$
if (pathSegments.length != 2)
// path does not have correct format. Return empty results.
return results;
// save to cast.
AbstractIntroPage targetPage = (AbstractIntroPage) model.findChild(
pathSegments[0], ABSTRACT_PAGE);
if (targetPage != null) {
results[0] = targetPage;
Element targetElement = targetPage.findDomChild(pathSegments[1]);
if (targetElement != null)
results[1] = targetElement;
}
return results;
}
/**
* @return Returns the content.
*/
public String getContent() {
return content;
}
/**
* Deep copy since class has mutable objects.
*/
@Override
public Object clone() throws CloneNotSupportedException {
AbstractIntroPage clone = (AbstractIntroPage) super.clone();
if (title != null) {
IntroPageTitle clonedTitle = (IntroPageTitle) title.clone();
clonedTitle.setParent(clone);
clone.title = clonedTitle;
}
// styles are safe for a shallow copy.
if (styles != null)
clone.styles = new Vector<String>(styles);
if (altStyles != null)
clone.altStyles = new Hashtable<>(altStyles);
return clone;
}
/**
* Used when cloning pages to assign a unique id. Cache original id before
* setting.
*
* @param id
*/
public void setId(String id) {
this.originalId = this.id;
this.id = id;
}
/*
* Creates an IFrame and injects it as the only child of the specified path.
*/
public boolean injectIFrame(String url, String embedTarget) {
// embed url as IFrame in target div. We need to find target div in
// this cloned page not in the original page.
IntroGroup divToReplace = (IntroGroup) findTarget(embedTarget);
if (divToReplace == null) {
// we failed to find embed div, log and exit.
Log.warning("Failed to find embedTarget: " + embedTarget //$NON-NLS-1$
+ " in page " + getId()); //$NON-NLS-1$
return false;
}
this.iframe = new IntroInjectedIFrame(getElement(), getBundle());
this.iframe.setParent(divToReplace);
this.iframe.setIFrameURL(url);
divToReplace.clearChildren();
divToReplace.addChild(iframe);
return true;
}
/**
* Return true if this page is a cloned page that has an IFrame.
*
* @return
*/
public boolean isIFramePage() {
return (iframe != null) ? true : false;
}
public String getUnmangledId() {
if (isIFramePage())
return originalId;
return id;
}
/**
* Set the url of the embedded IFrame, if this page is an IFrame page.
*
* @param url
*/
public void setIFrameURL(String url) {
if (!isIFramePage())
return;
this.iframe.setIFrameURL(url);
}
/**
* Return the url of the embedded IFrame, if this page is an IFrame page.
*
* @param url
*/
public String getIFrameURL() {
if (!isIFramePage())
return null;
return this.iframe.getIFrameURL();
}
/**
* Returns the raw or unprocessed base location.
*/
public String getInitialBase() {
return initialBase;
}
/**
* Return the url of the embedded IFrame, if this page is an IFrame page.
*
* @param url
*/
public boolean injectSharedStyle() {
return this.sharedStyle.equals("true") ? true : false; //$NON-NLS-1$
}
/**
* Returns true if this is a dynamicpage or not.
* @return Returns the isDynamic.
*/
public boolean isDynamic() {
return isDynamic;
}
/**
* @return Returns the url.
*/
public String getUrl() {
return url;
}
/**
* @return Returns the isStandbyPage.
*/
public boolean isStandbyPage() {
return isStandbyPage;
}
/**
* @param isStandbyPage
* The isStandbyPage to set.
*/
public void setStandbyPage(boolean isStandbyPage) {
this.isStandbyPage = isStandbyPage;
}
}