Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDejan Gloszic2006-02-22 06:27:10 +0000
committerDejan Gloszic2006-02-22 06:27:10 +0000
commit9e10585f019ddb316a181615c73c2a2f41ad2b06 (patch)
treed4b24ad520fbc3cdc710f3c3163f4935aad7a7a2
parentf887a2faf56a3ad7fe14108137db117ffa925446 (diff)
downloadeclipse.platform.ua-9e10585f019ddb316a181615c73c2a2f41ad2b06.tar.gz
eclipse.platform.ua-9e10585f019ddb316a181615c73c2a2f41ad2b06.tar.xz
eclipse.platform.ua-9e10585f019ddb316a181615c73c2a2f41ad2b06.zip
*** empty log message ***
-rw-r--r--org.eclipse.ui.intro/javascript/common.js8
-rw-r--r--org.eclipse.ui.intro/plugin.xml2
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/html/IntroHTMLGenerator.java2402
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/AbstractIntroContainer.java9
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/AbstractIntroElement.java13
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/IntroGroup.java6
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/IntroModelRoot.java20
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/swt/PageWidgetFactory.java5
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/universal/ExtensionData.java4
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/universal/ISharedIntroConstants.java6
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/universal/PageData.java8
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/universal/UniversalIntroConfigurer.java19
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/intro/config/IntroConfigurer.java16
-rw-r--r--org.eclipse.ui.intro/themes/purpleMesh/html/shared.css49
-rw-r--r--org.eclipse.ui.intro/universal/introContent.xml23
15 files changed, 1346 insertions, 1244 deletions
diff --git a/org.eclipse.ui.intro/javascript/common.js b/org.eclipse.ui.intro/javascript/common.js
new file mode 100644
index 000000000..4da3b9c22
--- /dev/null
+++ b/org.eclipse.ui.intro/javascript/common.js
@@ -0,0 +1,8 @@
+
+function toggleSection(id) {
+ if (document.getElementById) {
+ var element = document.getElementById(id);
+ element.style.display=(element.style.display=="block")?"none":"block";
+ }
+ return false;
+} \ No newline at end of file
diff --git a/org.eclipse.ui.intro/plugin.xml b/org.eclipse.ui.intro/plugin.xml
index bbadaaa02..3739d943e 100644
--- a/org.eclipse.ui.intro/plugin.xml
+++ b/org.eclipse.ui.intro/plugin.xml
@@ -49,11 +49,13 @@
introId="org.eclipse.ui.intro.universal">
<presentation
home-page-id="root" standby-page-id="standby">
+ <!-- -->
<implementation
style="$theme$/html/shared.css"
kind="html"
os="win32,linux,macosx">
</implementation>
+ <!-- -->
<implementation
kind="swt">
</implementation>
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/html/IntroHTMLGenerator.java b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/html/IntroHTMLGenerator.java
index 22d076606..eafd430fe 100644
--- a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/html/IntroHTMLGenerator.java
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/html/IntroHTMLGenerator.java
@@ -1,13 +1,11 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2005 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
+/***************************************************************************************************
+ * Copyright (c) 2004, 2005 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
- *******************************************************************************/
+ *
+ * Contributors: IBM Corporation - initial API and implementation
+ **************************************************************************************************/
package org.eclipse.ui.internal.intro.impl.html;
import java.io.BufferedReader;
@@ -41,1227 +39,1171 @@ import org.eclipse.ui.intro.config.IIntroContentProviderSite;
public class IntroHTMLGenerator {
- private AbstractIntroPage introPage;
-
- private IIntroContentProviderSite providerSite;
-
- /**
- * Generates the HTML code that will be presented in the browser widget for
- * the provided intro page.
- *
- * @param page
- * the page to generate HTML for
- * @param presentation
- * the presentation associated with this page.
- */
- public HTMLElement generateHTMLforPage(AbstractIntroPage page,
- IIntroContentProviderSite providerSite) {
- if (page == null)
- return null;
- this.introPage = page;
- this.providerSite = providerSite;
-
- // generate and add the appropriate encoding to the top of the document
- // generateEncoding();
- // create the main HTML element, and all of its contents.
- return generateHTMLElement();
- }
-
- /*
- * private HTMLElement generateEncoding() { HTMLElement encoding = new
- * HTMLElement(""); //$NON-NLS-1$ // TODO: figure out how to handle locale
- * based encoding // As far as the HTML generator is concerned, this is
- * probably as // simple as asking the model for the information return
- * encoding; }
- */
-
- /**
- * Generates the HTML element and its content:
- *
- * <pre>
- *
- * &lt;HTML&gt;
- * &lt;HEAD&gt;
- * head content
- * &lt;/HEAD&gt;
- * &lt;BODY&gt;
- * body content
- * &lt;/BODY&gt;
- * &lt;/HTML&gt;
- *
- * </pre>
- *
- * @return the html HTMLElement
- */
- private HTMLElement generateHTMLElement() {
- // this is the outermost element, so it has no indent
- int indentLevel = 0;
- HTMLElement html = new FormattedHTMLElement(
- IIntroHTMLConstants.ELEMENT_HTML, indentLevel, true);
- HTMLElement head = generateHeadElement(indentLevel + 1);
- HTMLElement body = generateBodyElement(indentLevel + 1);
- html.addContent(head);
- html.addContent(body);
- return html;
- }
-
- /**
- * Generates the HEAD element and its content:
- *
- * <pre>
- *
- *
- * &lt;HEAD&gt;
- * &lt;BASE href=&quot;base_plugin_location&gt;
- * &lt;style type=&quot;text/css&quot;&gt;HTML, IMG { border: 0px; } &lt;/style&gt;
- * &lt;TITLE&gt;page title &lt;/TITLE&gt;
- * &lt;LINK href=&quot;style sheet&quot;&gt;
- * additional head content, if specified
- * &lt;/HEAD&gt;
- *
- * </pre>
- *
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return the head HTMLElement
- */
- private HTMLElement generateHeadElement(int indentLevel) {
- HTMLElement head = new FormattedHTMLElement(
- IIntroHTMLConstants.ELEMENT_HEAD, indentLevel, true);
- // add the title
- head.addContent(generateTitleElement(null, indentLevel + 1));
- // create the BASE element
- String basePath = BundleUtil.getResolvedResourceLocation(introPage
- .getBase(), introPage.getBundle());
- HTMLElement base = generateBaseElement(indentLevel + 1, basePath);
- if (base != null)
- head.addContent(base);
- // create the HTML style block
- head.addContent(generateStyleElement(indentLevel + 1));
- // add the presentation style
- String style = IntroPlugin.getDefault().getIntroModelRoot()
- .getPresentation().getImplementationStyle();
- if (style != null && introPage.injectSharedStyle())
- head.addContent(generateLinkElement(style, indentLevel + 1));
- style = introPage.getStyle();
- if (style != null)
- head.addContent(generateLinkElement(style, indentLevel + 1));
- // add the page's inherited style(s)
- String[] pageStyles = introPage.getStyles();
- for (int i = 0; i < pageStyles.length; i++) {
- style = pageStyles[i];
- if (style != null)
- head.addContent(generateLinkElement(style, indentLevel + 1));
- }
- // if there is additional head conent specified in an external file,
- // include it. Additional head content can be specified at the
- // implementation level (which would apply to ALL pages) and at the
- // page level (which would apply only to that particular page).
- // For the implementation's head contribution:
- StringBuffer content = null;
- IntroHead introHead = IntroPlugin.getDefault().getIntroModelRoot()
- .getPresentation().getHead();
- if (introHead != null) {
- content = readFromFile(introHead.getSrc(), introHead
- .getInlineEncoding());
- if (content != null)
- head.addContent(content);
- }
- // For the page's head contribution:
- // TODO: there should only be one of these at the page level, not a
- // collection..
- IntroHead[] htmlHeads = introPage.getHTMLHeads();
- for (int i = 0; i < htmlHeads.length; i++) {
- introHead = htmlHeads[i];
- if (introHead != null) {
- content = readFromFile(introHead.getSrc(), introHead
- .getInlineEncoding());
- if (content != null)
- head.addContent(content);
- }
- }
- return head;
- }
-
- /**
- * Generates the BODY element and its content:
- *
- * <pre>
- *
- *
- * &lt;BODY&gt;
- * &lt;DIV id=&quot;pageId&quot; class=&quot;pageClass&quot;&gt;
- * page content
- * &lt;/DIV&gt;
- * &lt;/BODY&gt;
- *
- * </pre>
- *
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return the body HTMLElement
- */
- private HTMLElement generateBodyElement(int indentLevel) {
- HTMLElement body = new FormattedHTMLElement(
- IIntroHTMLConstants.ELEMENT_BODY, indentLevel, true);
- // Create the div that contains the page content
- String pageId = (introPage.getId() != null) ? introPage.getId()
- : IIntroHTMLConstants.DIV_ID_PAGE;
- HTMLElement pageContentDiv = generateDivElement(pageId, indentLevel + 1);
- if (introPage.getStyleId() != null)
- pageContentDiv.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS,
- introPage.getStyleId());
- if (introPage.getBackgroundImage() != null)
- pageContentDiv.addAttribute(IIntroHTMLConstants.ATTRIBUTE_STYLE,
- "background-image : url("+introPage.getBackgroundImage()+")"); //$NON-NLS-1$ //$NON-NLS-2$
-
- // Add any children of the page, in the order they are defined
- AbstractIntroElement[] children = introPage.getChildren();
- for (int i = 0; i < children.length; i++) {
- AbstractIntroElement child = children[i];
- // use indentLevel + 2 here, since this element is contained within
- // the pageContentDiv
- HTMLElement childElement = generateIntroElement(child,
- indentLevel + 2);
- if (childElement != null)
- pageContentDiv.addContent(childElement);
- }
- body.addContent(pageContentDiv);
- return body;
- }
-
- /**
- * Given an IntroElement, generate the appropriate HTMLElement
- *
- * @param element
- * the IntroElement
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return an HTMLElement
- */
- private HTMLElement generateIntroElement(AbstractIntroElement element,
- int indentLevel) {
- if (element == null)
- return null;
- // check to see if this element should be filtered from the HTML
- // presentation
- if (filteredFromPresentation(element))
- return null;
- switch (element.getType()) {
- case AbstractIntroElement.GROUP:
- return generateIntroDiv((IntroGroup) element, indentLevel);
- case AbstractIntroElement.LINK:
- return generateIntroLink((IntroLink) element, indentLevel);
- case AbstractIntroElement.HTML:
- return generateIntroHTML((IntroHTML) element, indentLevel);
- case AbstractIntroElement.CONTENT_PROVIDER:
- return generateIntroContent((IntroContentProvider) element,
- indentLevel);
- case AbstractIntroElement.IMAGE:
- return generateIntroImage((IntroImage) element, indentLevel);
- case AbstractIntroElement.TEXT:
- return generateIntroText((IntroText) element, indentLevel);
- case AbstractIntroElement.PAGE_TITLE:
- return generateIntroTitle((IntroPageTitle) element, indentLevel);
- case AbstractIntroElement.INJECTED_IFRAME:
- return generateIntroInjectedIFrame((IntroInjectedIFrame) element,
- indentLevel);
- default:
- return null;
- }
- }
-
- /**
- * Create a div element and its content from an IntroDiv:
- *
- * <pre>
- *
- *
- * &lt;div id=&quot;attrvalue&quot;&gt;
- * &lt;h4&gt;&lt;span class=&quot;div-label&quot;&gt;attrvalue&lt;/span&gt;&lt;h4&gt;
- * any defined divs, links, html, images, text, includes
- * &lt;/div&gt;
- *
- * </pre>
- *
- * @param element
- * the IntroDiv
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return a div HTMLElement
- */
- private HTMLElement generateIntroDiv(IntroGroup element, int indentLevel) {
- // Create the outer div element
- HTMLElement divElement = generateDivElement(element.getId(),
- indentLevel);
- // if a div class was specified, add it
- if (element.getStyleId() != null)
- divElement.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS,
- element.getStyleId());
- // Create the div label, if specified
- if (element.getLabel() != null) {
- HTMLElement divLabel = generateTextElement(
- IIntroHTMLConstants.ELEMENT_H4, null,
- IIntroHTMLConstants.SPAN_CLASS_DIV_LABEL, element.getLabel(),
- indentLevel + 1);
- divElement.addContent(divLabel);
- }
- if (element.getBackgroundImage() != null) {
- String imageUrl = element.getBackgroundImage();
- imageUrl = BundleUtil.getResolvedResourceLocation(element.getBase(), imageUrl, element.getBundle());
- String style;
- if (Platform.getWS().equals(Platform.WS_WIN32) &&
- imageUrl.toLowerCase().endsWith(".png")) { //$NON-NLS-1$
- // IE 5.5+ does not handle alphas in PNGs without
- // this hack. Remove when IE7 becomes widespread
- style = "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+imageUrl+"', sizingMethod='crop');"; //$NON-NLS-1$ //$NON-NLS-2$
- }
- else {
- style = "background-image : url("+imageUrl+")"; //$NON-NLS-1$ //$NON-NLS-2$
- }
- divElement.addAttribute(IIntroHTMLConstants.ATTRIBUTE_STYLE, style);
- }
- // Add any children of the div, in the order they are defined
- AbstractIntroElement[] children = element.getChildren();
- for (int i = 0; i < children.length; i++) {
- AbstractIntroElement child = children[i];
- HTMLElement childElement = generateIntroElement(child,
- indentLevel + 1);
- if (childElement != null)
- divElement.addContent(childElement);
- }
- return divElement;
- }
-
- /**
- * Generates an anchor (link) element and its content from an IntroLink:
- *
- * <pre>
- *
- * &lt;A id=linkId class=&quot;link&quot; href=linkHref&gt;
- * &lt;IMG src=&quot;blank.gif&quot;&gt;
- * &lt;SPAN class=&quot;link-label&quot;&gt;linkLabel &lt;/SPAN&gt;
- * &lt;P&gt;&lt;SPAN&gt;text&lt;/SPAN&gt;&lt;/P&gt;
- * &lt;/A&gt;
- *
- * </pre>
- *
- * @param element
- * the IntroLink
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return an anchor (&lt;A&gt;) HTMLElement
- */
- private HTMLElement generateIntroLink(IntroLink element, int indentLevel) {
- HTMLElement anchor = generateAnchorElement(element, indentLevel);
- // add <IMG src="blank.gif">
- String blankImageURL = BundleUtil.getResolvedResourceLocation(
- IIntroHTMLConstants.IMAGE_SRC_BLANK, IIntroConstants.PLUGIN_ID);
- if (blankImageURL != null) {
- anchor.addContent(generateImageElement(blankImageURL, null,
- IIntroHTMLConstants.IMAGE_CLASS_BG, indentLevel + 1));
- }
- // add link image, if one is specified
- if (element.getImg() != null) {
- HTMLElement img = generateIntroElement(element.getImg(),
- indentLevel + 1);
- if (img != null)
- anchor.addContent(img);
- }
- // add <SPAN class="link-label">linkLabel</SPAN>
- if (element.getLabel() != null) {
- HTMLElement label = generateSpanElement(
- IIntroHTMLConstants.SPAN_CLASS_LINK_LABEL, indentLevel + 1);
- label.addContent(element.getLabel());
- anchor.addContent(label);
- }
- IntroText linkText = element.getIntroText();
- if (linkText != null && linkText.getText() != null) {
- HTMLElement text = generateIntroElement(linkText, indentLevel + 1);
- if (text != null)
- anchor.addContent(text);
- }
- return anchor;
- }
-
- /**
- * Generate the appropriate HTML from an IntroHTML. If the IntroHTML type is
- * "inline", then the content from the referenced file is emitted as-is into
- * a div element. If the type is "embed", an OBJECT html element is created
- * whose <code>data</code> attribute is equal to the IntroHTML's
- * <code>src</code> value
- *
- * @param element
- * the IntroHTML
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return an HTMLElement
- */
- private HTMLElement generateIntroHTML(IntroHTML element, int indentLevel) {
- if (element.isInlined())
- return generateInlineIntroHTML(element, indentLevel);
-
- return generateEmbeddedIntroHTML(element, indentLevel);
- }
-
- /**
- * Generate an image element from an IntroImage:
- *
- * <pre>
- *
- * &lt;IMG src=imageSrc id=imageId&gt;
- *
- * </pre>
- *
- * @param element
- * the IntroImage
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return an img HTMLElement
- */
- private HTMLElement generateIntroImage(IntroImage element, int indentLevel) {
- HTMLElement imageElement = generateImageElement(element.getSrc(),
- element.getAlt(), element.getStyleId(), indentLevel);
- if (element.getId() != null)
- imageElement.addAttribute(IIntroHTMLConstants.ATTRIBUTE_ID, element
- .getId());
- return imageElement;
- }
-
- /**
- * Generate a paragraph (&lt;P&gt;) element from an IntroText. The paragraph
- * element will contain a span element that will contain the actual text.
- * Providing the span element provides additional flexibility for CSS
- * designers.
- *
- * <pre>
- *
- *
- * &lt;P&gt;&lt;SPAN&gt;spanContent&lt;/SPAN&gt;&lt;/P&gt;
- *
- * </pre>
- *
- * @param element
- * the IntroText
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return a paragraph HTMLElement
- */
- private HTMLElement generateIntroText(IntroText element, int indentLevel) {
- String spanClass = (element.getStyleId() != null) ? element
- .getStyleId() : IIntroHTMLConstants.SPAN_CLASS_TEXT;
- HTMLElement textElement = generateTextElement(
- IIntroHTMLConstants.ELEMENT_PARAGRAPH, element.getId(), spanClass,
- element.getText(), indentLevel);
- return textElement;
- }
-
- /**
- * @param element
- * @param indentLevel
- * @return
- */
- private HTMLElement generateIntroInjectedIFrame(
- IntroInjectedIFrame element, int indentLevel) {
- HTMLElement iframe = generateIFrameElement(element.getIFrameURL(), "0", //$NON-NLS-1$
- "auto", indentLevel); //$NON-NLS-1$
- return iframe;
- }
-
- /**
- * @param element
- * @param indentLevel
- * @return
- */
- private HTMLElement generateIntroTitle(IntroPageTitle element,
- int indentLevel) {
- HTMLElement titleElement = generateHeaderDiv(element.getId(), element
- .getStyleId(), IIntroHTMLConstants.ELEMENT_H1, element.getTitle(),
- indentLevel);
- return titleElement;
- }
-
- /**
- * Generate "inline" content from an IntroHTML. The content from the file
- * referenced by the IntroHTML's <code>src</code> attribute is emitted
- * as-is into a div element:
- *
- * <pre>
- *
- *
- * &lt;div id=&quot;attrvalue&quot; class=&quot;attrvalue2&quot;&gt;
- * content from file specified in src attribute
- * &lt;/div&gt;
- *
- * </pre>
- *
- * @param element
- * the IntroHTML
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return a div HTMLElement, or null if there was a problem reading from
- * the file
- */
- private HTMLElement generateInlineIntroHTML(IntroHTML element,
- int indentLevel) {
- // make sure to ask model for encoding. If encoding is null (ie: not
- // specified in
- // markup, local encoding is used.
- StringBuffer content = readFromFile(element.getSrc(), element
- .getInlineEncoding());
- if (content != null && content.length() > 0) {
- // Create the outer div element
- String divClass = (element.getStyleId() != null) ? element
- .getStyleId() : IIntroHTMLConstants.DIV_CLASS_INLINE_HTML;
- HTMLElement divElement = generateDivElement(element.getId(),
- divClass, indentLevel);
- // add the content of the specified file into the div element
- divElement.addContent(content);
- return divElement;
- }
- return null;
- }
-
- /**
- * Includes HTML content that is created by an IIntroContentProvider
- * implementation.
- *
- * @param element
- * @param indentLevel
- * @return
- */
- private HTMLElement generateIntroContent(IntroContentProvider element,
- int indentLevel) {
- // create a new div to wrap the content
- HTMLElement divElement = generateDivElement(element.getId(),
- IIntroHTMLConstants.DIV_CLASS_PROVIDED_CONTENT, indentLevel);
-
- // If we've already loaded the content provider for this element,
- // retrieve it, otherwise load the class
- IIntroContentProvider providerClass = ContentProviderManager.getInst()
- .getContentProvider(element);
- if (providerClass == null)
- // content provider never created before, create it.
- providerClass = ContentProviderManager.getInst()
- .createContentProvider(element, providerSite);
-
- if (providerClass != null) {
- StringWriter stringWriter = new StringWriter();
- PrintWriter pw = new PrintWriter(stringWriter);
- // create the specialized content
- providerClass.createContent(element.getId(), pw);
- // add the content of the specified file into the div element
- stringWriter.flush();
- divElement.addContent(stringWriter.toString());
- pw.close();
- } else {
- // we couldn't load the content provider, so add any alternate
- // text content if there is any
- IntroText htmlText = element.getIntroText();
- if (htmlText != null && htmlText.getText() != null) {
- String textClass = (htmlText.getStyleId() != null) ? htmlText
- .getStyleId() : IIntroHTMLConstants.SPAN_CLASS_TEXT;
- HTMLElement text = generateTextElement(
- IIntroHTMLConstants.ELEMENT_PARAGRAPH, htmlText.getId(),
- textClass, element.getText(), indentLevel);
- if (text != null)
- divElement.addContent(text);
- }
- }
- return divElement;
- }
-
- /**
- * Generate "embedded" content from an IntroHTML. An OBJECT html element is
- * created whose <code>data</code> attribute is equal to the IntroHTML's
- * <code>src</code> value.
- *
- * <pre>
- *
- * &lt;OBJECT type=&quot;text/html&quot; data=&quot;attrvalue&quot;&gt;
- * alternative text in case the object can not be rendered
- * &lt;/OBJECT&gt;
- *
- * </pre>
- *
- * @param element
- * the IntroHTML
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return an object HTMLElement
- */
- private HTMLElement generateEmbeddedIntroHTML(IntroHTML element,
- int indentLevel) {
- HTMLElement objectElement = new FormattedHTMLElement(
- IIntroHTMLConstants.ELEMENT_OBJECT, indentLevel, true);
- objectElement.addAttribute(IIntroHTMLConstants.ATTRIBUTE_TYPE,
- IIntroHTMLConstants.OBJECT_TYPE);
- if (element.getId() != null)
- objectElement.addAttribute(IIntroHTMLConstants.ATTRIBUTE_ID,
- element.getId());
- if (element.getSrc() != null)
- objectElement.addAttribute(IIntroHTMLConstants.ATTRIBUTE_DATA,
- element.getSrc());
- if (element.getStyleId() != null)
- objectElement.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS,
- element.getStyleId());
- // The alternative content is added in case the browser can not render
- // the specified content.
- IntroText htmlText = element.getIntroText();
- if (htmlText != null && htmlText.getText() != null) {
- String textClass = (htmlText.getStyleId() != null) ? htmlText
- .getStyleId() : IIntroHTMLConstants.SPAN_CLASS_TEXT;
- HTMLElement text = generateTextElement(
- IIntroHTMLConstants.ELEMENT_PARAGRAPH, htmlText.getId(),
- textClass, element.getText(), indentLevel);
- if (text != null)
- objectElement.addContent(text);
- }
- if (element.getIntroImage() != null) {
- HTMLElement img = generateIntroImage(element.getIntroImage(),
- indentLevel);
- if (img != null)
- objectElement.addContent(img);
- }
- return objectElement;
- }
-
- /**
- * Generates the BASE element for the head of the html document. Each
- * document can have only one base element
- *
- * <pre>
- *
- *
- * &lt;BASE href=baseURL&gt;
- * </pre>
- *
- * @param indentLevel
- * @param baseURL
- * @return
- */
- private HTMLElement generateBaseElement(int indentLevel, String baseURL) {
- HTMLElement base = new FormattedHTMLElement(
- IIntroHTMLConstants.ELEMENT_BASE, indentLevel, true, false);
- if (baseURL != null)
- base.addAttribute(IIntroHTMLConstants.ATTRIBUTE_HREF, baseURL);
- return base;
- }
-
- /**
- * Generates the style element that goes into HEAD:
- *
- * <pre>
- *
- * &lt;style type=&quot;text/css&quot;&gt;HTML, IMG { border: 0px; } &lt;/style&gt;
- *
- * </pre>
- *
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return the style HTMLElement
- */
- private HTMLElement generateStyleElement(int indentLevel) {
- HTMLElement style = new FormattedHTMLElement(
- IIntroHTMLConstants.ELEMENT_STYLE, indentLevel, false);
- style.addAttribute(IIntroHTMLConstants.ATTRIBUTE_TYPE,
- IIntroHTMLConstants.LINK_STYLE);
- style.addContent(IIntroHTMLConstants.STYLE_HTML);
- return style;
- }
-
- /**
- * Generates the title element and its content:
- *
- * <pre>
- *
- * &lt;TITLE&gt;intro title&lt;/TITLE&gt;
- *
- * </pre>
- *
- * @param title
- * the title of this intro page
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return the title HTMLElement
- */
- private HTMLElement generateTitleElement(String title, int indentLevel) {
- HTMLElement titleElement = new FormattedHTMLElement(
- IIntroHTMLConstants.ELEMENT_TITLE, indentLevel, false);
- if (title != null)
- titleElement.addContent(title);
- return titleElement;
- }
-
- /**
- * Generates a link element that refers to a cascading style sheet (CSS):
- *
- * <pre>
- *
- *
- * &lt;LINK rel=&quot;stylesheet&quot; style=&quot;text/css&quot; href=&quot;style sheet&quot;&gt;
- * </pre>
- *
- * @param href
- * the value of the href attribute for this link element
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return a link HTMLElement
- */
- private HTMLElement generateLinkElement(String href, int indentLevel) {
- HTMLElement link = new FormattedHTMLElement(
- IIntroHTMLConstants.ELEMENT_LINK, indentLevel, true, false);
- link.addAttribute(IIntroHTMLConstants.ATTRIBUTE_RELATIONSHIP,
- IIntroHTMLConstants.LINK_REL);
- link.addAttribute(IIntroHTMLConstants.ATTRIBUTE_STYLE,
- IIntroHTMLConstants.LINK_STYLE);
- if (href != null)
- link.addAttribute(IIntroHTMLConstants.ATTRIBUTE_HREF, href);
- return link;
- }
-
- /**
- * Generate an anchor element:
- *
- * <pre>
- *
- * &lt;A id=linkId class=linkClass href=linkHref&gt; &lt;/A&gt;
- *
- * </pre>
- *
- * @param link
- * the IntroLink element that contains the value for the id and
- * href attributes
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return an anchor (&lt;A&gt;) HTMLElement
- */
- private HTMLElement generateAnchorElement(IntroLink link, int indentLevel) {
- HTMLElement anchor = new FormattedHTMLElement(
- IIntroHTMLConstants.ELEMENT_ANCHOR, indentLevel, true);
- if (link.getId() != null)
- anchor.addAttribute(IIntroHTMLConstants.ATTRIBUTE_ID, link.getId());
- if (link.getUrl() != null)
- anchor.addAttribute(IIntroHTMLConstants.ATTRIBUTE_HREF, link
- .getUrl());
- if (link.getStyleId() != null)
- anchor.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS, link
- .getStyleId());
- else
- anchor.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS,
- IIntroHTMLConstants.ANCHOR_CLASS_LINK);
- return anchor;
- }
-
- /**
- * Generates a div block that contains a header and span element:
- *
- * <pre>
- *
- *
- * &lt;DIV id=divId&gt;
- * &lt;H&gt;&lt;SPAN&gt;spanContent &lt;/SPAN&gt; &lt;/H&gt;
- * &lt;/DIV&gt;
- *
- * </pre>
- *
- * @param divId
- * the id of the div to create
- * @param divClass
- * the class of the div
- * @param headerType
- * what type of header to create (e.g., H1, H2, etc)
- * @param spanContent
- * the span content
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return a div HTMLElement that contains a header
- */
- private HTMLElement generateHeaderDiv(String divId, String divClass,
- String headerType, String spanContent, int indentLevel) {
- // create the text element: <P><SPAN>spanContent</SPAN></P>
- HTMLElement text = generateTextElement(headerType, null, null,
- spanContent, indentLevel + 1);
- // create the containing div element
- HTMLElement div = generateDivElement(divId, divClass, indentLevel);
- div.addContent(text);
- return div;
- }
-
- /**
- * Generates a span element inside a text element, where the text element
- * can be a P (paragraph), or any of the H (Header) elements. Providing the
- * span element provides additional flexibility for CSS designers.
- *
- * <pre>
- *
- * &lt;P&gt;&lt;SPAN&gt;spanContent&lt;/SPAN&gt;&lt;/P&gt;
- *
- * </pre>
- *
- * @param type
- * the type of text element to create (e.g., P, H1, H2, etc)
- * @param spanID
- * the id of the span element, or null
- * @param spanClass
- * the class of the span element, or null
- * @param spanContent
- * the span content
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return a text HTMLElement that contains a span element
- */
- private HTMLElement generateTextElement(String type, String spanID,
- String spanClass, String spanContent, int indentLevel) {
- // Create the span: <SPAN>spanContent</SPAN>
- HTMLElement span = new HTMLElement(IIntroHTMLConstants.ELEMENT_SPAN);
- if (spanID != null)
- span.addAttribute(IIntroHTMLConstants.ATTRIBUTE_ID, spanID);
- if (spanClass != null)
- span.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS, spanClass);
- if (spanContent != null)
- span.addContent(spanContent);
- // Create the enclosing text element: <P><SPAN>spanContent</SPAN></P>
- HTMLElement text = new FormattedHTMLElement(type, indentLevel, false);
- text.addContent(span);
- return text;
- }
-
- /**
- * Generates a DIV element with the provided indent, id, and class.
- *
- * @param divId
- * value for the div's id attribute
- * @param divClass
- * value for the div's class attribute
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return a div HTMLElement
- */
- private HTMLElement generateDivElement(String divId, String divClass,
- int indentLevel) {
- HTMLElement div = generateDivElement(divId, indentLevel);
- div.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS, divClass);
- return div;
- }
-
- /**
- * Generates a DIV element with the provided indent and id.
- *
- * @param divId
- * value for the div's id attribute
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return a div HTMLElement
- */
- private HTMLElement generateDivElement(String divId, int indentLevel) {
- HTMLElement div = new FormattedHTMLElement(
- IIntroHTMLConstants.ELEMENT_DIV, indentLevel, true);
- if (divId != null)
- div.addAttribute(IIntroHTMLConstants.ATTRIBUTE_ID, divId);
- return div;
- }
-
- /**
- * Generates an IMG element:
- *
- * <pre>
- *
- *
- * &lt;IMG src=imageSrc alt=altText&gt;
- *
- * </pre>
- *
- * @param imageSrc
- * the value to be supplied to the src attribute
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return an img HTMLElement
- */
- private HTMLElement generateImageElement(String imageSrc, String altText,
- String imageClass, int indentLevel) {
- HTMLElement image = new FormattedHTMLElement(
- IIntroHTMLConstants.ELEMENT_IMG, indentLevel, true, false);
- boolean pngOnWin32 = imageSrc!=null && Platform.getWS().equals(Platform.WS_WIN32) && imageSrc.toLowerCase().endsWith(".png"); //$NON-NLS-1$
- if (imageSrc==null || pngOnWin32) {
- // we must handle PNGs here - IE does not support alpha blanding well.
- // We will set the alpha image loader and load the real image
- // that way. The 'src' attribute in the image itself will
- // get the blank image.
- String blankImageURL = BundleUtil.getResolvedResourceLocation(
- IIntroHTMLConstants.IMAGE_SRC_BLANK, IIntroConstants.PLUGIN_ID);
- if (blankImageURL!=null) {
- image.addAttribute(IIntroHTMLConstants.ATTRIBUTE_SRC, blankImageURL);
- if (pngOnWin32) {
- String style = "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+imageSrc+"', sizingMethod='scale')"; //$NON-NLS-1$//$NON-NLS-2$
- image.addAttribute(IIntroHTMLConstants.ATTRIBUTE_STYLE, style);
- }
- }
- }
- else
- image.addAttribute(IIntroHTMLConstants.ATTRIBUTE_SRC, imageSrc);
- if (altText == null)
- altText = ""; //$NON-NLS-1$
- image.addAttribute(IIntroHTMLConstants.ATTRIBUTE_ALT, altText);
- if (imageClass != null)
- image.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS, imageClass);
- return image;
- }
-
- /**
- * Generate a span element
- *
- * <pre>
- *
- * &lt;SPAN class=spanClass&gt; &lt;/SPAN&gt;
- *
- *
- * </pre>
- *
- * @param spanClass
- * the value to be supplied to the class attribute
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return a span HTMLElement
- */
- private HTMLElement generateSpanElement(String spanClass, int indentLevel) {
- HTMLElement span = new FormattedHTMLElement(
- IIntroHTMLConstants.ELEMENT_SPAN, indentLevel, false);
- span.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS, spanClass);
- return span;
- }
-
- /**
- * Generate a span element
- *
- * <pre>
- *
- * &lt;iframe src=&quot;localPage1.xhtml&quot; frameborder=&quot;1&quot; scrolling=&quot;auto&quot; longdesc=&quot;localPage1.xhtml&quot;&gt;
- * </pre>
- *
- * @param spanClass
- * the value to be supplied to the class attribute
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return a span HTMLElement
- */
- private HTMLElement generateIFrameElement(String src, String frameborder,
- String scrolling, int indentLevel) {
- HTMLElement iframe = new FormattedHTMLElement(
- IIntroHTMLConstants.ELEMENT_IFrame, indentLevel, false);
- if (src != null)
- iframe.addAttribute(IIntroHTMLConstants.ATTRIBUTE_SRC, src);
- if (frameborder != null)
- iframe.addAttribute(IIntroHTMLConstants.ATTRIBUTE_FRAMEBORDER,
- frameborder);
- if (scrolling != null)
- iframe.addAttribute(IIntroHTMLConstants.ATTRIBUTE_SCROLLING,
- scrolling);
- return iframe;
- }
-
-
-
-
- private boolean filteredFromPresentation(AbstractIntroElement element) {
- if (element.isOfType(AbstractIntroElement.BASE_ELEMENT))
- return ((AbstractBaseIntroElement) element).isFiltered();
-
- return false;
- }
-
- /**
- * Reads the content of the file referred to by the <code>src</code>
- * parameter and returns the content in the form of a StringBuffer. If the
- * file read contains substitution segments of the form $plugin:plugin_id$
- * then this method will make the proper substitution (the segment will be
- * replaced with the absolute path to the plugin with id plugin_id).
- *
- * @param src -
- * the file that contains the target conent
- * @param charsetName -
- * the encoding of the file to be read. If null, local encoding
- * is used. But the default of the model is UTF-8, so we should
- * not get a null encoding.
- * @return a StringBuffer containing the content in the file, or null
- */
- private StringBuffer readFromFile(String src, String charsetName) {
- if (src == null)
- return null;
- InputStream stream = null;
- StringBuffer content = new StringBuffer();
- BufferedReader reader = null;
- try {
- URL url = new URL(src);
- stream = url.openStream();
- // TODO: Do we need to worry about the encoding here? e.g.:
- // reader = new BufferedReader(new InputStreamReader(stream,
- // ResourcesPlugin.getEncoding()));
- if (charsetName == null)
- reader = new BufferedReader(new InputStreamReader(stream));
- else
- reader = new BufferedReader(new InputStreamReader(stream,
- charsetName));
- while (true) {
- int character = reader.read();
- if (character == -1) // EOF
- break; // done reading file
-
- else if (character == PluginIdParser.SUBSTITUTION_BEGIN) { // possible
- // substitution
- PluginIdParser parser = new PluginIdParser(character,
- reader);
- // If a valid plugin id was found in the proper format, text
- // will be the absolute path to that plugin. Otherwise, text
- // will simply be all characters read up to (but not
- // including)
- // the next dollar sign that follows the one just found.
- String text = parser.parsePluginId();
- if (text != null)
- content.append(text);
- } else {
- // make sure character is in char range before making cast
- if (character > 0x00 && character < 0xffff)
- content.append((char) character);
- else
- content.append(character);
- }
- }
- } catch (Exception exception) {
- Log.error("Error reading from file", exception); //$NON-NLS-1$
- } finally {
- try {
- if (reader != null)
- reader.close();
- if (stream != null)
- stream.close();
- } catch (IOException e) {
- Log.error("Error closing input stream", e); //$NON-NLS-1$
- return null;
- }
- }
- return content;
- }
-
- /**
- * A helper class to help identify substitution strings in a content file. A
- * properly formatted substitution string is of the form:
- * <code>$plugin:plugin_id$</code> where plugin_id is the valid id of an
- * installed plugin. The substitution string will be replaced with the
- * absolute path to the plugin.
- *
- * An example usage of the string substution: The html file
- * <code>inline.html</code> is included in your intro via the html inline
- * mechanism . This file needs to reference a resource that is located in
- * another plugin. The following might be found in inline.html: <code>
- * <a href="$plugin:test.plugin$html/test.html">link to file</a>
- * </code>
- * When this file is read in, the relevant section will be replaced as
- * follows: <code>
- * <a href="file:/install_path/plugins/test.plugin/html/test.html">link to file</a>
- * </code>
- *
- */
- private static class PluginIdParser {
- private BufferedReader reader;
-
- private static final char SUBSTITUTION_BEGIN = '$';
-
- private static final char SUBSTITUTION_END = '$';
-
- // tokenContent will contain all characters read by the parser, starting
- // with and including the initial $ token.
- private StringBuffer tokenContent;
-
- // pluginId will contain the content between the "$plugin:" segment
- // and the closing "$" token
- private StringBuffer pluginId;
-
- protected PluginIdParser(char tokenBegin, BufferedReader bufferedreader) {
- reader = bufferedreader;
- tokenContent = new StringBuffer(tokenBegin);
- pluginId = new StringBuffer();
- }
-
- protected PluginIdParser(int tokenBegin, BufferedReader bufferedreader) {
- reader = bufferedreader;
- tokenContent = new StringBuffer();
- pluginId = new StringBuffer();
- // make sure tokenBegin is in char range before making cast
- if (tokenBegin > 0x00 && tokenBegin < 0xffff)
- tokenContent.append((char) tokenBegin);
- }
-
- /**
- * This method should be called after the initial substitution
- * identifier has been read in (the substition string begins and ends
- * with the "$" character). A properly formatted substitution string is
- * of the form:</code> "$plugin:plugin_id$</code>- the initial "$" is
- * immediately followed by the "plugin:" segment - the <code>plugin_id
- * </code> refers to a valid, installed plugin - the substitution string
- * is terminated by a closing "$" If the above conditions are not met,
- * no substitution occurs. If the above conditions are met, the content
- * between (and including) the opening and closing "$" characters will
- * be replaced by the absolute path to the plugin
- *
- * @return
- */
- protected String parsePluginId() {
- if (reader == null || tokenContent == null || pluginId == null)
- return null;
-
- try {
- // Mark the current position of the reader so we can roll
- // back to this point if the proper "plugin:" segment is not
- // found.
- // Use 1024 as our readAheadLimit
- reader.mark(0x400);
- if (findValidPluginSegment()) {
- String pluginPath = getPluginPath();
- if (pluginPath == null) {
- // Didn't find a valid plugin id.
- // return tokenContent, which contains all characters
- // read up to (not including) the last $. (if the
- // last $ is part of a subsequent "$plugin:" segment
- // it can still be processed properly)
- return tokenContent.toString();
- }
- return pluginPath;
- }
-
- // The "plugin:" segment was not found. Reset the reader
- // so we can continue reading character by character.
- reader.reset();
- return tokenContent.toString();
-
- } catch (IOException exception) {
- Log.error("Error reading from file", exception); //$NON-NLS-1$
- return tokenContent.toString();
- }
- }
-
- /**
- * This method should be called after an initial substitution character
- * has been found (that is, after a $). It looks at the subsequent
- * characters in the input stream to determine if they match the
- * expected <code>plugin:</code> segment of the substitution string.
- * If the expected characters are found, they will be appended to the
- * tokenContent StringBuffer and the method will return true. If they
- * are not found, false is returned and the caller should reset the
- * BufferedReader to the position it was in before this method was
- * called.
- *
- * Resetting the reader ensures that the characters read in this method
- * can be re-examined in case one of them happens to be the beginning of
- * a valid substitution segment.
- *
- * @return true if the next characters match <code>plugin:</code>,
- * and false otherwise.
- */
- private boolean findValidPluginSegment() {
- final char[] PLUGIN_SEGMENT = { 'p', 'l', 'u', 'g', 'i', 'n', ':' };
- char[] streamContent = new char[PLUGIN_SEGMENT.length];
- try {
- int peek = reader.read(streamContent, 0, PLUGIN_SEGMENT.length);
- if ((peek == PLUGIN_SEGMENT.length)
- && (HTMLUtil.equalCharArrayContent(streamContent,
- PLUGIN_SEGMENT))) {
- // we have found the "$plugin:" segment
- tokenContent.append(streamContent);
- return true;
- }
- // The "plugin:" segment did not immediately follow the initial
- // $.
- return false;
- } catch (IOException exception) {
- Log.error("Error reading from file", exception); //$NON-NLS-1$
- return false;
- }
- }
-
- /**
- * This method continues to read from the input stream until either the
- * end of the file is reached, or until a character is found that
- * indicates the end of the substitution. If the SUBSTITUTION_END
- * character is found, the method looks up the plugin id that has been
- * built up to see if it is a valid id. If so, return the absolute path
- * to that plugin. If not, return null.
- *
- * This method assumes that the reader is positioned just after a valid
- * <code>plugin:</code> segment in a substitution string.
- *
- * @return absolute path of the plugin id, if valid. null otherwise
- */
- private String getPluginPath() {
- try {
- while (true) {
- int nextChar = reader.read();
-
- if (nextChar == -1) {
- // reached EOF while looking for closing $
- return null;
- } else if (nextChar == SUBSTITUTION_END) { // end of plugin
- // id
- // look up the plugin id. If it is a valid id
- // return the absolute path to this plugin.
- // otherwise return null.
- String path = BundleUtil
- .getResolvedBundleLocation(pluginId.toString());
-
- // If the plugin id was not valid, reset reader to the
- // previous mark. The mark should be at the character
- // just before the last dollar sign.
- if (path == null)
- reader.reset();
-
- return path;
- } else { // we have a regular character
- // mark the most recent non-dollar char in case we don't
- // find a valid plugin id and have to roll back
- // Use 1024 as our readAheadLimit
- reader.mark(0x400);
- // Add this character to the pluginId and tokenContent
- // String.
- // make sure we have a valid character before performing
- // cast
- if (nextChar > 0x00 && nextChar < 0xffff) {
- tokenContent.append((char) nextChar);
- // only include non-whitespace characters in plugin
- // id
- if (!Character.isWhitespace((char) nextChar))
- pluginId.append((char) nextChar);
- } else {
- tokenContent.append(nextChar);
- pluginId.append(nextChar);
- }
- }
- }
- } catch (IOException exception) {
- Log.error("Error reading from file", exception); //$NON-NLS-1$
- return null;
- }
- }
- }
+ private AbstractIntroPage introPage;
+
+ private IIntroContentProviderSite providerSite;
+
+ /**
+ * Generates the HTML code that will be presented in the browser widget for the provided intro
+ * page.
+ *
+ * @param page
+ * the page to generate HTML for
+ * @param presentation
+ * the presentation associated with this page.
+ */
+ public HTMLElement generateHTMLforPage(AbstractIntroPage page, IIntroContentProviderSite providerSite) {
+ if (page == null)
+ return null;
+ this.introPage = page;
+ this.providerSite = providerSite;
+
+ // generate and add the appropriate encoding to the top of the document
+ // generateEncoding();
+ // create the main HTML element, and all of its contents.
+ return generateHTMLElement();
+ }
+
+ /*
+ * private HTMLElement generateEncoding() { HTMLElement encoding = new HTMLElement("");
+ * //$NON-NLS-1$ // TODO: figure out how to handle locale based encoding // As far as the HTML
+ * generator is concerned, this is probably as // simple as asking the model for the information
+ * return encoding; }
+ */
+
+ /**
+ * Generates the HTML element and its content:
+ *
+ * <pre>
+ *
+ * &lt;HTML&gt;
+ * &lt;HEAD&gt;
+ * head content
+ * &lt;/HEAD&gt;
+ * &lt;BODY&gt;
+ * body content
+ * &lt;/BODY&gt;
+ * &lt;/HTML&gt;
+ *
+ * </pre>
+ *
+ * @return the html HTMLElement
+ */
+ private HTMLElement generateHTMLElement() {
+ // this is the outermost element, so it has no indent
+ int indentLevel = 0;
+ HTMLElement html = new FormattedHTMLElement(IIntroHTMLConstants.ELEMENT_HTML, indentLevel, true);
+ HTMLElement head = generateHeadElement(indentLevel + 1);
+ HTMLElement body = generateBodyElement(indentLevel + 1, head);
+ html.addContent(head);
+ html.addContent(body);
+ return html;
+ }
+
+ /**
+ * Generates the HEAD element and its content:
+ *
+ * <pre>
+ *
+ *
+ * &lt;HEAD&gt;
+ * &lt;BASE href=&quot;base_plugin_location&gt;
+ * &lt;style type=&quot;text/css&quot;&gt;HTML, IMG { border: 0px; } &lt;/style&gt;
+ * &lt;TITLE&gt;page title &lt;/TITLE&gt;
+ * &lt;LINK href=&quot;style sheet&quot;&gt;
+ * additional head content, if specified
+ * &lt;/HEAD&gt;
+ *
+ * </pre>
+ *
+ * @param indentLevel
+ * the number of indents to insert before the element when it is printed
+ * @return the head HTMLElement
+ */
+ private HTMLElement generateHeadElement(int indentLevel) {
+ HTMLElement head = new FormattedHTMLElement(IIntroHTMLConstants.ELEMENT_HEAD, indentLevel, true);
+ // add the title
+ head.addContent(generateTitleElement(null, indentLevel + 1));
+ // create the BASE element
+ String basePath = BundleUtil.getResolvedResourceLocation(introPage.getBase(), introPage.getBundle());
+ HTMLElement base = generateBaseElement(indentLevel + 1, basePath);
+ if (base != null)
+ head.addContent(base);
+ // create the HTML style block
+ head.addContent(generateStyleElement(indentLevel + 1));
+ // add the presentation style
+ String style = IntroPlugin.getDefault().getIntroModelRoot().getPresentation()
+ .getImplementationStyle();
+ if (style != null && introPage.injectSharedStyle())
+ head.addContent(generateLinkElement(style, indentLevel + 1));
+ style = introPage.getStyle();
+ if (style != null)
+ head.addContent(generateLinkElement(style, indentLevel + 1));
+ // add javascript
+ head.addContent(generateJavascriptElement(indentLevel + 1));
+
+ // add the page's inherited style(s)
+ String[] pageStyles = introPage.getStyles();
+ for (int i = 0; i < pageStyles.length; i++) {
+ style = pageStyles[i];
+ if (style != null)
+ head.addContent(generateLinkElement(style, indentLevel + 1));
+ }
+ // if there is additional head conent specified in an external file,
+ // include it. Additional head content can be specified at the
+ // implementation level (which would apply to ALL pages) and at the
+ // page level (which would apply only to that particular page).
+ // For the implementation's head contribution:
+ StringBuffer content = null;
+ IntroHead introHead = IntroPlugin.getDefault().getIntroModelRoot().getPresentation().getHead();
+ if (introHead != null) {
+ content = readFromFile(introHead.getSrc(), introHead.getInlineEncoding());
+ if (content != null)
+ head.addContent(content);
+ }
+ // For the page's head contribution:
+ // TODO: there should only be one of these at the page level, not a
+ // collection..
+ IntroHead[] htmlHeads = introPage.getHTMLHeads();
+ for (int i = 0; i < htmlHeads.length; i++) {
+ introHead = htmlHeads[i];
+ if (introHead != null) {
+ content = readFromFile(introHead.getSrc(), introHead.getInlineEncoding());
+ if (content != null)
+ head.addContent(content);
+ }
+ }
+ return head;
+ }
+
+ private HTMLElement generateJavascriptElement(int indentLevel) {
+ String rel = "javascript/common.js"; //$NON-NLS-1$
+ String abs = BundleUtil.getResolvedResourceLocation(rel, IntroPlugin.getDefault().getBundle());
+ HTMLElement jselement = new FormattedHTMLElement("script", indentLevel, false); //$NON-NLS-1$
+ jselement.addAttribute("type", "text/javascript"); //$NON-NLS-1$ //$NON-NLS-2$
+ jselement.addAttribute("src", abs); //$NON-NLS-1$
+ return jselement;
+ }
+
+ /**
+ * Generates the BODY element and its content:
+ *
+ * <pre>
+ *
+ *
+ * &lt;BODY&gt;
+ * &lt;DIV id=&quot;pageId&quot; class=&quot;pageClass&quot;&gt;
+ * page content
+ * &lt;/DIV&gt;
+ * &lt;/BODY&gt;
+ *
+ * </pre>
+ *
+ * @param indentLevel
+ * the number of indents to insert before the element when it is printed
+ * @return the body HTMLElement
+ */
+ private HTMLElement generateBodyElement(int indentLevel, HTMLElement head) {
+ HTMLElement body = new FormattedHTMLElement(IIntroHTMLConstants.ELEMENT_BODY, indentLevel, true);
+ // Create the div that contains the page content
+ String pageId = (introPage.getId() != null) ? introPage.getId() : IIntroHTMLConstants.DIV_ID_PAGE;
+ HTMLElement pageContentDiv = generateDivElement(pageId, indentLevel + 1);
+ if (introPage.getStyleId() != null)
+ pageContentDiv.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS, introPage.getStyleId());
+ if (introPage.getBackgroundImage() != null)
+ pageContentDiv.addAttribute(IIntroHTMLConstants.ATTRIBUTE_STYLE,
+ "background-image : url(" + introPage.getBackgroundImage() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
+
+ // Add any children of the page, in the order they are defined
+ AbstractIntroElement[] children = introPage.getChildren();
+ for (int i = 0; i < children.length; i++) {
+ AbstractIntroElement child = children[i];
+ // use indentLevel + 2 here, since this element is contained within
+ // the pageContentDiv
+ HTMLElement childElement = generateIntroElement(child, indentLevel + 2);
+ if (childElement != null) {
+ addMixinStyle(childElement, child.getMixinStyle());
+ pageContentDiv.addContent(childElement);
+ }
+ }
+ body.addContent(pageContentDiv);
+ return body;
+ }
+
+ /**
+ * Given an IntroElement, generate the appropriate HTMLElement
+ *
+ * @param element
+ * the IntroElement
+ * @param indentLevel
+ * the number of indents to insert before the element when it is printed
+ * @return an HTMLElement
+ */
+ private HTMLElement generateIntroElement(AbstractIntroElement element, int indentLevel) {
+ if (element == null)
+ return null;
+ // check to see if this element should be filtered from the HTML
+ // presentation
+ if (filteredFromPresentation(element))
+ return null;
+ switch (element.getType()) {
+ case AbstractIntroElement.GROUP:
+ return generateIntroDiv((IntroGroup) element, indentLevel);
+ case AbstractIntroElement.LINK:
+ return generateIntroLink((IntroLink) element, indentLevel);
+ case AbstractIntroElement.HTML:
+ return generateIntroHTML((IntroHTML) element, indentLevel);
+ case AbstractIntroElement.CONTENT_PROVIDER:
+ return generateIntroContent((IntroContentProvider) element, indentLevel);
+ case AbstractIntroElement.IMAGE:
+ return generateIntroImage((IntroImage) element, indentLevel);
+ case AbstractIntroElement.TEXT:
+ return generateIntroText((IntroText) element, indentLevel);
+ case AbstractIntroElement.PAGE_TITLE:
+ return generateIntroTitle((IntroPageTitle) element, indentLevel);
+ case AbstractIntroElement.INJECTED_IFRAME:
+ return generateIntroInjectedIFrame((IntroInjectedIFrame) element, indentLevel);
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Create a div element and its content from an IntroDiv:
+ *
+ * <pre>
+ *
+ *
+ * &lt;div id=&quot;attrvalue&quot;&gt;
+ * &lt;h4&gt;&lt;span class=&quot;div-label&quot;&gt;attrvalue&lt;/span&gt;&lt;h4&gt;
+ * any defined divs, links, html, images, text, includes
+ * &lt;/div&gt;
+ *
+ * </pre>
+ *
+ * @param element
+ * the IntroDiv
+ * @param indentLevel
+ * the number of indents to insert before the element when it is printed
+ * @return a div HTMLElement
+ */
+ private HTMLElement generateIntroDiv(IntroGroup element, int indentLevel) {
+ // Create the outer div element
+ HTMLElement divElement = generateDivElement(element.getId(), indentLevel);
+ HTMLElement childContainer = divElement;
+ // if a div class was specified, add it
+ if (element.getStyleId() != null)
+ divElement.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS, element.getStyleId());
+ // Create the div label, if specified
+ if (element.getLabel() != null) {
+ HTMLElement divLabel = generateTextElement(IIntroHTMLConstants.ELEMENT_H4, null,
+ IIntroHTMLConstants.SPAN_CLASS_DIV_LABEL, element.getLabel(), indentLevel + 1);
+ if (element.isExpandable()) {
+ String clientId = element.getId()+"-content"; //$NON-NLS-1$
+ String href = "#"; //$NON-NLS-1$
+ HTMLElement link = new FormattedHTMLElement(IIntroHTMLConstants.ELEMENT_ANCHOR,
+ indentLevel + 1, true);
+ link.addAttribute(IIntroHTMLConstants.ATTRIBUTE_HREF, href);
+ String call = "return (toggleSection('" + clientId + "'))"; //$NON-NLS-1$ //$NON-NLS-2$
+ link.addAttribute("onClick", call); //$NON-NLS-1$
+ link.addContent(divLabel);
+ divElement.addContent(link);
+ childContainer = generateDivElement(clientId, indentLevel+1);
+ childContainer.addAttribute("class", "section-body"); //$NON-NLS-1$//$NON-NLS-2$
+ divElement.addContent(childContainer);
+ } else
+ divElement.addContent(divLabel);
+ }
+ if (element.getBackgroundImage() != null) {
+ String imageUrl = element.getBackgroundImage();
+ imageUrl = BundleUtil.getResolvedResourceLocation(element.getBase(), imageUrl, element
+ .getBundle());
+ String style;
+ if (Platform.getWS().equals(Platform.WS_WIN32) && imageUrl.toLowerCase().endsWith(".png")) { //$NON-NLS-1$
+ // IE 5.5+ does not handle alphas in PNGs without
+ // this hack. Remove when IE7 becomes widespread
+ style = "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + imageUrl + "', sizingMethod='crop');"; //$NON-NLS-1$ //$NON-NLS-2$
+ } else {
+ style = "background-image : url(" + imageUrl + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ divElement.addAttribute(IIntroHTMLConstants.ATTRIBUTE_STYLE, style);
+ }
+ // Add any children of the div, in the order they are defined
+ AbstractIntroElement[] children = element.getChildren();
+ for (int i = 0; i < children.length; i++) {
+ AbstractIntroElement child = children[i];
+ HTMLElement childElement = generateIntroElement(child, indentLevel + 1);
+ if (childElement != null) {
+ addMixinStyle(childElement, child.getMixinStyle());
+ childContainer.addContent(childElement);
+ }
+ }
+ return divElement;
+ }
+
+ private void addMixinStyle(HTMLElement element, String mixinStyle) {
+ if (mixinStyle==null)
+ return;
+ String key = "class"; //$NON-NLS-1$
+ String original = (String)element.getElementAttributes().get(key);
+ if (original==null)
+ original = mixinStyle;
+ else
+ original += " "+mixinStyle; //$NON-NLS-1$
+ element.addAttribute(key, original);
+ }
+
+ /**
+ * Generates an anchor (link) element and its content from an IntroLink:
+ *
+ * <pre>
+ *
+ * &lt;A id=linkId class=&quot;link&quot; href=linkHref&gt;
+ * &lt;IMG src=&quot;blank.gif&quot;&gt;
+ * &lt;SPAN class=&quot;link-label&quot;&gt;linkLabel &lt;/SPAN&gt;
+ * &lt;P&gt;&lt;SPAN&gt;text&lt;/SPAN&gt;&lt;/P&gt;
+ * &lt;/A&gt;
+ *
+ * </pre>
+ *
+ * @param element
+ * the IntroLink
+ * @param indentLevel
+ * the number of indents to insert before the element when it is printed
+ * @return an anchor (&lt;A&gt;) HTMLElement
+ */
+ private HTMLElement generateIntroLink(IntroLink element, int indentLevel) {
+ HTMLElement anchor = generateAnchorElement(element, indentLevel);
+ // add <IMG src="blank.gif">
+ String blankImageURL = BundleUtil.getResolvedResourceLocation(IIntroHTMLConstants.IMAGE_SRC_BLANK,
+ IIntroConstants.PLUGIN_ID);
+ if (blankImageURL != null) {
+ anchor.addContent(generateImageElement(blankImageURL, null, IIntroHTMLConstants.IMAGE_CLASS_BG,
+ indentLevel + 1));
+ }
+ // add link image, if one is specified
+ if (element.getImg() != null) {
+ HTMLElement img = generateIntroElement(element.getImg(), indentLevel + 1);
+ if (img != null)
+ anchor.addContent(img);
+ }
+ // add <SPAN class="link-label">linkLabel</SPAN>
+ if (element.getLabel() != null) {
+ HTMLElement label = generateSpanElement(IIntroHTMLConstants.SPAN_CLASS_LINK_LABEL,
+ indentLevel + 1);
+ label.addContent(element.getLabel());
+ anchor.addContent(label);
+ }
+ IntroText linkText = element.getIntroText();
+ if (linkText != null && linkText.getText() != null) {
+ HTMLElement text = generateIntroElement(linkText, indentLevel + 1);
+ if (text != null)
+ anchor.addContent(text);
+ }
+ return anchor;
+ }
+
+ /**
+ * Generate the appropriate HTML from an IntroHTML. If the IntroHTML type is "inline", then the
+ * content from the referenced file is emitted as-is into a div element. If the type is "embed",
+ * an OBJECT html element is created whose <code>data</code> attribute is equal to the
+ * IntroHTML's <code>src</code> value
+ *
+ * @param element
+ * the IntroHTML
+ * @param indentLevel
+ * the number of indents to insert before the element when it is printed
+ * @return an HTMLElement
+ */
+ private HTMLElement generateIntroHTML(IntroHTML element, int indentLevel) {
+ if (element.isInlined())
+ return generateInlineIntroHTML(element, indentLevel);
+
+ return generateEmbeddedIntroHTML(element, indentLevel);
+ }
+
+ /**
+ * Generate an image element from an IntroImage:
+ *
+ * <pre>
+ *
+ * &lt;IMG src=imageSrc id=imageId&gt;
+ *
+ * </pre>
+ *
+ * @param element
+ * the IntroImage
+ * @param indentLevel
+ * the number of indents to insert before the element when it is printed
+ * @return an img HTMLElement
+ */
+ private HTMLElement generateIntroImage(IntroImage element, int indentLevel) {
+ HTMLElement imageElement = generateImageElement(element.getSrc(), element.getAlt(), element
+ .getStyleId(), indentLevel);
+ if (element.getId() != null)
+ imageElement.addAttribute(IIntroHTMLConstants.ATTRIBUTE_ID, element.getId());
+ return imageElement;
+ }
+
+ /**
+ * Generate a paragraph (&lt;P&gt;) element from an IntroText. The paragraph element will
+ * contain a span element that will contain the actual text. Providing the span element provides
+ * additional flexibility for CSS designers.
+ *
+ * <pre>
+ *
+ *
+ * &lt;P&gt;&lt;SPAN&gt;spanContent&lt;/SPAN&gt;&lt;/P&gt;
+ *
+ * </pre>
+ *
+ * @param element
+ * the IntroText
+ * @param indentLevel
+ * the number of indents to insert before the element when it is printed
+ * @return a paragraph HTMLElement
+ */
+ private HTMLElement generateIntroText(IntroText element, int indentLevel) {
+ String spanClass = (element.getStyleId() != null) ? element.getStyleId()
+ : IIntroHTMLConstants.SPAN_CLASS_TEXT;
+ HTMLElement textElement = generateTextElement(IIntroHTMLConstants.ELEMENT_PARAGRAPH, element.getId(),
+ spanClass, element.getText(), indentLevel);
+ return textElement;
+ }
+
+ /**
+ * @param element
+ * @param indentLevel
+ * @return
+ */
+ private HTMLElement generateIntroInjectedIFrame(IntroInjectedIFrame element, int indentLevel) {
+ HTMLElement iframe = generateIFrameElement(element.getIFrameURL(), "0", //$NON-NLS-1$
+ "auto", indentLevel); //$NON-NLS-1$
+ return iframe;
+ }
+
+ /**
+ * @param element
+ * @param indentLevel
+ * @return
+ */
+ private HTMLElement generateIntroTitle(IntroPageTitle element, int indentLevel) {
+ HTMLElement titleElement = generateHeaderDiv(element.getId(), element.getStyleId(),
+ IIntroHTMLConstants.ELEMENT_H1, element.getTitle(), indentLevel);
+ return titleElement;
+ }
+
+ /**
+ * Generate "inline" content from an IntroHTML. The content from the file referenced by the
+ * IntroHTML's <code>src</code> attribute is emitted as-is into a div element:
+ *
+ * <pre>
+ *
+ *
+ * &lt;div id=&quot;attrvalue&quot; class=&quot;attrvalue2&quot;&gt;
+ * content from file specified in src attribute
+ * &lt;/div&gt;
+ *
+ * </pre>
+ *
+ * @param element
+ * the IntroHTML
+ * @param indentLevel
+ * the number of indents to insert before the element when it is printed
+ * @return a div HTMLElement, or null if there was a problem reading from the file
+ */
+ private HTMLElement generateInlineIntroHTML(IntroHTML element, int indentLevel) {
+ // make sure to ask model for encoding. If encoding is null (ie: not
+ // specified in
+ // markup, local encoding is used.
+ StringBuffer content = readFromFile(element.getSrc(), element.getInlineEncoding());
+ if (content != null && content.length() > 0) {
+ // Create the outer div element
+ String divClass = (element.getStyleId() != null) ? element.getStyleId()
+ : IIntroHTMLConstants.DIV_CLASS_INLINE_HTML;
+ HTMLElement divElement = generateDivElement(element.getId(), divClass, indentLevel);
+ // add the content of the specified file into the div element
+ divElement.addContent(content);
+ return divElement;
+ }
+ return null;
+ }
+
+ /**
+ * Includes HTML content that is created by an IIntroContentProvider implementation.
+ *
+ * @param element
+ * @param indentLevel
+ * @return
+ */
+ private HTMLElement generateIntroContent(IntroContentProvider element, int indentLevel) {
+ // create a new div to wrap the content
+ HTMLElement divElement = generateDivElement(element.getId(),
+ IIntroHTMLConstants.DIV_CLASS_PROVIDED_CONTENT, indentLevel);
+
+ // If we've already loaded the content provider for this element,
+ // retrieve it, otherwise load the class
+ IIntroContentProvider providerClass = ContentProviderManager.getInst().getContentProvider(element);
+ if (providerClass == null)
+ // content provider never created before, create it.
+ providerClass = ContentProviderManager.getInst().createContentProvider(element, providerSite);
+
+ if (providerClass != null) {
+ StringWriter stringWriter = new StringWriter();
+ PrintWriter pw = new PrintWriter(stringWriter);
+ // create the specialized content
+ providerClass.createContent(element.getId(), pw);
+ // add the content of the specified file into the div element
+ stringWriter.flush();
+ divElement.addContent(stringWriter.toString());
+ pw.close();
+ } else {
+ // we couldn't load the content provider, so add any alternate
+ // text content if there is any
+ IntroText htmlText = element.getIntroText();
+ if (htmlText != null && htmlText.getText() != null) {
+ String textClass = (htmlText.getStyleId() != null) ? htmlText.getStyleId()
+ : IIntroHTMLConstants.SPAN_CLASS_TEXT;
+ HTMLElement text = generateTextElement(IIntroHTMLConstants.ELEMENT_PARAGRAPH, htmlText
+ .getId(), textClass, element.getText(), indentLevel);
+ if (text != null)
+ divElement.addContent(text);
+ }
+ }
+ return divElement;
+ }
+
+ /**
+ * Generate "embedded" content from an IntroHTML. An OBJECT html element is created whose
+ * <code>data</code> attribute is equal to the IntroHTML's <code>src</code> value.
+ *
+ * <pre>
+ *
+ * &lt;OBJECT type=&quot;text/html&quot; data=&quot;attrvalue&quot;&gt;
+ * alternative text in case the object can not be rendered
+ * &lt;/OBJECT&gt;
+ *
+ * </pre>
+ *
+ * @param element
+ * the IntroHTML
+ * @param indentLevel
+ * the number of indents to insert before the element when it is printed
+ * @return an object HTMLElement
+ */
+ private HTMLElement generateEmbeddedIntroHTML(IntroHTML element, int indentLevel) {
+ HTMLElement objectElement = new FormattedHTMLElement(IIntroHTMLConstants.ELEMENT_OBJECT, indentLevel,
+ true);
+ objectElement.addAttribute(IIntroHTMLConstants.ATTRIBUTE_TYPE, IIntroHTMLConstants.OBJECT_TYPE);
+ if (element.getId() != null)
+ objectElement.addAttribute(IIntroHTMLConstants.ATTRIBUTE_ID, element.getId());
+ if (element.getSrc() != null)
+ objectElement.addAttribute(IIntroHTMLConstants.ATTRIBUTE_DATA, element.getSrc());
+ if (element.getStyleId() != null)
+ objectElement.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS, element.getStyleId());
+ // The alternative content is added in case the browser can not render
+ // the specified content.
+ IntroText htmlText = element.getIntroText();
+ if (htmlText != null && htmlText.getText() != null) {
+ String textClass = (htmlText.getStyleId() != null) ? htmlText.getStyleId()
+ : IIntroHTMLConstants.SPAN_CLASS_TEXT;
+ HTMLElement text = generateTextElement(IIntroHTMLConstants.ELEMENT_PARAGRAPH, htmlText.getId(),
+ textClass, element.getText(), indentLevel);
+ if (text != null)
+ objectElement.addContent(text);
+ }
+ if (element.getIntroImage() != null) {
+ HTMLElement img = generateIntroImage(element.getIntroImage(), indentLevel);
+ if (img != null)
+ objectElement.addContent(img);
+ }
+ return objectElement;
+ }
+
+ /**
+ * Generates the BASE element for the head of the html document. Each document can have only one
+ * base element
+ *
+ * <pre>
+ *
+ *
+ * &lt;BASE href=baseURL&gt;
+ * </pre>
+ *
+ * @param indentLevel
+ * @param baseURL
+ * @return
+ */
+ private HTMLElement generateBaseElement(int indentLevel, String baseURL) {
+ HTMLElement base = new FormattedHTMLElement(IIntroHTMLConstants.ELEMENT_BASE, indentLevel, true,
+ false);
+ if (baseURL != null)
+ base.addAttribute(IIntroHTMLConstants.ATTRIBUTE_HREF, baseURL);
+ return base;
+ }
+
+ /**
+ * Generates the style element that goes into HEAD:
+ *
+ * <pre>
+ *
+ * &lt;style type=&quot;text/css&quot;&gt;HTML, IMG { border: 0px; } &lt;/style&gt;
+ *
+ * </pre>
+ *
+ * @param indentLevel
+ * the number of indents to insert before the element when it is printed
+ * @return the style HTMLElement
+ */
+ private HTMLElement generateStyleElement(int indentLevel) {
+ HTMLElement style = new FormattedHTMLElement(IIntroHTMLConstants.ELEMENT_STYLE, indentLevel, false);
+ style.addAttribute(IIntroHTMLConstants.ATTRIBUTE_TYPE, IIntroHTMLConstants.LINK_STYLE);
+ style.addContent(IIntroHTMLConstants.STYLE_HTML);
+ return style;
+ }
+
+ /**
+ * Generates the title element and its content:
+ *
+ * <pre>
+ *
+ * &lt;TITLE&gt;intro title&lt;/TITLE&gt;
+ *
+ * </pre>
+ *
+ * @param title
+ * the title of this intro page
+ * @param indentLevel
+ * the number of indents to insert before the element when it is printed
+ * @return the title HTMLElement
+ */
+ private HTMLElement generateTitleElement(String title, int indentLevel) {
+ HTMLElement titleElement = new FormattedHTMLElement(IIntroHTMLConstants.ELEMENT_TITLE, indentLevel,
+ false);
+ if (title != null)
+ titleElement.addContent(title);
+ return titleElement;
+ }
+
+ /**
+ * Generates a link element that refers to a cascading style sheet (CSS):
+ *
+ * <pre>
+ *
+ *
+ * &lt;LINK rel=&quot;stylesheet&quot; style=&quot;text/css&quot; href=&quot;style sheet&quot;&gt;
+ * </pre>
+ *
+ * @param href
+ * the value of the href attribute for this link element
+ * @param indentLevel
+ * the number of indents to insert before the element when it is printed
+ * @return a link HTMLElement
+ */
+ private HTMLElement generateLinkElement(String href, int indentLevel) {
+ HTMLElement link = new FormattedHTMLElement(IIntroHTMLConstants.ELEMENT_LINK, indentLevel, true,
+ false);
+ link.addAttribute(IIntroHTMLConstants.ATTRIBUTE_RELATIONSHIP, IIntroHTMLConstants.LINK_REL);
+ link.addAttribute(IIntroHTMLConstants.ATTRIBUTE_STYLE, IIntroHTMLConstants.LINK_STYLE);
+ if (href != null)
+ link.addAttribute(IIntroHTMLConstants.ATTRIBUTE_HREF, href);
+ return link;
+ }
+
+ /**
+ * Generate an anchor element:
+ *
+ * <pre>
+ *
+ * &lt;A id=linkId class=linkClass href=linkHref&gt; &lt;/A&gt;
+ *
+ * </pre>
+ *
+ * @param link
+ * the IntroLink element that contains the value for the id and href attributes
+ * @param indentLevel
+ * the number of indents to insert before the element when it is printed
+ * @return an anchor (&lt;A&gt;) HTMLElement
+ */
+ private HTMLElement generateAnchorElement(IntroLink link, int indentLevel) {
+ HTMLElement anchor = new FormattedHTMLElement(IIntroHTMLConstants.ELEMENT_ANCHOR, indentLevel, true);
+ if (link.getId() != null)
+ anchor.addAttribute(IIntroHTMLConstants.ATTRIBUTE_ID, link.getId());
+ if (link.getUrl() != null)
+ anchor.addAttribute(IIntroHTMLConstants.ATTRIBUTE_HREF, link.getUrl());
+ if (link.getStyleId() != null)
+ anchor.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS, link.getStyleId());
+ else
+ anchor.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS, IIntroHTMLConstants.ANCHOR_CLASS_LINK);
+ return anchor;
+ }
+
+ /**
+ * Generates a div block that contains a header and span element:
+ *
+ * <pre>
+ *
+ *
+ * &lt;DIV id=divId&gt;
+ * &lt;H&gt;&lt;SPAN&gt;spanContent &lt;/SPAN&gt; &lt;/H&gt;
+ * &lt;/DIV&gt;
+ *
+ * </pre>
+ *
+ * @param divId
+ * the id of the div to create
+ * @param divClass
+ * the class of the div
+ * @param headerType
+ * what type of header to create (e.g., H1, H2, etc)
+ * @param spanContent
+ * the span content
+ * @param indentLevel
+ * the number of indents to insert before the element when it is printed
+ * @return a div HTMLElement that contains a header
+ */
+ private HTMLElement generateHeaderDiv(String divId, String divClass, String headerType,
+ String spanContent, int indentLevel) {
+ // create the text element: <P><SPAN>spanContent</SPAN></P>
+ HTMLElement text = generateTextElement(headerType, null, null, spanContent, indentLevel + 1);
+ // create the containing div element
+ HTMLElement div = generateDivElement(divId, divClass, indentLevel);
+ div.addContent(text);
+ return div;
+ }
+
+ /**
+ * Generates a span element inside a text element, where the text element can be a P
+ * (paragraph), or any of the H (Header) elements. Providing the span element provides
+ * additional flexibility for CSS designers.
+ *
+ * <pre>
+ *
+ * &lt;P&gt;&lt;SPAN&gt;spanContent&lt;/SPAN&gt;&lt;/P&gt;
+ *
+ * </pre>
+ *
+ * @param type
+ * the type of text element to create (e.g., P, H1, H2, etc)
+ * @param spanID
+ * the id of the span element, or null
+ * @param spanClass
+ * the class of the span element, or null
+ * @param spanContent
+ * the span content
+ * @param indentLevel
+ * the number of indents to insert before the element when it is printed
+ * @return a text HTMLElement that contains a span element
+ */
+ private HTMLElement generateTextElement(String type, String spanID, String spanClass, String spanContent,
+ int indentLevel) {
+ // Create the span: <SPAN>spanContent</SPAN>
+ HTMLElement span = new HTMLElement(IIntroHTMLConstants.ELEMENT_SPAN);
+ if (spanID != null)
+ span.addAttribute(IIntroHTMLConstants.ATTRIBUTE_ID, spanID);
+ if (spanClass != null)
+ span.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS, spanClass);
+ if (spanContent != null)
+ span.addContent(spanContent);
+ // Create the enclosing text element: <P><SPAN>spanContent</SPAN></P>
+ HTMLElement text = new FormattedHTMLElement(type, indentLevel, false);
+ text.addContent(span);
+ return text;
+ }
+
+ /**
+ * Generates a DIV element with the provided indent, id, and class.
+ *
+ * @param divId
+ * value for the div's id attribute
+ * @param divClass
+ * value for the div's class attribute
+ * @param indentLevel
+ * the number of indents to insert before the element when it is printed
+ * @return a div HTMLElement
+ */
+ private HTMLElement generateDivElement(String divId, String divClass, int indentLevel) {
+ HTMLElement div = generateDivElement(divId, indentLevel);
+ div.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS, divClass);
+ return div;
+ }
+
+ /**
+ * Generates a DIV element with the provided indent and id.
+ *
+ * @param divId
+ * value for the div's id attribute
+ * @param indentLevel
+ * the number of indents to insert before the element when it is printed
+ * @return a div HTMLElement
+ */
+ private HTMLElement generateDivElement(String divId, int indentLevel) {
+ HTMLElement div = new FormattedHTMLElement(IIntroHTMLConstants.ELEMENT_DIV, indentLevel, true);
+ if (divId != null)
+ div.addAttribute(IIntroHTMLConstants.ATTRIBUTE_ID, divId);
+ return div;
+ }
+
+ /**
+ * Generates an IMG element:
+ *
+ * <pre>
+ *
+ *
+ * &lt;IMG src=imageSrc alt=altText&gt;
+ *
+ * </pre>
+ *
+ * @param imageSrc
+ * the value to be supplied to the src attribute
+ * @param indentLevel
+ * the number of indents to insert before the element when it is printed
+ * @return an img HTMLElement
+ */
+ private HTMLElement generateImageElement(String imageSrc, String altText, String imageClass,
+ int indentLevel) {
+ HTMLElement image = new FormattedHTMLElement(IIntroHTMLConstants.ELEMENT_IMG, indentLevel, true,
+ false);
+ boolean pngOnWin32 = imageSrc != null && Platform.getWS().equals(Platform.WS_WIN32)
+ && imageSrc.toLowerCase().endsWith(".png"); //$NON-NLS-1$
+ if (imageSrc == null || pngOnWin32) {
+ // we must handle PNGs here - IE does not support alpha blanding well.
+ // We will set the alpha image loader and load the real image
+ // that way. The 'src' attribute in the image itself will
+ // get the blank image.
+ String blankImageURL = BundleUtil.getResolvedResourceLocation(
+ IIntroHTMLConstants.IMAGE_SRC_BLANK, IIntroConstants.PLUGIN_ID);
+ if (blankImageURL != null) {
+ image.addAttribute(IIntroHTMLConstants.ATTRIBUTE_SRC, blankImageURL);
+ if (pngOnWin32) {
+ String style = "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + imageSrc + "', sizingMethod='scale')"; //$NON-NLS-1$//$NON-NLS-2$
+ image.addAttribute(IIntroHTMLConstants.ATTRIBUTE_STYLE, style);
+ }
+ }
+ } else
+ image.addAttribute(IIntroHTMLConstants.ATTRIBUTE_SRC, imageSrc);
+ if (altText == null)
+ altText = ""; //$NON-NLS-1$
+ image.addAttribute(IIntroHTMLConstants.ATTRIBUTE_ALT, altText);
+ if (imageClass != null)
+ image.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS, imageClass);
+ return image;
+ }
+
+ /**
+ * Generate a span element
+ *
+ * <pre>
+ *
+ * &lt;SPAN class=spanClass&gt; &lt;/SPAN&gt;
+ *
+ *
+ * </pre>
+ *
+ * @param spanClass
+ * the value to be supplied to the class attribute
+ * @param indentLevel
+ * the number of indents to insert before the element when it is printed
+ * @return a span HTMLElement
+ */
+ private HTMLElement generateSpanElement(String spanClass, int indentLevel) {
+ HTMLElement span = new FormattedHTMLElement(IIntroHTMLConstants.ELEMENT_SPAN, indentLevel, false);
+ span.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS, spanClass);
+ return span;
+ }
+
+ /**
+ * Generate a span element
+ *
+ * <pre>
+ *
+ * &lt;iframe src=&quot;localPage1.xhtml&quot; frameborder=&quot;1&quot; scrolling=&quot;auto&quot; longdesc=&quot;localPage1.xhtml&quot;&gt;
+ * </pre>
+ *
+ * @param spanClass
+ * the value to be supplied to the class attribute
+ * @param indentLevel
+ * the number of indents to insert before the element when it is printed
+ * @return a span HTMLElement
+ */
+ private HTMLElement generateIFrameElement(String src, String frameborder, String scrolling,
+ int indentLevel) {
+ HTMLElement iframe = new FormattedHTMLElement(IIntroHTMLConstants.ELEMENT_IFrame, indentLevel, false);
+ if (src != null)
+ iframe.addAttribute(IIntroHTMLConstants.ATTRIBUTE_SRC, src);
+ if (frameborder != null)
+ iframe.addAttribute(IIntroHTMLConstants.ATTRIBUTE_FRAMEBORDER, frameborder);
+ if (scrolling != null)
+ iframe.addAttribute(IIntroHTMLConstants.ATTRIBUTE_SCROLLING, scrolling);
+ return iframe;
+ }
+
+
+
+
+ private boolean filteredFromPresentation(AbstractIntroElement element) {
+ if (element.isOfType(AbstractIntroElement.BASE_ELEMENT))
+ return ((AbstractBaseIntroElement) element).isFiltered();
+
+ return false;
+ }
+
+ /**
+ * Reads the content of the file referred to by the <code>src</code> parameter and returns the
+ * content in the form of a StringBuffer. If the file read contains substitution segments of the
+ * form $plugin:plugin_id$ then this method will make the proper substitution (the segment will
+ * be replaced with the absolute path to the plugin with id plugin_id).
+ *
+ * @param src -
+ * the file that contains the target conent
+ * @param charsetName -
+ * the encoding of the file to be read. If null, local encoding is used. But the
+ * default of the model is UTF-8, so we should not get a null encoding.
+ * @return a StringBuffer containing the content in the file, or null
+ */
+ private StringBuffer readFromFile(String src, String charsetName) {
+ if (src == null)
+ return null;
+ InputStream stream = null;
+ StringBuffer content = new StringBuffer();
+ BufferedReader reader = null;
+ try {
+ URL url = new URL(src);
+ stream = url.openStream();
+ // TODO: Do we need to worry about the encoding here? e.g.:
+ // reader = new BufferedReader(new InputStreamReader(stream,
+ // ResourcesPlugin.getEncoding()));
+ if (charsetName == null)
+ reader = new BufferedReader(new InputStreamReader(stream));
+ else
+ reader = new BufferedReader(new InputStreamReader(stream, charsetName));
+ while (true) {
+ int character = reader.read();
+ if (character == -1) // EOF
+ break; // done reading file
+
+ else if (character == PluginIdParser.SUBSTITUTION_BEGIN) { // possible
+ // substitution
+ PluginIdParser parser = new PluginIdParser(character, reader);
+ // If a valid plugin id was found in the proper format, text
+ // will be the absolute path to that plugin. Otherwise, text
+ // will simply be all characters read up to (but not
+ // including)
+ // the next dollar sign that follows the one just found.
+ String text = parser.parsePluginId();
+ if (text != null)
+ content.append(text);
+ } else {
+ // make sure character is in char range before making cast
+ if (character > 0x00 && character < 0xffff)
+ content.append((char) character);
+ else
+ content.append(character);
+ }
+ }
+ } catch (Exception exception) {
+ Log.error("Error reading from file", exception); //$NON-NLS-1$
+ } finally {
+ try {
+ if (reader != null)
+ reader.close();
+ if (stream != null)
+ stream.close();
+ } catch (IOException e) {
+ Log.error("Error closing input stream", e); //$NON-NLS-1$
+ return null;
+ }
+ }
+ return content;
+ }
+
+ /**
+ * A helper class to help identify substitution strings in a content file. A properly formatted
+ * substitution string is of the form: <code>$plugin:plugin_id$</code> where plugin_id is the
+ * valid id of an installed plugin. The substitution string will be replaced with the absolute
+ * path to the plugin.
+ *
+ * An example usage of the string substution: The html file <code>inline.html</code> is
+ * included in your intro via the html inline mechanism . This file needs to reference a
+ * resource that is located in another plugin. The following might be found in inline.html:
+ * <code>
+ * <a href="$plugin:test.plugin$html/test.html">link to file</a>
+ * </code> When this file
+ * is read in, the relevant section will be replaced as follows: <code>
+ * <a href="file:/install_path/plugins/test.plugin/html/test.html">link to file</a>
+ * </code>
+ *
+ */
+ private static class PluginIdParser {
+
+ private BufferedReader reader;
+
+ private static final char SUBSTITUTION_BEGIN = '$';
+
+ private static final char SUBSTITUTION_END = '$';
+
+ // tokenContent will contain all characters read by the parser, starting
+ // with and including the initial $ token.
+ private StringBuffer tokenContent;
+
+ // pluginId will contain the content between the "$plugin:" segment
+ // and the closing "$" token
+ private StringBuffer pluginId;
+
+ protected PluginIdParser(char tokenBegin, BufferedReader bufferedreader) {
+ reader = bufferedreader;
+ tokenContent = new StringBuffer(tokenBegin);
+ pluginId = new StringBuffer();
+ }
+
+ protected PluginIdParser(int tokenBegin, BufferedReader bufferedreader) {
+ reader = bufferedreader;
+ tokenContent = new StringBuffer();
+ pluginId = new StringBuffer();
+ // make sure tokenBegin is in char range before making cast
+ if (tokenBegin > 0x00 && tokenBegin < 0xffff)
+ tokenContent.append((char) tokenBegin);
+ }
+
+ /**
+ * This method should be called after the initial substitution identifier has been read in
+ * (the substition string begins and ends with the "$" character). A properly formatted
+ * substitution string is of the form:</code> "$plugin:plugin_id$</code>- the initial "$"
+ * is immediately followed by the "plugin:" segment - the <code>plugin_id </code> refers to
+ * a valid, installed plugin - the substitution string is terminated by a closing "$" If the
+ * above conditions are not met, no substitution occurs. If the above conditions are met,
+ * the content between (and including) the opening and closing "$" characters will be
+ * replaced by the absolute path to the plugin
+ *
+ * @return
+ */
+ protected String parsePluginId() {
+ if (reader == null || tokenContent == null || pluginId == null)
+ return null;
+
+ try {
+ // Mark the current position of the reader so we can roll
+ // back to this point if the proper "plugin:" segment is not
+ // found.
+ // Use 1024 as our readAheadLimit
+ reader.mark(0x400);
+ if (findValidPluginSegment()) {
+ String pluginPath = getPluginPath();
+ if (pluginPath == null) {
+ // Didn't find a valid plugin id.
+ // return tokenContent, which contains all characters
+ // read up to (not including) the last $. (if the
+ // last $ is part of a subsequent "$plugin:" segment
+ // it can still be processed properly)
+ return tokenContent.toString();
+ }
+ return pluginPath;
+ }
+
+ // The "plugin:" segment was not found. Reset the reader
+ // so we can continue reading character by character.
+ reader.reset();
+ return tokenContent.toString();
+
+ } catch (IOException exception) {
+ Log.error("Error reading from file", exception); //$NON-NLS-1$
+ return tokenContent.toString();
+ }
+ }
+
+ /**
+ * This method should be called after an initial substitution character has been found (that
+ * is, after a $). It looks at the subsequent characters in the input stream to determine if
+ * they match the expected <code>plugin:</code> segment of the substitution string. If the
+ * expected characters are found, they will be appended to the tokenContent StringBuffer and
+ * the method will return true. If they are not found, false is returned and the caller
+ * should reset the BufferedReader to the position it was in before this method was called.
+ *
+ * Resetting the reader ensures that the characters read in this method can be re-examined
+ * in case one of them happens to be the beginning of a valid substitution segment.
+ *
+ * @return true if the next characters match <code>plugin:</code>, and false otherwise.
+ */
+ private boolean findValidPluginSegment() {
+ final char[] PLUGIN_SEGMENT = { 'p', 'l', 'u', 'g', 'i', 'n', ':' };
+ char[] streamContent = new char[PLUGIN_SEGMENT.length];
+ try {
+ int peek = reader.read(streamContent, 0, PLUGIN_SEGMENT.length);
+ if ((peek == PLUGIN_SEGMENT.length)
+ && (HTMLUtil.equalCharArrayContent(streamContent, PLUGIN_SEGMENT))) {
+ // we have found the "$plugin:" segment
+ tokenContent.append(streamContent);
+ return true;
+ }
+ // The "plugin:" segment did not immediately follow the initial
+ // $.
+ return false;
+ } catch (IOException exception) {
+ Log.error("Error reading from file", exception); //$NON-NLS-1$
+ return false;
+ }
+ }
+
+ /**
+ * This method continues to read from the input stream until either the end of the file is
+ * reached, or until a character is found that indicates the end of the substitution. If the
+ * SUBSTITUTION_END character is found, the method looks up the plugin id that has been
+ * built up to see if it is a valid id. If so, return the absolute path to that plugin. If
+ * not, return null.
+ *
+ * This method assumes that the reader is positioned just after a valid <code>plugin:</code>
+ * segment in a substitution string.
+ *
+ * @return absolute path of the plugin id, if valid. null otherwise
+ */
+ private String getPluginPath() {
+ try {
+ while (true) {
+ int nextChar = reader.read();
+
+ if (nextChar == -1) {
+ // reached EOF while looking for closing $
+ return null;
+ } else if (nextChar == SUBSTITUTION_END) { // end of plugin
+ // id
+ // look up the plugin id. If it is a valid id
+ // return the absolute path to this plugin.
+ // otherwise return null.
+ String path = BundleUtil.getResolvedBundleLocation(pluginId.toString());
+
+ // If the plugin id was not valid, reset reader to the
+ // previous mark. The mark should be at the character
+ // just before the last dollar sign.
+ if (path == null)
+ reader.reset();
+
+ return path;
+ } else { // we have a regular character
+ // mark the most recent non-dollar char in case we don't
+ // find a valid plugin id and have to roll back
+ // Use 1024 as our readAheadLimit
+ reader.mark(0x400);
+ // Add this character to the pluginId and tokenContent
+ // String.
+ // make sure we have a valid character before performing
+ // cast
+ if (nextChar > 0x00 && nextChar < 0xffff) {
+ tokenContent.append((char) nextChar);
+ // only include non-whitespace characters in plugin
+ // id
+ if (!Character.isWhitespace((char) nextChar))
+ pluginId.append((char) nextChar);
+ } else {
+ tokenContent.append(nextChar);
+ pluginId.append(nextChar);
+ }
+ }
+ }
+ } catch (IOException exception) {
+ Log.error("Error reading from file", exception); //$NON-NLS-1$
+ return null;
+ }
+ }
+ }
}
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/AbstractIntroContainer.java b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/AbstractIntroContainer.java
index 345d4a8e0..7f46a9b02 100644
--- a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/AbstractIntroContainer.java
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/AbstractIntroContainer.java
@@ -228,7 +228,7 @@ public abstract class AbstractIntroContainer extends AbstractBaseIntroElement {
vector.copyInto(filteredElements);
// add the elements at the end children's vector.
insertElementsBefore(filteredElements, getBundle(), base, children
- .size());
+ .size(), null);
loaded = true;
// we cannot free DOM model element because a page's children may be
// nulled when reflowing a content provider.
@@ -241,13 +241,14 @@ public abstract class AbstractIntroContainer extends AbstractBaseIntroElement {
* @param childElements
*/
protected void insertElementsBefore(Element[] childElements, Bundle bundle,
- String base, int index) {
+ String base, int index, String mixinStyle) {
for (int i = 0; i < childElements.length; i++) {
Element childElement = childElements[i];
AbstractIntroElement child = getModelChild(childElement, bundle,
base);
if (child != null) {
child.setParent(this);
+ child.setMixinStyle(mixinStyle);
children.add(index, child);
// index is only incremented if we actually added a child.
index++;
@@ -262,12 +263,12 @@ public abstract class AbstractIntroContainer extends AbstractBaseIntroElement {
* @param childElements
*/
protected void insertElementsBefore(Element[] childElements, Bundle bundle,
- String base, AbstractIntroElement child) {
+ String base, AbstractIntroElement child, String mixinStyle) {
int childLocation = children.indexOf(child);
if (childLocation == -1)
// bad reference child.
return;
- insertElementsBefore(childElements, bundle, base, childLocation);
+ insertElementsBefore(childElements, bundle, base, childLocation, mixinStyle);
}
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/AbstractIntroElement.java b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/AbstractIntroElement.java
index 0c7a5290b..d841b225c 100644
--- a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/AbstractIntroElement.java
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/AbstractIntroElement.java
@@ -175,6 +175,7 @@ public abstract class AbstractIntroElement extends FilterableUAElement implement
private AbstractIntroElement parent;
private IConfigurationElement cfgElement;
private Bundle bundle;
+ private String mixinStyle;
/**
@@ -443,5 +444,17 @@ public abstract class AbstractIntroElement extends FilterableUAElement implement
}
+
+ public String getMixinStyle() {
+ return mixinStyle;
+ }
+
+
+
+ public void setMixinStyle(String mixinStyle) {
+ this.mixinStyle = mixinStyle;
+ }
+
+
} \ No newline at end of file
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/IntroGroup.java b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/IntroGroup.java
index a74900e4a..217b7a2a3 100644
--- a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/IntroGroup.java
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/IntroGroup.java
@@ -26,6 +26,7 @@ public class IntroGroup extends AbstractIntroContainer {
protected static final String TAG_GROUP = "group"; //$NON-NLS-1$
private static final String ATT_LABEL = "label"; //$NON-NLS-1$
private static final String ATT_COMPUTED = "computed"; //$NON-NLS-1$
+ private static final String ATT_EXPANDABLE = "expandable"; //$NON-NLS-1$
private String label;
/**
* @param element
@@ -51,6 +52,11 @@ public class IntroGroup extends AbstractIntroContainer {
return AbstractIntroElement.GROUP;
}
+ public boolean isExpandable() {
+ String value=getAttribute(element, ATT_EXPANDABLE);
+ return value!=null && value.equalsIgnoreCase("true"); //$NON-NLS-1$
+ }
+
protected void loadChildren() {
String value = getAttribute(element, ATT_COMPUTED);
if (value!=null && value.equalsIgnoreCase("true")) //$NON-NLS-1$
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/IntroModelRoot.java b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/IntroModelRoot.java
index f2671331a..0991d0e2a 100644
--- a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/IntroModelRoot.java
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/IntroModelRoot.java
@@ -579,8 +579,24 @@ public class IntroModelRoot extends AbstractIntroContainer {
AbstractIntroContainer anchorParent = (AbstractIntroContainer) anchor
.getParent();
// insert the elements of the extension before the anchor.
- anchorParent.insertElementsBefore(extensionContent.getChildren(),
- bundle, base, anchor);
+ String mixinStyle = getMixinStyle(extensionContent);
+ Element [] children = extensionContent.getChildren();
+ anchorParent.insertElementsBefore(children,
+ bundle, base, anchor, mixinStyle);
+ }
+
+ private String getMixinStyle(IntroExtensionContent extensionContent) {
+ String path = extensionContent.getPath();
+ if (!path.endsWith("/@")) //$NON-NLS-1$
+ return null;
+ String pageId = path.substring(0, path.length()-2);
+ IntroModelRoot modelRoot = getModelRoot();
+ if (modelRoot==null)
+ return null;
+ IntroConfigurer configurer = modelRoot.getConfigurer();
+ if (configurer==null)
+ return null;
+ return configurer.getMixinStyle(pageId, extensionContent.getId());
}
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/swt/PageWidgetFactory.java b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/swt/PageWidgetFactory.java
index 1714a163a..280bee1b1 100644
--- a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/swt/PageWidgetFactory.java
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/swt/PageWidgetFactory.java
@@ -188,10 +188,13 @@ public class PageWidgetFactory {
private Composite createGroup(Composite parent, IntroGroup group) {
String label = group.getLabel();
String description = styleManager.getDescription(group);
+ boolean expandable = group.isExpandable();
Composite client = null;
Composite control = null;
- if (description != null || label != null) {
+ if (description != null || label != null || expandable) {
int style = description != null ? Section.DESCRIPTION : SWT.NULL;
+ if (expandable)
+ style |= Section.TWISTIE | Section.FOCUS_TITLE | Section.CLIENT_INDENT;
Section section = toolkit.createSection(parent, style);
if (label != null)
section.setText(label);
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/universal/ExtensionData.java b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/universal/ExtensionData.java
index a17677bf0..3d2a45c79 100644
--- a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/universal/ExtensionData.java
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/universal/ExtensionData.java
@@ -24,6 +24,10 @@ public class ExtensionData {
ISharedIntroConstants.LOW, ISharedIntroConstants.MEDIUM, ISharedIntroConstants.HIGH,
ISharedIntroConstants.NEW };
+ public static final String[] IMPORTANCE_STYLE_TABLE = { ISharedIntroConstants.STYLE_CALLOUT,
+ ISharedIntroConstants.STYLE_LOW, ISharedIntroConstants.STYLE_MEDIUM, ISharedIntroConstants.STYLE_HIGH,
+ ISharedIntroConstants.STYLE_NEW };
+
public static final String [] IMPORTANCE_NAME_TABLE = { Messages.ExtensionData_callout,
Messages.ExtensionData_low, Messages.ExtensionData_medium, Messages.ExtensionData_high, Messages.ExtensionData_new };
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/universal/ISharedIntroConstants.java b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/universal/ISharedIntroConstants.java
index 2901091a9..9e3209e06 100644
--- a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/universal/ISharedIntroConstants.java
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/universal/ISharedIntroConstants.java
@@ -8,6 +8,12 @@ public interface ISharedIntroConstants {
String CALLOUT = "callout"; //$NON-NLS-1$
String HIDDEN = "hidden"; //$NON-NLS-1$
String NEW = "new"; //$NON-NLS-1$
+
+ String STYLE_LOW = "importance-low"; //$NON-NLS-1$
+ String STYLE_MEDIUM = "importance-medium"; //$NON-NLS-1$
+ String STYLE_HIGH = "importance-high"; //$NON-NLS-1$
+ String STYLE_CALLOUT = "importance-callout"; //$NON-NLS-1$
+ String STYLE_NEW = "importance-new"; //$NON-NLS-1$
String DEFAULT_ANCHOR = "defaultAnchor"; //$NON-NLS-1$
String DEFAULT_CONTENT_PATH = "/page-content/bottom/"+DEFAULT_ANCHOR; //$NON-NLS-1$
// Page ids
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/universal/PageData.java b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/universal/PageData.java
index e64c0e22e..b24fb5380 100644
--- a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/universal/PageData.java
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/universal/PageData.java
@@ -89,7 +89,7 @@ public class PageData {
}
return null;
}
-
+
private void addGroup(Element element, boolean hide) {
GroupData gd = new GroupData(element);
if (hide) hidden = gd;
@@ -98,7 +98,7 @@ public class PageData {
}
public void addImplicitExtension(String extensionId, String name) {
- ExtensionData ed = findExtension(extensionId);
+ ExtensionData ed = findExtension(extensionId, true);
if (ed!=null) {
// see if name needs to be supplied
if (ed.getName()==null || ed.getName().length()==0)
@@ -134,7 +134,7 @@ public class PageData {
return id;
}
- private ExtensionData findExtension(String extensionId) {
+ public ExtensionData findExtension(String extensionId, boolean checkHidden) {
for (int i=0; i<groups.size(); i++) {
GroupData gdata = (GroupData)groups.get(i);
ExtensionData ed = gdata.find(extensionId);
@@ -142,7 +142,7 @@ public class PageData {
return ed;
}
// check the hidden
- if (hidden!=null)
+ if (checkHidden && hidden!=null)
return hidden.find(extensionId);
return null;
}
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/universal/UniversalIntroConfigurer.java b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/universal/UniversalIntroConfigurer.java
index 92f1341bb..8ebecc8aa 100644
--- a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/universal/UniversalIntroConfigurer.java
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/universal/UniversalIntroConfigurer.java
@@ -71,6 +71,25 @@ public class UniversalIntroConfigurer extends IntroConfigurer implements IShared
return null;
}
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.intro.config.IntroConfigurer#getMixinStyle(java.lang.String)
+ */
+ public String getMixinStyle(String pageId, String extensionId) {
+ if (introData.size()>0) {
+ // TODO getting the active product one only
+ // Eventually we should consult the data from all the products
+ IntroData idata = (IntroData) introData.get(0);
+ PageData pdata = idata.getPage(pageId);
+ if (pdata != null) {
+ ExtensionData ed = pdata.findExtension(extensionId, false);
+ int importance = ed.getImportance();
+ if (importance!=ExtensionData.HIDDEN)
+ return ExtensionData.IMPORTANCE_STYLE_TABLE[importance];
+ }
+ }
+ return null;
+ }
+
private String resolveVariable(Bundle bundle, String value) {
if (value != null) {
String path = null;
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/intro/config/IntroConfigurer.java b/org.eclipse.ui.intro/src/org/eclipse/ui/intro/config/IntroConfigurer.java
index 4b5dca362..5f26db971 100644
--- a/org.eclipse.ui.intro/src/org/eclipse/ui/intro/config/IntroConfigurer.java
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/intro/config/IntroConfigurer.java
@@ -71,4 +71,20 @@ public abstract class IntroConfigurer {
* <code>null</code> if the path cannot be resolved or the extension should be hidden.
*/
public abstract String resolvePath(String extensionId, String path);
+
+ /**
+ * Returns the style value that will be mixed in with the original style of the extension.
+ * Themes can use this feature to render certain extensions differently.
+ *
+ * @param pageId
+ * the identifier of the target page that this extension
+ * is contributed into
+ * @param extensionId
+ * the identifier of the extension to provide the mixin style for.
+ * @return the style to add to the original extension style or <code>null</code> if no mixin
+ * style is found for this extension.
+ */
+ public String getMixinStyle(String pageId, String extensionId) {
+ return null;
+ }
} \ No newline at end of file
diff --git a/org.eclipse.ui.intro/themes/purpleMesh/html/shared.css b/org.eclipse.ui.intro/themes/purpleMesh/html/shared.css
index c86f75625..10f5f14b4 100644
--- a/org.eclipse.ui.intro/themes/purpleMesh/html/shared.css
+++ b/org.eclipse.ui.intro/themes/purpleMesh/html/shared.css
@@ -74,6 +74,9 @@ html, body, div, h1, h4, p, a { margin : 0px; padding : 0px; }
.intro-header H1 { padding-top : 10px; margin-left : 10px; }
+.section { }
+.section-body { display: none; padding : 0px; }
+
/* For regular div labels */
#page-content div H4 {
padding : 10px;
@@ -230,7 +233,7 @@ body, .page{
#navigation-links a#whatsnew:focus img,
#navigation-links a#whatsnew:active img { background-image : url(../graphics/icons/ctool/whatsnew48.gif); }
-#navigation-links a#workbench { position : absolute; right : 0px; top : 0px; text-align : right;}
+#navigation-links a#workbench { position : absolute; right : 0px; top : -35px; text-align : right;}
#navigation-links a#workbench .text { display : none; }
#navigation-links a#workbench img { background-image : url(../graphics/icons/etool/wb48.gif); width : 53px; height : 53px;}
#navigation-links a#workbench:hover img,
@@ -265,26 +268,66 @@ h1, p { margin-left : 10px; } /* required in mozilla so the page description is
#page-content #top-left {
border: none; float: left; margin: 0; padding: 0; width: 50%;
+ /*
background-color: #ffc0c0;
+ */
clear: left;
}
#page-content #top-right {
border: none; float: right; margin: 0; padding: 0; width: 50%;
+ /*
background-color: #c0ffc0;
+ */
clear: right;
}
+/* top-bottom divider - runs the entire width to ensure
+ * bottom boxes start at the same y
+ */
+#page-content #content-divider {
+ border: none; float: none; margin: 0; padding: 0; width: 100%;
+ /*
+ background-color: #c0c0c0;
+ */
+ clear: both;
+}
+
#page-content #bottom-left {
border: none; float: left; margin: 0; padding: 0; width: 50%;
- background-color: #ffc0c0;
+ /*
+ background-color: #ffffc0;
+ */
clear: left;
}
#page-content #bottom-right {
border: none; float: right; margin: 0; padding: 0; width: 50%;
- background-color: #c0ffc0;
+ /*
+ background-color: #c0ffff;
+ */
clear: right;
}
+/*
+ * Extension importance styles
+ */
+.importance-low {
+}
+
+.importance-medium {
+ background-color: #ffdddd;
+}
+
+.importance-high {
+ background-color: #ffffdd;
+}
+
+.importance-new {
+}
+
+.importance-callout {
+ background-color: #cccccc;
+}
+
#page-content #content-header H4, .page-description {
text-align : left;
margin-right : 10px;
diff --git a/org.eclipse.ui.intro/universal/introContent.xml b/org.eclipse.ui.intro/universal/introContent.xml
index 5ef20769d..7dada35ee 100644
--- a/org.eclipse.ui.intro/universal/introContent.xml
+++ b/org.eclipse.ui.intro/universal/introContent.xml
@@ -49,6 +49,7 @@
<!-- Overview page -->
<page id="overview" style="$theme$/html/overview.css" alt-style="$theme$/swt/overview.properties" style-id="page">
+ <title style-id="intro-header">$introTitle$</title>
<group id="extra-group1" filteredFrom="swt"/>
<group id="navigation-links" filteredFrom="swt">
<group id="page-links" computed="true">
@@ -67,6 +68,7 @@
<text style-id="page-description" id="page-description">Eclipse is a kind of universal tool platform - an open extensible IDE for anything and nothing in particular. It provides a feature-rich development environment that allows the developer to efficiently create tools that integrate seamlessly into the Eclipse Platform.</text>
<group id="top-left" computed="true"/>
<group id="top-right" computed="true"/>
+ <group id="content-divider"/>
<group id="bottom-left" computed="true"/>
<group id="bottom-right" computed="true"/>
</group>
@@ -74,7 +76,10 @@
<group id="extra-group3" filteredFrom="swt"><anchor id="anchor"/></group>
<group id="extra-group4" filteredFrom="swt"><anchor id="anchor"/></group>
</page>
+
+ <!-- Tutorials page -->
<page id="tutorials" style="$theme$/html/tutorials.css" alt-style="$theme$/swt/tutorials.properties" style-id="page">
+ <title style-id="intro-header">$introTitle$</title>
<group id="extra-group1" filteredFrom="swt"/>
<group id="navigation-links" filteredFrom="swt">
<group id="page-links" computed="true">
@@ -93,6 +98,7 @@
<text style-id="page-description" id="page-description">Learn how to be productive using Eclipse by completing end-to-end tutorials that will guide you along the way.</text>
<group id="top-left" computed="true"/>
<group id="top-right" computed="true"/>
+ <group id="content-divider"/>
<group id="bottom-left" computed="true"/>
<group id="bottom-right" computed="true"/>
</group>
@@ -100,7 +106,10 @@
<group id="extra-group3" filteredFrom="swt"><anchor id="anchor"/></group>
<group id="extra-group4" filteredFrom="swt"><anchor id="anchor"/></group>
</page>
+
+ <!-- Samples page -->
<page id="samples" style="$theme$/html/samples/samples.css" alt-style="$theme$/swt/samples.properties" style-id="page">
+ <title style-id="intro-header">$introTitle$</title>
<group id="extra-group1" filteredFrom="swt"/>
<group id="navigation-links" filteredFrom="swt">
<group id="page-links" computed="true">
@@ -119,6 +128,7 @@
<text style-id="page-description" id="page-description">Explore Eclipse by installing prefabricated samples (may require Internet connection).</text>
<group id="top-left" computed="true"/>
<group id="top-right" computed="true"/>
+ <group id="content-divider"/>
<group id="bottom-left" computed="true"/>
<group id="bottom-right" computed="true"/>
</group>
@@ -127,7 +137,9 @@
<group id="extra-group4" filteredFrom="swt"><anchor id="anchor"/></group>
</page>
+ <!-- What's New page -->
<page id="whatsnew" style="$theme$/html/whatsnew.css" alt-style="$theme$/swt/whatsnew.properties" style-id="page">
+ <title style-id="intro-header">$introTitle$</title>
<group id="extra-group1" filteredFrom="swt"/>
<group id="navigation-links" filteredFrom="swt">
<group id="page-links" computed="true">
@@ -145,6 +157,7 @@
<text style-id="page-title" id="page-title" filteredFrom="html">WHAT'S NEW</text>
<group id="top-left" computed="true"/>
<group id="top-right" computed="true"/>
+ <group id="content-divider"/>
<group id="bottom-left" computed="true"/>
<group id="bottom-right" computed="true"/>
</group>
@@ -153,7 +166,9 @@
<group id="extra-group4" filteredFrom="swt"><anchor id="anchor"/></group>
</page>
+ <!-- First Steps page -->
<page id="firststeps" style="$theme$/html/firststeps.css" alt-style="$theme$/swt/firststeps.properties" style-id="page">
+ <title style-id="intro-header">$introTitle$</title>
<group id="extra-group1" filteredFrom="swt"/>
<group id="navigation-links" filteredFrom="swt">
<group id="page-links" computed="true">
@@ -171,6 +186,7 @@
<text style-id="page-title" id="page-title" filteredFrom="html">FIRST STEPS</text>
<group id="top-left" computed="true"/>
<group id="top-right" computed="true"/>
+ <group id="content-divider"/>
<group id="bottom-left" computed="true"/>
<group id="bottom-right" computed="true"/>
</group>
@@ -179,7 +195,9 @@
<group id="extra-group4" filteredFrom="swt"><anchor id="anchor"/></group>
</page>
+ <!-- Web resources page -->
<page id="webresources" style="$theme$/html/webresources.css" alt-style="$theme$/swt/webresources.properties" style-id="page">
+ <title style-id="intro-header">$introTitle$</title>
<group id="navigation-links" filteredFrom="swt">
<group id="page-links" computed="true">
</group>
@@ -196,6 +214,7 @@
<text style-id="page-title" id="page-title" filteredFrom="html">WEB RESOURCE</text>
<group id="top-left" computed="true"/>
<group id="top-right" computed="true"/>
+ <group id="content-divider"/>
<group id="bottom-left" computed="true"/>
<group id="bottom-right" computed="true"/>
</group>
@@ -204,7 +223,10 @@
<group id="extra-group4" filteredFrom="swt"><anchor id="anchor"/></group>
</page>
+
+ <!-- Migrate page -->
<page id="migrate" style="$theme$/html/migrate.css" alt-style="$theme$/swt/migrate.properties" style-id="page">
+ <title style-id="intro-header">$introTitle$</title>
<group id="extra-group1" filteredFrom="swt"/>
<group id="navigation-links" filteredFrom="swt">
<group id="page-links" computed="true">
@@ -222,6 +244,7 @@
<text style-id="page-title" id="page-title" filteredFrom="html">MIGRATE</text>
<group id="top-left" computed="true"/>
<group id="top-right" computed="true"/>
+ <group id="content-divider"/>
<group id="bottom-left" computed="true"/>
<group id="bottom-right" computed="true"/>
</group>

Back to the top