001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.visualweb.css2;
042:
043: import org.netbeans.modules.visualweb.api.designer.cssengine.CssProvider;
044: import org.netbeans.modules.visualweb.api.designer.cssengine.CssValue;
045: import org.netbeans.modules.visualweb.designer.CssUtilities;
046: import java.net.URL;
047: import org.openide.ErrorManager;
048:
049: import org.openide.util.NbBundle;
050: import org.w3c.dom.Element;
051:
052: import org.netbeans.modules.visualweb.designer.WebForm;
053: import org.netbeans.modules.visualweb.api.designer.cssengine.XhtmlCss;
054: import org.netbeans.modules.visualweb.designer.html.HtmlTag;
055:
056: /**
057: * XXX This shouldn't be in the desinger, there shouldn't be any notion of fragments here.
058: *
059: * JspIncludeBox represents a <% include file="url" %> tag in the jsp markup. It will force
060: * the contents to be displayed in a block box.
061: *
062: * @author Tor Norbye
063: */
064: public class JspIncludeBox extends ExternalDocumentBox {
065: /**
066: * Element used for looking up styles for this inclusion box. That
067: * way I can look up the color, width, height etc. of the page fragment root element
068: * rather than the jsp.directive.include element
069: */
070: // private RaveElement styleElement;
071: private Element styleElement;
072:
073: /** Use the "getJspIncludeBox" factory method instead */
074: private JspIncludeBox(/*WebForm frameForm,*/WebForm webform,
075: Element element, /*URL url,*/
076: BoxType boxType, boolean inline, boolean replaced) {
077: super (webform.getPane(), /*frameForm,*/webform, element, /*url,*/
078: boxType,
079: // The jsp:directive.include directive should be block formatted.
080: // However, it's not easy to include a
081: // jsp:directive.include { display : block } rule in the default
082: // stylesheet because the batik parser mishandles escapes
083: // (the correct "jsp\:directive.include" doesn't work) so instead
084: // just hardcode the block formatting knowledge here
085: //inline,
086: false, replaced);
087: }
088:
089: /** Create a new framebox, or provide one from a cache */
090: public static CssBox getJspIncludeBox(CreateContext context,
091: WebForm webform, Element element, BoxType boxType,
092: HtmlTag tag, boolean inline) {
093: // URL src = getContentURL(webform, element); // TODO - check for null here!
094: // WebForm frameForm = null;
095: //
096: // if (src != null) {
097: //// frameForm = findForm(webform, src);
098: // frameForm = webform.findExternalForm(src);
099: // }
100:
101: // if (frameForm == WebForm.EXTERNAL) {
102: // frameForm = null;
103: // }
104:
105: JspIncludeBox box = new JspIncludeBox(/*frameForm,*/webform,
106: element, /*src,*/boxType, inline, tag.isReplacedTag());
107:
108: WebForm frameForm = box.getExternalForm();
109: if (frameForm != null) {
110: if (context.isVisitedForm(frameForm)) {
111: return new StringBox(webform, element, boxType,
112: NbBundle.getMessage(JspIncludeBox.class,
113: "RecursiveFrame"), null, AUTO, AUTO);
114: }
115:
116: // XXX Moved to designer/jsf/../JsfForm.
117: // //context.visitForm(frameForm);
118: // frameForm.setContextPage(webform);
119:
120: // XXX #110849 This is bad. The layout depends on whether the CSS was computed. Bad architecture.
121: // This needs to be cleared, because otherwise when used in fragment it would yield bad result for context page.
122: if (frameForm != null) {
123: CssProvider.getEngineService()
124: .clearComputedStylesForElement(
125: frameForm.getHtmlBody());
126: }
127: }
128:
129: if ((frameForm != null) && (frameForm.getHtmlBody() != null)) {
130: box.styleElement = frameForm.getHtmlBody();
131: }
132:
133: //// if ((frameForm != null) && (frameForm.getModel() != null) &&
134: //// (frameForm.getModel().getFacesUnit() != null) &&
135: //// frameForm.getModel().getFacesUnit().isPage()) {
136: // if (frameForm != null && frameForm.isPage()) {
137: //// InSyncService.getProvider().getRaveErrorHandler().displayError(NbBundle.getMessage(JspIncludeBox.class, "FragmentIsPage", getFile(element)));
138: // ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL,
139: // new IllegalStateException("Form is page, and should be a fragment, form=" + frameForm + ", file=" + getFile(element, webform))); // NOI18N
140: // }
141:
142: return box;
143: }
144:
145: private static String getFragmentPath(Element element,
146: WebForm webform) {
147: if (element.getParentNode() instanceof Element) {
148: Element parentDiv = (Element) element.getParentNode();
149: CssBox parent = webform.getCssBoxForElement(parentDiv);
150: ;
151: if (parent != null) {
152: while ((parent = parent.getParent()) != null) {
153: if (parent instanceof JspIncludeBox) {
154: String parentName = getFile(
155: parent.getElement(), webform);
156: if (parentName == null) {
157: return null;
158: }
159: return parentName.substring(0, parentName
160: .lastIndexOf("/") + 1);// NOI18N
161: }
162: }
163: }
164: }
165: return "";
166: }
167:
168: private static String getFile(Element element, WebForm webform) {
169: String src;
170: // XXX #94248 Hack for jsp:include, get page attribute.
171: if (HtmlTag.JSPINCLUDEX.name.equals(element.getTagName())) {
172: src = element.getAttribute("page"); // NOI18N
173: } else { // Falling for the rest.
174: // See http://java.sun.com/products/jsp/syntax/1.2/syntaxref129.html
175: // TODO: make attribute in HtmlAttribute
176: src = element.getAttribute("file"); // NOI18N
177: }
178:
179: if ((src == null) || (src.length() == 0)) {
180: return null;
181: }
182:
183: return getFragmentPath(element, webform) + src;
184: }
185:
186: protected String getUrlString() {
187: return getFile(getElement(), getWebForm());
188: }
189:
190: /**
191: * Return a URL for the included content, or null if it could not be determined.
192: */
193: @Override
194: protected URL getContentURL(WebForm webform, Element element) {
195: String src = getFile(element, webform);
196:
197: if ((src == null) || (src.length() == 0)) {
198: return null;
199: }
200:
201: // return InSyncService.getProvider().resolveUrl(webform.getMarkup().getBase(), webform.getJspDom(), src);
202: return webform.resolveUrl(src);
203: }
204:
205: // public String toString() {
206: // return "JspIncludeBox[" + paramString() + "]";
207: // }
208:
209: /*
210: protected String paramString() {
211: return super.paramString() + ", " + markup;
212: }
213: */
214:
215: // Override standard methods to give frames special treatment, since
216: // they are "black boxes" as far as the box hierarchy is concerned
217: /**
218: * What should the default intrinsic width be? Mozilla 1.6 seems to use 300x150.
219: */
220: public int getIntrinsicWidth() {
221: return 300;
222: }
223:
224: /**
225: * What should the default intrinsic height be? Mozilla 1.6 seems to use 300x150.
226: */
227: public int getIntrinsicHeight() {
228: return 150;
229: }
230:
231: public void relayout(FormatContext context) {
232: // Note - we don't pass in context.initialCB since
233: // fixed boxes should not be relative to the outer viewport
234: // by default
235: initializeContentSize(); // XXX I shouldn't do this here - I've already set it in compute horiz
236:
237: int cw = contentWidth;
238: int ch = contentHeight;
239: int w = (contentWidth != AUTO) ? contentWidth
240: : containingBlockWidth;
241: int h = (contentHeight != AUTO) ? contentHeight
242: : containingBlockHeight;
243: relayout(null, w, h, -1);
244:
245: // Box page layout overrides contentHeight and contentWidth
246: // XXX Do I need to reset the "width" and "height" properties too?
247: if (cw != AUTO) {
248: contentWidth = cw;
249: width = leftBorderWidth + leftPadding + contentWidth
250: + rightPadding + rightBorderWidth;
251: }
252:
253: if (ch != AUTO) {
254: contentHeight = ch;
255: height = topBorderWidth + topPadding + contentHeight
256: + bottomPadding + bottomBorderWidth;
257: }
258:
259: //super.relayout(context);
260: }
261:
262: /** No grids in included page fragment visualizations - the grid only applies when
263: * users are manipulating individual components in a surface, which is not allowed
264: * in a page fragment
265: */
266: protected void initializeGrid() {
267: }
268:
269: protected void initializeContentSize() {
270: if (styleElement != null) {
271: // contentWidth = CssLookup.getLength(styleElement, XhtmlCss.WIDTH_INDEX);
272: // contentHeight = CssLookup.getLength(styleElement, XhtmlCss.HEIGHT_INDEX);
273: contentWidth = CssUtilities.getCssLength(styleElement,
274: XhtmlCss.WIDTH_INDEX);
275: contentHeight = CssUtilities.getCssLength(styleElement,
276: XhtmlCss.HEIGHT_INDEX);
277: } else {
278: super .initializeContentSize();
279: }
280: }
281:
282: // protected void initializeHorizontalWidths(FormatContext context) {
283: // Element oldElement = element;
284: // try {
285: // if (styleElement != null) {
286: // // XXX Bad hack, cheating by replacing temporarily the element.
287: // // FIXME Find a better solution.
288: // element = styleElement;
289: // }
290: //
291: // super.initializeHorizontalWidths(context);
292: // } finally {
293: // element = oldElement;
294: // }
295: //
296: // }
297: // XXX FIXME Overriding to fake diff element.
298: protected CssValue computeWidthCssValue() {
299: if (styleElement != null) {
300: return CssProvider.getEngineService()
301: .getComputedValueForElement(styleElement,
302: XhtmlCss.WIDTH_INDEX);
303: } else {
304: return super .computeWidthCssValue();
305: }
306: }
307:
308: // XXX FIXME Overriding to fake diff element.
309: protected void uncomputeWidthCssValue() {
310: if (styleElement != null) {
311: CssProvider.getEngineService().uncomputeValueForElement(
312: styleElement, XhtmlCss.WIDTH_INDEX);
313: } else {
314: super .uncomputeWidthCssValue();
315: }
316: }
317:
318: protected void createChildren(CreateContext context) {
319: super .createChildren(context);
320:
321: if (getBoxCount() == 0) {
322: String desc = NbBundle.getMessage(JspIncludeBox.class,
323: (getExternalForm() != null) ? "EmptyFragment"
324: : "NoFragment"); // NOI18N
325: addGrayItalicText(context,
326: (styleElement != null) ? styleElement
327: : getElement(), desc);
328:
329: return;
330: }
331: }
332: }
|