Source Code Cross Referenced for DomDocumentImpl.java in  » IDE-Netbeans » visualweb.api.designer » org » netbeans » modules » visualweb » designer » jsf » text » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Netbeans » visualweb.api.designer » org.netbeans.modules.visualweb.designer.jsf.text 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003:         *
0004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * The contents of this file are subject to the terms of either the GNU
0007:         * General Public License Version 2 only ("GPL") or the Common
0008:         * Development and Distribution License("CDDL") (collectively, the
0009:         * "License"). You may not use this file except in compliance with the
0010:         * License. You can obtain a copy of the License at
0011:         * http://www.netbeans.org/cddl-gplv2.html
0012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013:         * specific language governing permissions and limitations under the
0014:         * License.  When distributing the software, include this License Header
0015:         * Notice in each file and include the License file at
0016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
0017:         * particular file as subject to the "Classpath" exception as provided
0018:         * by Sun in the GPL Version 2 section of the License file that
0019:         * accompanied this code. If applicable, add the following below the
0020:         * License Header, with the fields enclosed by brackets [] replaced by
0021:         * your own identifying information:
0022:         * "Portions Copyrighted [year] [name of copyright owner]"
0023:         *
0024:         * Contributor(s):
0025:         *
0026:         * The Original Software is NetBeans. The Initial Developer of the Original
0027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
0028:         * Microsystems, Inc. All Rights Reserved.
0029:         *
0030:         * If you wish your version of this file to be governed by only the CDDL
0031:         * or only the GPL Version 2, indicate your decision by adding
0032:         * "[Contributor] elects to include this software in this distribution
0033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034:         * single choice of license, a recipient has the option to distribute
0035:         * your version of this file under either the CDDL, the GPL Version 2 or
0036:         * to extend the choice of license to its licensees as provided above.
0037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
0038:         * Version 2 license, then the option applies only if the new code is
0039:         * made subject to such option by the copyright holder.
0040:         */
0041:
0042:        package org.netbeans.modules.visualweb.designer.jsf.text;
0043:
0044:        import com.sun.rave.designtime.DesignBean;
0045:        import com.sun.rave.designtime.markup.MarkupDesignBean;
0046:        import java.awt.Point;
0047:        import java.util.ArrayList;
0048:        import java.util.List;
0049:        import javax.swing.event.EventListenerList;
0050:        import org.netbeans.modules.visualweb.api.designer.Designer;
0051:        import org.netbeans.modules.visualweb.api.designer.Designer.Box;
0052:
0053:        import org.netbeans.modules.visualweb.api.designer.DomProvider;
0054:        import org.netbeans.modules.visualweb.api.designer.DomProvider.DomDocumentEvent;
0055:        import org.netbeans.modules.visualweb.api.designer.DomProvider.DomDocumentListener;
0056:        import org.netbeans.modules.visualweb.api.designer.DomProvider.DomDocument;
0057:        import org.netbeans.modules.visualweb.api.designer.DomProvider.DomPosition;
0058:        import org.netbeans.modules.visualweb.api.designer.DomProvider.DomPosition.Bias;
0059:        import org.netbeans.modules.visualweb.api.designer.DomProvider.DomRange;
0060:        import org.netbeans.modules.visualweb.api.designer.cssengine.CssProvider;
0061:        import org.netbeans.modules.visualweb.api.designer.cssengine.CssValue;
0062:        import org.netbeans.modules.visualweb.api.designer.cssengine.StyleData;
0063:        import org.netbeans.modules.visualweb.api.designer.markup.MarkupService;
0064:        import org.netbeans.modules.visualweb.api.designer.cssengine.XhtmlCss;
0065:        import org.netbeans.modules.visualweb.designer.html.HtmlAttribute;
0066:        import org.netbeans.modules.visualweb.designer.html.HtmlTag;
0067:        import org.netbeans.modules.visualweb.designer.jsf.JsfForm;
0068:        import org.netbeans.modules.visualweb.designer.jsf.JsfSupportUtilities;
0069:        import org.netbeans.modules.visualweb.insync.UndoEvent;
0070:        import org.netbeans.modules.visualweb.insync.markup.MarkupUnit;
0071:
0072:        import org.openide.ErrorManager;
0073:        import org.openide.util.NbBundle;
0074:        import org.w3c.dom.DOMException;
0075:
0076:        import org.w3c.dom.DocumentFragment;
0077:        import org.w3c.dom.Element;
0078:        import org.w3c.dom.Node;
0079:        import org.w3c.dom.NodeList;
0080:        import org.w3c.dom.Text;
0081:        import org.w3c.dom.ranges.DocumentRange;
0082:        import org.w3c.dom.traversal.DocumentTraversal;
0083:        import org.w3c.dom.traversal.NodeFilter;
0084:        import org.w3c.dom.traversal.NodeIterator;
0085:
0086:        /**
0087:         * XXX Moved from designer/../Document.
0088:         *
0089:         *  Wrapper object for dom documents; holds some additional
0090:         *  state and document methods.
0091:         *
0092:         * @todo Refactor the EventListener into an adapter class
0093:         * @todo IMPORTANT: I need to cache the font lookup stuff so
0094:         *    I don't keep recomputing it!
0095:         * @author Tor Norbye
0096:         */
0097:        public class DomDocumentImpl implements  DomProvider.DomDocument {
0098:            //    // DEBUG:
0099:            //    // Log info pertaining to document events
0100:            //    static final boolean debugevents = false;
0101:            //    private WebForm webform;
0102:            private JsfForm jsfForm;
0103:
0104:            //    private ImageCache imageCache;
0105:            //    private DocumentCache frameCache;
0106:
0107:            //    /** For testsuite use only!!! */
0108:            //    public URL testBase;
0109:
0110:            //    /**
0111:            //     * The event listener list for the document.
0112:            //     */
0113:            //    protected EventListenerList listenerList = new EventListenerList();
0114:
0115:            // --- Document locking ----------------------------------
0116:            //    private UndoEvent undoEvent;
0117:
0118:            public DomDocumentImpl(/*WebForm webform*/JsfForm jsfForm) {
0119:                //        this.webform = webform;
0120:                this .jsfForm = jsfForm;
0121:
0122:                // Ensure we've got a model
0123:                // TODO - this should be cleaned up
0124:                //        webform.getDomSynchronizer();
0125:            }
0126:
0127:            public String toString() {
0128:                //        if ((webform != null) && (webform.getModel() != null) && (webform.getMarkup() != null) &&
0129:                //                (webform.getMarkup().getFileObject() != null)) {
0130:                //            return "Document[" + webform.getMarkup().getFileObject().toString() + "]";
0131:                //        }
0132:
0133:                //        return super.toString() + "[webForm=" + webform + "]"; // NOI18N
0134:                return super .toString() + "[jsfForm=" + jsfForm + "]"; // NOI18N
0135:            }
0136:
0137:            //    public WebForm getWebForm() {
0138:            //        return webform;
0139:            //    }
0140:
0141:            //    /**
0142:            //     * Returns the location to resolve relative URLs against.  By
0143:            //     * default this will be the document's URL if the document
0144:            //     * was loaded from a URL.  If a base tag is found and
0145:            //     * can be parsed, it will be used as the base location.
0146:            //     *
0147:            //     * @return the base location
0148:            //     */
0149:            //    public URL getBase() {
0150:            ////        URL url = webform.getMarkup().getBase();
0151:            //        URL url = webform.getBaseUrl();
0152:            //
0153:            //        if (url != null) {
0154:            //            return url;
0155:            //        }
0156:            //
0157:            //        return testBase;
0158:            //    }
0159:
0160:            // XXX Moved to Webform.
0161:            //    /**
0162:            //     * Return a cache of images for this document
0163:            //     */
0164:            //    public ImageCache getImageCache() {
0165:            //        if (imageCache == null) {
0166:            //            imageCache = new ImageCache();
0167:            //        }
0168:            //
0169:            //        return imageCache;
0170:            //    }
0171:            //
0172:            //    /**
0173:            //     * Return a cache of webform boxes associated with this document
0174:            //     * @todo Rename; it's no longer a box cache but rather a document
0175:            //     *   cache!
0176:            //     */
0177:            //    public DocumentCache getFrameBoxCache() {
0178:            //        if (frameCache == null) {
0179:            //            frameCache = new DocumentCache();
0180:            //        }
0181:            //
0182:            //        return frameCache;
0183:            //    }
0184:            //
0185:            //    /**
0186:            //     * Return true iff the document has cached frame boxes
0187:            //     */
0188:            //    public boolean hasCachedFrameBoxes() {
0189:            //        return (frameCache != null) && (frameCache.size() > 0);
0190:            //    }
0191:            //
0192:            //    /**
0193:            //     * Clear out caches for a "refresh" operation
0194:            //     */
0195:            //    public void flushCaches() {
0196:            //        if (frameCache != null) {
0197:            //            frameCache.flush();
0198:            //        }
0199:            //
0200:            //        if (imageCache != null) {
0201:            //            imageCache.flush();
0202:            //        }
0203:            //    }
0204:
0205:            //    public void insertString(/*DesignerCaret caret,*/ Position pos, String str) {
0206:            public boolean insertString(
0207:                    /*DesignerCaret caret,*/Designer designer,
0208:                    DomRange domRange, String str) {
0209:                if (domRange == null) {
0210:                    return false;
0211:                }
0212:                //                    UndoEvent undoEvent = webform.getModel().writeLock(NbBundle.getMessage(DefaultKeyTypedAction.class, "InsertChar")); // NOI18N
0213:                //        DomProvider.WriteLock writeLock = jsfForm.writeLock(NbBundle.getMessage(DomDocumentImpl.class, "LBL_InsertText")); // NOI18N
0214:                UndoEvent writeLock = jsfForm.writeLock(NbBundle.getMessage(
0215:                        DomDocumentImpl.class, "LBL_InsertText")); // NOI18N
0216:                try {
0217:
0218:                    //        if (hasSelection()) {
0219:                    //            removeSelection();
0220:                    if (!domRange.isEmpty()) {
0221:                        deleteRangeContents(domRange);
0222:                    }
0223:
0224:                    //        Position pos = getDot();
0225:                    //        DomPosition pos = getDot();
0226:                    DomPosition pos = domRange.getDot();
0227:
0228:                    //        if (editor == null) {
0229:                    //        if (!component.getWebForm().isInlineEditing()) {
0230:                    if (!designer.isInlineEditing()) {
0231:                        //            assert (pos == Position.NONE) || !pos.isRendered();
0232:                        //            if (pos != Position.NONE && MarkupService.isRenderedNode(pos.getNode())) {
0233:                        //            if (pos != DomPosition.NONE && MarkupService.isRenderedNode(pos.getNode())) {
0234:                        if (pos != DomPosition.NONE
0235:                                && isRenderedNode(pos.getNode())) {
0236:                            ErrorManager.getDefault().notify(
0237:                                    ErrorManager.INFORMATIONAL,
0238:                                    new IllegalStateException(
0239:                                            "Node is expected to be not rendered, node="
0240:                                                    + pos.getNode())); // NOI18N
0241:                            return false;
0242:                        }
0243:                    } // else: Stay in the DocumentFragment; don't jump to the source DOM (there is none)
0244:
0245:                    //        if (pos == Position.NONE) {
0246:                    if (pos == DomPosition.NONE) {
0247:                        //            UIManager.getLookAndFeel().provideErrorFeedback(this);
0248:                        return false;
0249:                    }
0250:
0251:                    // TODO: If you're pressing shift while hitting Enter, we should force a <br/>,
0252:                    // and otherwise we should split the current block tag (if there is one, and
0253:                    // that block tag is not a <div> or a <body> (for these we always use <br>).
0254:                    //        assert (pos != null) && (pos != Position.NONE);
0255:                    if (pos == null || pos == DomPosition.NONE) {
0256:                        ErrorManager.getDefault().notify(
0257:                                ErrorManager.INFORMATIONAL,
0258:                                new IllegalArgumentException(
0259:                                        "Invalid position, pos=" + pos)); // NOI18N
0260:                        return false;
0261:                    }
0262:
0263:                    //        Element body = webform.getHtmlBody();
0264:                    Element body = jsfForm.getHtmlBody();
0265:
0266:                    if ((pos.getNode() == body)
0267:                            || ((pos.getNode().getParentNode() == body)
0268:                                    && (pos.getNode().getNodeType() == Node.TEXT_NODE) && JsfSupportUtilities
0269:                                    .onlyWhitespace(pos.getNode()
0270:                                            .getNodeValue()))) {
0271:                        // Trying to insert text right at the top <body> level.
0272:                        // Insert text in a paragraph instead!
0273:                        Node next = null;
0274:
0275:                        if (pos.getNode() == body) {
0276:                            next = body.getChildNodes().item(pos.getOffset());
0277:                        } else {
0278:                            next = pos.getNode().getNextSibling();
0279:                        }
0280:
0281:                        // XXX TODO get rid of using xhtml directly, 
0282:                        // it should be shielded by api.
0283:                        Element p = createElement(
0284:                                org.netbeans.modules.visualweb.xhtml.P.class
0285:                                        .getName(), body, next);
0286:                        createElement(
0287:                                org.netbeans.modules.visualweb.xhtml.Br.class
0288:                                        .getName(), p, null);
0289:
0290:                        //            pos.setLocation(p, 0, Bias.FORWARD);
0291:                        //            caret.setDot(new Position(p, 0, Bias.FORWARD));
0292:                        fireInsertUpdate(new DefaultDomDocumentEvent(this ,
0293:                                createDomPosition(p, 0, Bias.FORWARD)));
0294:                    }
0295:
0296:                    if (str.equals("\n") || str.equals("\r\n")) {
0297:                        insertNewline(/*caret,*/pos.getNode(), pos.getOffset());
0298:
0299:                        return true;
0300:                    }
0301:
0302:                    // Can't put "&" directly in source!
0303:                    //        if (str.equals("&") && !FacesSupport.isHtmlNode(webform, pos.getNode())) {
0304:                    if (str.equals("&")
0305:                            && !isHtmlNode(/*webform*/jsfForm, pos.getNode())) { // NOI18N
0306:                        str = "&amp;"; // NOI18N
0307:                    }
0308:
0309:                    Node node = pos.getNode();
0310:                    int offset = pos.getOffset();
0311:                    Node targetNode = node; // Node to move caret to when we're done
0312:                    int targetOffset = offset;
0313:
0314:                    // TODO - replace <, >, ", etc. with entities
0315:                    if ((node.getNodeType() == Node.TEXT_NODE)
0316:                            || (node.getNodeType() == Node.CDATA_SECTION_NODE)) {
0317:                        org.w3c.dom.Text text = (org.w3c.dom.Text) node;
0318:
0319:                        if ((str.length() == 1) && (str.charAt(0) == ' ')) {
0320:                            insertSpace(/*caret,*/pos.getNode(), pos
0321:                                    .getOffset());
0322:
0323:                            // XXX check that this works on Windows too - or do they
0324:                            // use \r\n ?
0325:                            return true;
0326:                        } else {
0327:                            text.insertData(offset, str);
0328:                            targetNode = text;
0329:                            targetOffset += str.length();
0330:                        }
0331:
0332:                        //            caret.setDot(new Position(targetNode, targetOffset, pos.getBias()));
0333:                        fireInsertUpdate(new DefaultDomDocumentEvent(this ,
0334:                                createDomPosition(targetNode, targetOffset, pos
0335:                                        .getBias())));
0336:                    } else if ((node.getNodeType() == Node.ELEMENT_NODE)
0337:                            || (node.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE)) {
0338:                        NodeList list = node.getChildNodes();
0339:                        int len = list.getLength();
0340:
0341:                        if ((len == 0) || (offset >= len)) {
0342:                            // We have a 0 index but no children, e.g. we're
0343:                            // inside an empty element.
0344:                            // XXX what if it's a newline??
0345:                            // Add a text node into the list, as the first
0346:                            // child
0347:                            // XXX for the <body> tag I should auto insert a <p>
0348:                            // too around the text...
0349:                            //                org.w3c.dom.Document dom = webform.getJspDom();
0350:                            org.w3c.dom.Document dom = jsfForm.getJspDom();
0351:
0352:                            Node text = dom.createTextNode(str);
0353:
0354:                            //                if (((RaveRenderNode)node).isJspx()) {
0355:                            if (MarkupService.isJspxNode(node)) {
0356:                                MarkupService.markJspxSource(text);
0357:                            }
0358:
0359:                            node.appendChild(text);
0360:
0361:                            //                caret.setDot(new Position(text, str.length(), Bias.FORWARD));
0362:                            fireInsertUpdate(new DefaultDomDocumentEvent(this ,
0363:                                    createDomPosition(text, str.length(),
0364:                                            Bias.FORWARD)));
0365:
0366:                            return true;
0367:                        } else if (offset < len) {
0368:                            // Insert text before the given sibling;
0369:                            // if prev is a text node append to
0370:                            // that, otherwise insert a text node there
0371:                            if ((offset > 0)
0372:                                    && (list.item(offset - 1) instanceof  Text)) {
0373:                                org.w3c.dom.CharacterData text = (org.w3c.dom.CharacterData) list
0374:                                        .item(offset - 1);
0375:                                text.appendData(str);
0376:
0377:                                //                    caret.setDot(new Position(text, text.getLength(), pos.getBias()));
0378:                                fireInsertUpdate(new DefaultDomDocumentEvent(
0379:                                        this , createDomPosition(text, text
0380:                                                .getLength(), pos.getBias())));
0381:
0382:                                return true;
0383:                            } else {
0384:                                //                    org.w3c.dom.Document dom = webform.getJspDom();
0385:                                org.w3c.dom.Document dom = jsfForm.getJspDom();
0386:
0387:                                Node text = dom.createTextNode(str);
0388:
0389:                                //                    if (((RaveRenderNode)node).isJspx()) {
0390:                                if (MarkupService.isJspxNode(node)) {
0391:                                    MarkupService.markJspxSource(text);
0392:                                }
0393:
0394:                                Node before = list.item(offset);
0395:                                node.insertBefore(text, before);
0396:
0397:                                //                    caret.setDot(new Position(text, str.length(), Bias.FORWARD));
0398:                                fireInsertUpdate(new DefaultDomDocumentEvent(
0399:                                        this , createDomPosition(text, str
0400:                                                .length(), Bias.FORWARD)));
0401:
0402:                                return true;
0403:                            }
0404:                        }
0405:                    } else {
0406:                        ErrorManager.getDefault().log(
0407:                                "Unexpected node: " + offset + ", str=" + str);
0408:                        return false;
0409:                    }
0410:                    return true;
0411:
0412:                } finally {
0413:                    //                        doc.writeUnlock();
0414:                    //                        webform.getModel().writeUnlock(undoEvent);
0415:                    jsfForm.writeUnlock(writeLock);
0416:                }
0417:
0418:            }
0419:
0420:            public boolean deleteRangeContents(DomRange domRange) {
0421:                if (domRange instanceof  DomRangeImpl) {
0422:                    DomRangeImpl domRangeImpl = (DomRangeImpl) domRange;
0423:
0424:                    DomPosition firstPosition = domRangeImpl.getFirstPosition();
0425:                    DomPosition lastPosition = domRangeImpl.getLastPosition();
0426:                    // XXX For now it works only over the source nodes. That has to be changes.
0427:                    if (!jsfForm.isInlineEditing()
0428:                    //            && (MarkupService.isRenderedNode(firstPosition.getNode()) || MarkupService.isRenderedNode(lastPosition.getNode()))) {
0429:                            && (isRenderedNode(firstPosition.getNode()) || isRenderedNode(lastPosition
0430:                                    .getNode()))) {
0431:                        ErrorManager.getDefault().notify(
0432:                                ErrorManager.INFORMATIONAL,
0433:                                new IllegalStateException(
0434:                                        "It is not inline editing, nor both positions are source ones," // NOI18N
0435:                                                + "\nstartPosition="
0436:                                                + firstPosition // NOI18N
0437:                                                + "\nendPosition="
0438:                                                + lastPosition)); // NOI18N
0439:                        return false;
0440:                    }
0441:
0442:                    deleteComponents(firstPosition, lastPosition);
0443:                    return domRangeImpl.deleteRangeContents();
0444:                }
0445:                return false;
0446:            }
0447:
0448:            public String getRangeText(DomRange domRange) {
0449:                if (domRange instanceof  DomRangeImpl) {
0450:                    DomRangeImpl domRangeImpl = (DomRangeImpl) domRange;
0451:
0452:                    DomPosition firstPosition = domRangeImpl.getFirstPosition();
0453:                    DomPosition lastPosition = domRangeImpl.getLastPosition();
0454:                    return getText(firstPosition, lastPosition);
0455:                }
0456:
0457:                return ""; // NOI18N
0458:            }
0459:
0460:            // XXX Moved from FacesSupport
0461:            private static boolean isHtmlNode(
0462:                    /*WebForm webform*/JsfForm jsfForm, Node node) {
0463:                if (node.getNodeType() == Node.TEXT_NODE) {
0464:                    node = node.getParentNode();
0465:                }
0466:
0467:                if ((node == null) || !(node instanceof  Element)) {
0468:                    return false;
0469:                }
0470:
0471:                //        RaveElement element = (RaveElement)node;
0472:                //        if (element.isRendered()) {
0473:                //            return true;
0474:                //        }
0475:                //        if (MarkupService.isRenderedNode(node)) {
0476:                if (jsfForm.isRenderedNode(node)) {
0477:                    return true;
0478:                }
0479:
0480:                //        if (webform.getManager().isInlineEditing()) {
0481:                if (jsfForm.isInlineEditing()) {
0482:                    // In inline editing mode we'return modifying an already rendered
0483:                    // fragment. It is not marked rendered since in terms of source mapping
0484:                    // it's serving as a source dom, returned from FacesPageUnit's render
0485:                    // operations etc.
0486:                    return true;
0487:                }
0488:
0489:                return false;
0490:            }
0491:
0492:            /** Any more inline content on this line? */
0493:            private static boolean haveMoreInlineContent(Node node) {
0494:                while (node != null) {
0495:                    if (node instanceof  Text) {
0496:                        return true;
0497:                    } else if (node instanceof  Element) {
0498:                        Element element = (Element) node;
0499:                        HtmlTag tag = HtmlTag.getTag(element.getTagName());
0500:
0501:                        if (tag == HtmlTag.BR) {
0502:                            return true;
0503:                        }
0504:
0505:                        //                Value display = CssLookup.getValue(element, XhtmlCss.DISPLAY_INDEX);
0506:                        CssValue cssDisplay = CssProvider.getEngineService()
0507:                                .getComputedValueForElement(element,
0508:                                        XhtmlCss.DISPLAY_INDEX);
0509:
0510:                        //                if (ContainerBox.isInlineTag(cssDisplay, element, tag)) {
0511:                        if (CssProvider.getValueService().isInlineTag(
0512:                                cssDisplay, element, tag)) {
0513:                            return true;
0514:                        }
0515:                    }
0516:
0517:                    node = node.getNextSibling();
0518:                }
0519:
0520:                return false;
0521:            }
0522:
0523:            /** Insert a newline at the given position: if we're inside a list this
0524:             * means to add a new list item, otherwise we add a &lt;br&gt; (or two, in
0525:             * a few scenarios.)
0526:             */
0527:            private void insertNewline(/*DesignerCaret caret,*/Node node,
0528:                    int offset) {
0529:                org.w3c.dom.Text text = null;
0530:                Node parent = null;
0531:                Node next = null;
0532:
0533:                if ((node.getNodeType() == Node.TEXT_NODE)
0534:                        || (node.getNodeType() == Node.CDATA_SECTION_NODE)) {
0535:                    text = (org.w3c.dom.Text) node;
0536:                    next = text.getNextSibling();
0537:                    parent = node.getParentNode();
0538:                } else {
0539:                    parent = node;
0540:
0541:                    NodeList list = node.getChildNodes();
0542:                    int len = list.getLength();
0543:
0544:                    if ((len == 0) || (offset >= len)) {
0545:                        // We have a 0 index but no children, e.g. we're
0546:                        // inside an empty element.
0547:                        // XXX Can we do anything here?
0548:                        next = null;
0549:                    } else if (offset < len) {
0550:                        next = list.item(offset);
0551:                    }
0552:                }
0553:
0554:                // Inserted newline: should split string and insert a
0555:                // <br/>  (unless we're inside a list, in that case create
0556:                // a new bullet)
0557:                //        Element list = DesignerUtils.getListItemParent(node);
0558:                Element list = getListItemParent(node);
0559:
0560:                if (list != null) {
0561:                    // XXX TODO get rid of using xhtml directly, 
0562:                    // it should be shielded by api.
0563:                    Element li = createElement(
0564:                            org.netbeans.modules.visualweb.xhtml.Li.class
0565:                                    .getName(), list.getParentNode(), list
0566:                                    .getNextSibling());
0567:                    //            DocumentRange dom = (DocumentRange)webform.getJspDom();
0568:                    DocumentRange dom = (DocumentRange) jsfForm.getJspDom();
0569:
0570:                    org.w3c.dom.ranges.Range domRange = dom.createRange();
0571:                    domRange.setStart(node, offset);
0572:
0573:                    // Locate end of the current list item
0574:                    //            Position listItemEnd = Position.create(list, true);
0575:                    DomPosition listItemEnd = createNextDomPosition(list, true);
0576:                    domRange.setEnd(listItemEnd.getNode(), listItemEnd
0577:                            .getOffset());
0578:
0579:                    DocumentFragment df = domRange.extractContents();
0580:                    domRange.detach();
0581:
0582:                    NodeList nl = df.getChildNodes();
0583:
0584:                    if ((nl.getLength() > 0)
0585:                            && nl.item(0) instanceof  Element
0586:                            && ((Element) nl.item(0)).getTagName().equals(
0587:                                    HtmlTag.LI.name)) {
0588:                        nl = nl.item(0).getChildNodes();
0589:                    }
0590:
0591:                    for (int ch = 0, len = nl.getLength(); ch < len; ch++) {
0592:                        Node n = nl.item(ch);
0593:
0594:                        if (n == null) {
0595:                            continue;
0596:                        }
0597:
0598:                        if (((n.getNodeType() == Node.TEXT_NODE) || (n
0599:                                .getNodeType() == Node.CDATA_SECTION_NODE))
0600:                                && JsfSupportUtilities.onlyWhitespace(n
0601:                                        .getNodeValue())) {
0602:                            continue;
0603:                        }
0604:
0605:                        li.appendChild(n);
0606:                    }
0607:
0608:                    if (li.getChildNodes().getLength() == 0) {
0609:                        // XXX TODO get rid of using xhtml directly, 
0610:                        // it should be shielded by api.
0611:                        createElement(
0612:                                org.netbeans.modules.visualweb.xhtml.Br.class
0613:                                        .getName(), li, null);
0614:                    }
0615:
0616:                    // It's possible that we've moved EVERYTHING from the current item
0617:                    // in which case we need to put a <br> in there.
0618:                    if (node.getChildNodes().getLength() == 0) {
0619:                        // XXX TODO get rid of using xhtml directly, 
0620:                        // it should be shielded by api.
0621:                        createElement(
0622:                                org.netbeans.modules.visualweb.xhtml.Br.class
0623:                                        .getName(), node, null);
0624:                    }
0625:
0626:                    //            caret.setDot(new Position(li, 0, Bias.FORWARD));
0627:                    fireInsertUpdate(new DefaultDomDocumentEvent(this ,
0628:                            createDomPosition(li, 0, Bias.FORWARD)));
0629:                } else {
0630:                    // TODO - if the offset is 0, or end, we don't have
0631:                    // to split!
0632:                    Element br;
0633:
0634:                    if ((text == null) || (offset == text.getLength())) {
0635:                        // Insert after our (possibly text-)node
0636:                        // null for next is okay - will be
0637:                        // appended to the end of the list
0638:                        boolean isLastInline = !haveMoreInlineContent(next);
0639:                        boolean after = true;
0640:                        // XXX TODO get rid of using xhtml directly, 
0641:                        // it should be shielded by api.
0642:                        br = createElement(
0643:                                org.netbeans.modules.visualweb.xhtml.Br.class
0644:                                        .getName(), parent, next);
0645:
0646:                        // We may have to insert an additional <br> here.
0647:                        // Let's say you have this: "<p>Hello^</p>" and you
0648:                        // press Return. If we just insert a <br/> you get
0649:                        // "<p>Hello<br/>^</p>" which is still only a single line;
0650:                        // but the user is expecting to see a new blank line
0651:                        // to edit: "<p>Hello<br/>^<br/></p>".  Of course we
0652:                        // can't blindly insert one; we have to know that
0653:                        // there aren't any other inline tags following the
0654:                        // br in line context; e.g. if we press return here:
0655:                        // "<p>Hello^<span>foo</span></p>" we should end up with
0656:                        // "<p>Hello<br/>^<span>foo</span></p>".
0657:                        if (isLastInline) {
0658:                            // XXX TODO get rid of using xhtml directly, 
0659:                            // it should be shielded by api.
0660:                            br = createElement(
0661:                                    org.netbeans.modules.visualweb.xhtml.Br.class
0662:                                            .getName(), parent, next);
0663:                            after = false;
0664:                        }
0665:
0666:                        if (next instanceof  Element) {
0667:                            //                    caret.setDot(Position.create((Element)next, false));
0668:                            fireInsertUpdate(new DefaultDomDocumentEvent(
0669:                                    this ,
0670:                                    createNextDomPosition((Element) next, false)));
0671:                        } else {
0672:                            //                    caret.setDot(Position.create(br, after));
0673:                            fireInsertUpdate(new DefaultDomDocumentEvent(this ,
0674:                                    createNextDomPosition(br, after)));
0675:                        }
0676:                    } else if (offset == 0) {
0677:                        // Insert before our text node
0678:                        // XXX TODO get rid of using xhtml directly, 
0679:                        // it should be shielded by api.
0680:                        br = createElement(
0681:                                org.netbeans.modules.visualweb.xhtml.Br.class
0682:                                        .getName(), parent, text);
0683:
0684:                        //                caret.setDot(new Position(text, 0, Bias.FORWARD));
0685:                        fireInsertUpdate(new DefaultDomDocumentEvent(this ,
0686:                                createDomPosition(text, 0, Bias.FORWARD)));
0687:                    } else {
0688:                        // Insert in the middle of the text node; split it
0689:                        org.w3c.dom.Text secondHalf = text.splitText(offset);
0690:                        // XXX TODO get rid of using xhtml directly, 
0691:                        // it should be shielded by api.
0692:                        br = createElement(
0693:                                org.netbeans.modules.visualweb.xhtml.Br.class
0694:                                        .getName(), text.getParentNode(),
0695:                                secondHalf);
0696:
0697:                        if (JsfSupportUtilities.onlyWhitespace(secondHalf
0698:                                .getNodeValue())) {
0699:                            boolean isLastInline = true;
0700:
0701:                            if (secondHalf.getNextSibling() != null) {
0702:                                isLastInline = !haveMoreInlineContent(secondHalf
0703:                                        .getNextSibling());
0704:                            }
0705:
0706:                            if (isLastInline) {
0707:                                // XXX TODO get rid of using xhtml directly, 
0708:                                // it should be shielded by api.
0709:                                br = createElement(
0710:                                        org.netbeans.modules.visualweb.xhtml.Br.class
0711:                                                .getName(), text
0712:                                                .getParentNode(), secondHalf
0713:                                                .getNextSibling());
0714:
0715:                                //                        caret.setDot(Position.create(br, false));
0716:                                fireInsertUpdate(new DefaultDomDocumentEvent(
0717:                                        this , createNextDomPosition(br, false)));
0718:
0719:                                return;
0720:                            }
0721:                        }
0722:
0723:                        //caret.setDot(Position.create(br, true));
0724:                        //                caret.setDot(new Position(secondHalf, 0, Bias.FORWARD));
0725:                        fireInsertUpdate(new DefaultDomDocumentEvent(this ,
0726:                                createDomPosition(secondHalf, 0, Bias.FORWARD)));
0727:                    }
0728:                }
0729:            }
0730:
0731:            // XXX Moved from DesignerUtils.
0732:            /** For the given node, locate a parent list item element, or return
0733:             * null if no such parent is found.
0734:             */
0735:            private static Element getListItemParent(Node node) {
0736:                while (node != null) {
0737:                    if (node.getNodeType() == Node.ELEMENT_NODE) {
0738:                        Element element = (Element) node;
0739:
0740:                        if (element.getTagName().equals(HtmlTag.LI.name)) {
0741:                            return element;
0742:                        }
0743:                    }
0744:
0745:                    node = node.getParentNode();
0746:                }
0747:
0748:                return null;
0749:            }
0750:
0751:            private void insertSpace(/*DesignerCaret caret,*/Node node,
0752:                    int offset) {
0753:                org.w3c.dom.Text text = null;
0754:                Node parent = null;
0755:                Node next = null;
0756:                String str = " ";
0757:
0758:                if ((node.getNodeType() == Node.TEXT_NODE)
0759:                        || (node.getNodeType() == Node.CDATA_SECTION_NODE)) {
0760:                    text = (org.w3c.dom.Text) node;
0761:                } else {
0762:                    parent = node;
0763:
0764:                    NodeList list = node.getChildNodes();
0765:                    int len = list.getLength();
0766:
0767:                    if ((len == 0) || (offset >= len)) {
0768:                        // We have a 0 index but no children, e.g. we're
0769:                        // inside an empty element.
0770:                        // XXX Can we do anything here?
0771:                        next = null;
0772:                    } else if (offset < len) {
0773:                        next = list.item(offset);
0774:                    }
0775:
0776:                    //            org.w3c.dom.Document dom = webform.getJspDom();
0777:                    org.w3c.dom.Document dom = jsfForm.getJspDom();
0778:
0779:                    text = dom.createTextNode(str);
0780:
0781:                    //            if (((RaveRenderNode)node).isJspx()) {
0782:                    if (MarkupService.isJspxNode(node)) {
0783:                        MarkupService.markJspxSource(text);
0784:                    }
0785:
0786:                    parent.insertBefore(text, next);
0787:
0788:                    //            caret.setDot(new Position(text, str.length(), Bias.FORWARD));
0789:                    fireInsertUpdate(new DefaultDomDocumentEvent(this ,
0790:                            createDomPosition(text, str.length(), Bias.FORWARD)));
0791:
0792:                    return;
0793:                }
0794:
0795:                // Special handling for spaces! If the user hits the space
0796:                // bar multiple times, html will simply compress the spaces
0797:                // to a single character. So we have to convert this to
0798:                // a &nbsp;. However, we don't want ALL spaces to become
0799:                // &nbsp; since "nbsp" stands for "non breaking space" -
0800:                // this would totally break word wrapping - so we only
0801:                // convert the second and subsequent character in the
0802:                // sequence.
0803:                // But even that's not enough. We want the nonbreaking spaces
0804:                // to be located with the PREVIOUS word, not the next word,
0805:                // so we have to do a little magic.
0806:                // In particular (^ denotes caret/insert location for space):
0807:                //  "foo^bar" -> "foo bar"
0808:                //  "foo ^bar" -> "foo&nbsp; bar"
0809:                //  "foo&nbsp; ^bar" -> "foo&nbsp;&nbsp; bar"
0810:                //  "foo&nbsp;&nbsp; ^bar" -> "foo&nbsp;&nbsp;&nbsp; bar"
0811:                //  "foo&nbsp;^ bar" -> "foo&nbsp;&nbsp;^ bar"
0812:                // Algorithm:
0813:                //  if the character before the caret is a space
0814:                //   then insert an NBSP -before- it
0815:                //  else if the character after the caret is a space
0816:                //   then insert an NBSP
0817:                //  else insert a space
0818:                String data = text.getData();
0819:                int len = text.getLength();
0820:                assert offset <= len;
0821:
0822:                boolean before = (offset > 0)
0823:                        && (data.charAt(offset - 1) == ' ');
0824:                boolean after = (offset < len) && (data.charAt(offset) == ' ');
0825:                Node targetNode = node; // Node to move caret to when we're done
0826:                int targetOffset = offset;
0827:
0828:                if (before || after) {
0829:                    if (before) {
0830:                        offset--;
0831:                    }
0832:
0833:                    //final String NBSP_STRING = "\u00A0";
0834:                    final String NBSP_STRING;
0835:
0836:                    // XXX #115195 This is not OK for inline editing.
0837:                    if (!jsfForm.isInlineEditing()) {
0838:                        //            if (((RaveRenderNode)node).isJspx()) {
0839:                        if (MarkupService.isJspxNode(node)) {
0840:                            NBSP_STRING = "&nbsp;"; // JSPX source is "escaped"
0841:                        } else { // html - put it right into source. Should I try to insert
0842:
0843:                            // an entity reference here instead? Might not serialize well.
0844:                            // Make sure AttributeInlineEditor checks for this!
0845:                            NBSP_STRING = "\u00A0";
0846:                        }
0847:
0848:                        str = NBSP_STRING;
0849:                    }
0850:
0851:                    text.insertData(offset, str);
0852:                    targetNode = text;
0853:                    targetOffset += str.length();
0854:
0855:                    // Insert an entity instead
0856:
0857:                    /*
0858:                    // XXX No, that doesn't work right. The parser seems to
0859:                    // convert entities into character data, and not do the
0860:                    // reverse translation, so this doesn't buy us anything.
0861:                    EntityReference er = webform.getDom().createEntityReference("nbsp");
0862:                    if (offset == 0) {
0863:                        // Insert before our text node
0864:                        text.getParentNode().insertBefore(er, text);
0865:                        targetNode = text;
0866:                        targetOffset = 1;
0867:                    } else if (offset == text.getLength()) {
0868:                        // Insert after our text node
0869:                        // null for text.getNextSibling() is okay - will be
0870:                        // appended to the end of the list
0871:                        text.getParentNode().insertBefore(er, text.getNextSibling());
0872:                        targetNode = text;
0873:                        targetOffset += str.length();
0874:                    } else {
0875:                        // Insert in the middle of the text node; split it
0876:                        org.w3c.dom.Text secondHalf = text.splitText(offset);
0877:                        text.getParentNode().insertBefore(er, secondHalf);
0878:                        targetNode = secondHalf;
0879:                        targetOffset = 0;
0880:                    }
0881:                     */
0882:                } else {
0883:                    text.insertData(offset, str);
0884:                    targetNode = text;
0885:                    targetOffset += str.length();
0886:                }
0887:
0888:                // XXX check that this works on Windows too - or do they
0889:                // use \r\n ?
0890:                //        caret.setDot(new Position(targetNode, targetOffset, Bias.FORWARD));
0891:                fireInsertUpdate(new DefaultDomDocumentEvent(this ,
0892:                        createDomPosition(targetNode, targetOffset,
0893:                                Bias.FORWARD)));
0894:            }
0895:
0896:            //    /** XXX Copy also in insync/FacesDnDSupport
0897:            //     * Create a new bean of the given type, positioned below parent
0898:            //     * before the given node. Returns the created element. */
0899:            //    private DesignBean createBean(String className, Node parent, Node before) {
0900:            ////        MarkupPosition pos = new MarkupPosition(parent, before);
0901:            ////        DesignBean parentBean = /*FacesSupport.*/Util.findParentBean(parent);
0902:            ////        LiveUnit unit = webform.getModel().getLiveUnit();
0903:            ////        DesignBean bean = unit.createBean(className, parentBean, pos);
0904:            ////
0905:            ////        return bean;
0906:            //        return webform.createBean(className, parent, before);
0907:            //    }
0908:
0909:            //    /** XXX Copy also in insync/FacesDnDSupport.
0910:            //     * Given a node, return the nearest DesignBean that "contains" it */
0911:            //    private static DesignBean findParentBean(Node node) {
0912:            //        while (node != null) {
0913:            ////            if (node instanceof RaveElement) {
0914:            ////                RaveElement element = (RaveElement)node;
0915:            //            if (node instanceof Element) {
0916:            //                Element element = (Element)node;
0917:            //
0918:            ////                if (element.getDesignBean() != null) {
0919:            ////                    return element.getDesignBean();
0920:            ////                }
0921:            ////                MarkupDesignBean markupDesignBean = InSyncService.getProvider().getMarkupDesignBeanForElement(element);
0922:            //                MarkupDesignBean markupDesignBean = WebForm.getDomProviderService().getMarkupDesignBeanForElement(element);
0923:            //                if (markupDesignBean != null) {
0924:            //                    return markupDesignBean;
0925:            //                }
0926:            //            }
0927:            //
0928:            //            node = node.getParentNode();
0929:            //        }
0930:            //
0931:            //        return null;
0932:            //    }
0933:
0934:            /** Create a new element of the given type, positioned below parent
0935:             * before the given node. Returns the created element. */
0936:            private/*public*/Element createElement(String className,
0937:                    Node parent, Node before) {
0938:                // XXX TODO Pass in the tag name too. If we're editing in a DocumentFragment
0939:                // (e.g. inline editing) create elements directly rather than going
0940:                // through the designtime API.
0941:                //        DesignBean bean = createBean(className, parent, before);
0942:                //        DesignBean bean = webform.createBean(className, parent, before);
0943:                //        return webform.createComponent(className, parent, before);
0944:                return jsfForm.createComponent(className, parent, before);
0945:
0946:                //        if (bean == null) {
0947:                //            return null;
0948:                //        }
0949:
0950:                //        return FacesSupport.getMarkupBean(bean).getElement();
0951:                //        return Util.getMarkupBean(bean).getElement();
0952:                //        return WebForm.getDomProviderService().getMarkupBeanElement(bean);
0953:            }
0954:
0955:            // XXX Moved form DomRangeImpl.    
0956:            /** Delete all the JSF components found in the given range */
0957:            //    private void deleteComponents() {
0958:            private void deleteComponents(DomPosition first, DomPosition second) {
0959:                // This will require a traversal, but probably not using the
0960:                // DomTraversal class since we'll be deleting elements as
0961:                // we're traversing
0962:                //        Position second = getLastPosition();
0963:                //        DomPosition second = getLastPosition();
0964:
0965:                //        if (second == Position.NONE) {
0966:                if (second == DomPosition.NONE) {
0967:                    return;
0968:                }
0969:
0970:                //        Position first = getFirstPosition();
0971:                //        DomPosition first = getFirstPosition();
0972:                //        assert first.isEarlierThan(first);
0973:
0974:                Node firstNode = first.getNode();
0975:
0976:                if (firstNode instanceof  Element) {
0977:                    if (first.getOffset() < firstNode.getChildNodes()
0978:                            .getLength()) {
0979:                        firstNode = firstNode.getChildNodes().item(
0980:                                first.getOffset());
0981:                    }
0982:                }
0983:
0984:                Node secondNode = second.getNode();
0985:
0986:                if (first.equals(second)) {
0987:                    secondNode = firstNode;
0988:                } else if (secondNode instanceof  Element) {
0989:                    if ((second.getOffset() > 0)
0990:                            && (second.getOffset() <= secondNode
0991:                                    .getChildNodes().getLength())) {
0992:                        secondNode = secondNode.getChildNodes().item(
0993:                                second.getOffset() - 1);
0994:                    } else if (second.getOffset() == 0) {
0995:                        // Gotta locate immediate inorder traversal neighbor to the left
0996:                        while ((secondNode != null)
0997:                                && (secondNode.getPreviousSibling() == null)) {
0998:                            secondNode = secondNode.getParentNode();
0999:                        }
1000:
1001:                        if (secondNode == null) {
1002:                            ErrorManager.getDefault().log(
1003:                                    "Unexpected second position " + second); // NOI18N
1004:
1005:                            return;
1006:                        }
1007:
1008:                        secondNode = secondNode.getPreviousSibling();
1009:
1010:                        while (true) {
1011:                            NodeList nl = secondNode.getChildNodes();
1012:
1013:                            if (nl.getLength() > 0) {
1014:                                secondNode = nl.item(nl.getLength() - 1);
1015:                            } else {
1016:                                break;
1017:                            }
1018:                        }
1019:                    }
1020:                }
1021:
1022:                // Insert content for the first node
1023:                if ((firstNode == secondNode) && firstNode instanceof  Text) {
1024:                    // Common case - and we're done; no components to be deleted here
1025:                    return;
1026:                }
1027:
1028:                // Iterate over the range building up all the DesignBeans to be
1029:                // destroyed
1030:                //        ArrayList beans = new ArrayList();
1031:                List<Element> components = new ArrayList<Element>();
1032:
1033:                //        org.w3c.dom.Document dom = webform.getJspDom();
1034:                org.w3c.dom.Document dom = jsfForm.getJspDom();
1035:
1036:                if (!(dom instanceof  DocumentTraversal)) {
1037:                    return;
1038:                }
1039:
1040:                DocumentTraversal trav = (DocumentTraversal) dom;
1041:
1042:                // Iterating over all since we can't just limit ourselves to text nodes
1043:                // in case the target node is not necessarily a text node!
1044:                NodeIterator iterator = trav.createNodeIterator(dom,
1045:                        NodeFilter.SHOW_ALL, null, false);
1046:
1047:                // The node iterator doesn't seem to have a way to jump to a
1048:                // particular node, so we search for it ourselves
1049:                Node curr = firstNode;
1050:
1051:                while (curr != null) {
1052:                    try {
1053:                        curr = iterator.nextNode();
1054:
1055:                        if (curr == firstNode) {
1056:                            break;
1057:                        }
1058:                    } catch (DOMException ex) {
1059:                        ErrorManager.getDefault().notify(
1060:                                ErrorManager.INFORMATIONAL, ex);
1061:
1062:                        break;
1063:                    }
1064:                }
1065:
1066:                Node last = secondNode;
1067:
1068:                while (curr != null) {
1069:                    //            if (curr instanceof RaveElement) {
1070:                    //                RaveElement element = (RaveElement)curr;
1071:                    if (curr instanceof  Element) {
1072:                        Element element = (Element) curr;
1073:                        //                DesignBean bean = element.getDesignBean();
1074:                        //                DesignBean bean = InSyncService.getProvider().getMarkupDesignBeanForElement(element);
1075:                        //                DesignBean bean = WebForm.getDomProviderService().getMarkupDesignBeanForElement(element);
1076:                        Element componentRootElement = MarkupService
1077:                                .getRenderedElementForElement(element);
1078:
1079:                        //                if ((bean != null) &&
1080:                        if ((componentRootElement != null)
1081:                                && ((element.getParentNode() == null) ||
1082:                                //                        (element.getParentNode() instanceof RaveElement &&
1083:                                //                        (((RaveElement)element.getParentNode()).getDesignBean() != bean)))) {
1084:                                (element.getParentNode() instanceof  Element
1085:                                //                        && InSyncService.getProvider().getMarkupDesignBeanForElement((Element)element.getParentNode()) != bean))) {
1086:                                //                        && WebForm.getDomProviderService().getMarkupDesignBeanForElement((Element)element.getParentNode()) != bean))) {
1087:                                && MarkupService
1088:                                        .getRenderedElementForElement((Element) element
1089:                                                .getParentNode()) != componentRootElement))) {
1090:                            //                    if (!beans.contains(bean)) {
1091:                            //                        beans.add(bean);
1092:                            //                    }
1093:                            if (!components.contains(componentRootElement)) {
1094:                                components.add(componentRootElement);
1095:                            }
1096:                        }
1097:                    }
1098:
1099:                    if ((curr == null) || (curr == last)) {
1100:                        break;
1101:                    }
1102:
1103:                    try {
1104:                        curr = iterator.nextNode();
1105:                    } catch (DOMException ex) {
1106:                        ErrorManager.getDefault().notify(ex);
1107:
1108:                        break;
1109:                    }
1110:                }
1111:
1112:                iterator.detach();
1113:
1114:                //        FacesModel model = webform.getModel();
1115:                //        Document doc = webform.getDocument();
1116:
1117:                ////        UndoEvent undoEvent = webform.getModel().writeLock(NbBundle.getMessage(DeleteNextCharAction.class, "DeleteText")); // NOI18N
1118:                ////        DomProvider.WriteLock writeLock = webform.writeLock(NbBundle.getMessage(DeleteNextCharAction.class, "DeleteText")); // NOI18N
1119:                //        DomProvider.WriteLock writeLock = jsfForm.writeLock(NbBundle.getMessage(DomDocumentImpl.class, "LBL_DeleteText")); // NOI18N
1120:                //        try {
1121:                ////            doc.writeLock(NbBundle.getMessage(DeleteNextCharAction.class, "DeleteText")); // NOI18N
1122:                //
1123:                ////            for (int i = 0; i < beans.size(); i++) {
1124:                ////                DesignBean bean = (DesignBean)beans.get(i);
1125:                //            for (Element componentRootElement : components) {
1126:                //
1127:                ////                if (!FacesSupport.isSpecialBean(/*webform, */bean)) {
1128:                ////                if (!Util.isSpecialBean(bean)) {
1129:                ////                if (bean instanceof MarkupDesignBean && !WebForm.getDomProviderService().isSpecialComponent(
1130:                ////                        WebForm.getDomProviderService().getComponentRootElementForMarkupDesignBean((MarkupDesignBean)bean))) {
1131:                ////                if (!WebForm.getDomProviderService().isSpecialComponent(componentRootElement)) {
1132:                //                if (!JsfSupportUtilities.isSpecialComponent(componentRootElement)) {
1133:                ////                    model.getLiveUnit().deleteBean(bean);
1134:                ////                    webform.deleteBean(bean);
1135:                ////                    webform.deleteComponent(componentRootElement);
1136:                //                    jsfForm.deleteComponent(componentRootElement);
1137:                //                }
1138:                //            }
1139:                //        } finally {
1140:                ////            doc.writeUnlock();
1141:                ////            webform.getModel().writeUnlock(undoEvent);
1142:                ////            webform.writeUnlock(writeLock);
1143:                //            jsfForm.writeUnlock(writeLock);
1144:                //        }
1145:                deleteComponents(components.toArray(new Element[components
1146:                        .size()]));
1147:            }
1148:
1149:            /** Return the text in the range (linearized to a String); this is only the
1150:             * text nodes, not comment nodes, not markup, etc.
1151:             */
1152:            private String getText(DomPosition first, DomPosition second) {
1153:                // Since we'll be iterating forwards, gotta make sure we know
1154:                // which point is first
1155:                //        Position second = getLastPosition();
1156:                //        DomPosition second = getLastPosition();
1157:
1158:                //        if (second == Position.NONE) {
1159:                if (second == DomPosition.NONE) {
1160:                    return "";
1161:                }
1162:
1163:                //        Position first = getFirstPosition();
1164:                //        DomPosition first = getFirstPosition();
1165:                //        assert first.isEarlierThan(first);
1166:
1167:                StringBuffer sb = new StringBuffer();
1168:
1169:                Node firstNode = first.getNode();
1170:
1171:                if (firstNode instanceof  Element) {
1172:                    if (first.getOffset() < firstNode.getChildNodes()
1173:                            .getLength()) {
1174:                        firstNode = firstNode.getChildNodes().item(
1175:                                first.getOffset());
1176:                    }
1177:                }
1178:
1179:                Node secondNode = second.getNode();
1180:
1181:                if (first.equals(second)) {
1182:                    secondNode = firstNode;
1183:                } else if (secondNode instanceof  Element) {
1184:                    if ((second.getOffset() > 0)
1185:                            && (second.getOffset() <= secondNode
1186:                                    .getChildNodes().getLength())) {
1187:                        secondNode = secondNode.getChildNodes().item(
1188:                                second.getOffset() - 1);
1189:                    } else if (second.getOffset() == 0) {
1190:                        // Gotta locate immediate inorder traversal neighbor to the left
1191:                        while ((secondNode != null)
1192:                                && (secondNode.getPreviousSibling() == null)) {
1193:                            secondNode = secondNode.getParentNode();
1194:                        }
1195:
1196:                        if (secondNode == null) {
1197:                            ErrorManager.getDefault().log(
1198:                                    "Unexpected second position " + second); // NOI18N
1199:
1200:                            return "";
1201:                        }
1202:
1203:                        secondNode = secondNode.getPreviousSibling();
1204:
1205:                        while (true) {
1206:                            NodeList nl = secondNode.getChildNodes();
1207:
1208:                            if (nl.getLength() > 0) {
1209:                                secondNode = nl.item(nl.getLength() - 1);
1210:                            } else {
1211:                                break;
1212:                            }
1213:                        }
1214:                    }
1215:                }
1216:
1217:                // Insert content for the first node
1218:                if (firstNode instanceof  Text) {
1219:                    if (secondNode == firstNode) {
1220:                        String s = firstNode.getNodeValue();
1221:
1222:                        for (int i = first.getOffset(); i < second.getOffset(); i++) {
1223:                            sb.append(s.charAt(i));
1224:                        }
1225:
1226:                        return sb.toString();
1227:                    } else {
1228:                        String s = firstNode.getNodeValue();
1229:
1230:                        for (int i = first.getOffset(), n = s.length(); i < n; i++) {
1231:                            sb.append(s.charAt(i));
1232:                        }
1233:                    }
1234:                }
1235:
1236:                // Append content for all the nodes between first and second
1237:                //        org.w3c.dom.Document dom = webform.getJspDom();
1238:                org.w3c.dom.Document dom = jsfForm.getJspDom();
1239:
1240:                if (!(dom instanceof  DocumentTraversal)) {
1241:                    return "";
1242:                }
1243:
1244:                DocumentTraversal trav = (DocumentTraversal) dom;
1245:
1246:                // Iterating over all since we can't just limit ourselves to text nodes
1247:                // in case the target node is not necessarily a text node!
1248:                NodeIterator iterator = trav.createNodeIterator(dom,
1249:                        NodeFilter.SHOW_ALL, null, false);
1250:                Node curr = firstNode;
1251:
1252:                // The node iterator doesn't seem to have a way to jump to a particular node,
1253:                // so we search for it ourselves
1254:                while (curr != null) {
1255:                    try {
1256:                        curr = iterator.nextNode();
1257:
1258:                        if (curr == firstNode) {
1259:                            break;
1260:                        }
1261:                    } catch (DOMException ex) {
1262:                        ErrorManager.getDefault().notify(ex);
1263:
1264:                        break;
1265:                    }
1266:                }
1267:
1268:                Node last = secondNode;
1269:
1270:                while (curr != null) {
1271:                    try {
1272:                        curr = iterator.nextNode();
1273:                    } catch (DOMException ex) {
1274:                        ErrorManager.getDefault().notify(ex);
1275:
1276:                        break;
1277:                    }
1278:
1279:                    if ((curr == null) || (curr == last)) {
1280:                        break;
1281:                    }
1282:
1283:                    if (curr instanceof  Text) {
1284:                        sb.append(curr.getNodeValue());
1285:                    }
1286:                }
1287:
1288:                iterator.detach();
1289:
1290:                // Append content for the last node
1291:                if (secondNode instanceof  Text) {
1292:                    String s = secondNode.getNodeValue();
1293:
1294:                    for (int i = 0; i < second.getOffset(); i++) {
1295:                        sb.append(s.charAt(i));
1296:                    }
1297:                }
1298:
1299:                return sb.toString();
1300:            }
1301:
1302:            // XXX Moved to GridHandler.
1303:            //    /** Transfer the given element such that it's parented at the given position */
1304:            //    public boolean reparent(DesignBean bean, Element element, Position pos) {
1305:            //        if (pos == Position.NONE) {
1306:            //            return false;
1307:            //        }
1308:            //
1309:            //        // First see where it's currently located
1310:            //        Position currPos = Position.create(element, false);
1311:            //
1312:            //        if (pos.equals(currPos)) {
1313:            //            return true; // Already in the right place - done
1314:            //        }
1315:            //
1316:            ////        if (pos.isRendered()) {
1317:            //        if (MarkupService.isRenderedNode(pos.getNode())) {
1318:            //            pos = pos.getSourcePosition();
1319:            //        }
1320:            //
1321:            //        if (pos == Position.NONE) {
1322:            //            return false;
1323:            //        }
1324:            //
1325:            //        Node node = pos.getNode();
1326:            //
1327:            //        // Ensure the node is not in a DocumentFragment - if it is, moving
1328:            //        // an element here is going to remove it from the jsp!!
1329:            //        Node curr = node;
1330:            //
1331:            //        while (curr.getParentNode() != null) {
1332:            //            curr = curr.getParentNode();
1333:            //        }
1334:            //
1335:            //        //if (curr instanceof DocumentFragment) {
1336:            //        if (curr != webform.getJspDom()) {
1337:            //            return false;
1338:            //        }
1339:            //
1340:            //        Node parentNode = node;
1341:            //        Node before = null;
1342:            //
1343:            //        if (node instanceof Text) {
1344:            //            parentNode = node.getParentNode();
1345:            //
1346:            //            if (pos.getOffset() == 0) {
1347:            //                before = node;
1348:            //            } else {
1349:            //                Text txt = (Text)node;
1350:            //
1351:            //                if (pos.getOffset() < txt.getLength()) {
1352:            //                    before = txt.splitText(pos.getOffset());
1353:            //                } else {
1354:            //                    // Ugh, what if it's the last node here??
1355:            //                    // XXX won't work right!
1356:            //                    before = txt.getNextSibling();
1357:            //                }
1358:            //            }
1359:            //        } else {
1360:            //            before = parentNode.getFirstChild();
1361:            //
1362:            //            for (int i = 0, n = pos.getOffset(); i < n; i++) {
1363:            //                if (before == null) {
1364:            //                    break;
1365:            //                }
1366:            //
1367:            //                before = before.getNextSibling();
1368:            //            }
1369:            //        }
1370:            //
1371:            //        if (before == element) {
1372:            //            return true;
1373:            //        }
1374:            //
1375:            ////        LiveUnit lu = webform.getModel().getLiveUnit();
1376:            ////        MarkupPosition markupPos = new MarkupPosition(parentNode, before);
1377:            ////        DesignBean parentBean = null;
1378:            ////        Node e = parentNode;
1379:            ////
1380:            ////        while (e != null) {
1381:            //////            if (e instanceof RaveElement) {
1382:            //////                parentBean = ((RaveElement)e).getDesignBean();
1383:            ////            if (e instanceof Element) {
1384:            //////                parentBean = InSyncService.getProvider().getMarkupDesignBeanForElement((Element)e);
1385:            ////                parentBean = WebForm.getDomProviderService().getMarkupDesignBeanForElement((Element)e);
1386:            ////                
1387:            ////                if (parentBean != null) {
1388:            ////                    break;
1389:            ////                }
1390:            ////            }
1391:            ////
1392:            ////            e = e.getParentNode();
1393:            ////        }
1394:            ////
1395:            ////        if (bean == parentBean) {
1396:            ////            return false;
1397:            ////        }
1398:            ////
1399:            ////        boolean success = lu.moveBean(bean, parentBean, markupPos);
1400:            //        boolean success = webform.moveBean(bean, parentNode, before);
1401:            //
1402:            //        if (webform.getPane().getCaret() != null) {
1403:            //            pos = ModelViewMapper.getFirstDocumentPosition(webform, false);
1404:            //            webform.getPane().getCaret().setDot(pos);
1405:            //        }
1406:            //
1407:            //        return success;
1408:            //    }
1409:
1410:            //    /**
1411:            //     * Acquires a lock to begin mutating the document this lock
1412:            //     * protects.  There can be no writing, notification of changes, or
1413:            //     * reading going on in order to gain the lock.  Additionally a thread is
1414:            //     * allowed to gain more than one <code>writeLock</code>,
1415:            //     * as long as it doesn't attempt to gain additional <code>writeLock</code>s
1416:            //     * from within document notification.
1417:            //     * @param description Description of the task being initiated
1418:            //     */
1419:            //    public final synchronized void writeLock(String description) {
1420:            //        undoEvent = webform.getModel().writeLock(description);
1421:            //    }
1422:            //
1423:            //    /**
1424:            //     * Releases a write lock previously obtained via <code>writeLock</code>.
1425:            //     * After decrementing the lock count if there are no oustanding locks
1426:            //     * this will allow a new writer, or readers.
1427:            //     *
1428:            //     * @see #writeLock
1429:            //     */
1430:            //    public final synchronized void writeUnlock() {
1431:            //        webform.getModel().writeUnlock(undoEvent);
1432:            //        undoEvent = null;
1433:            //    }
1434:
1435:            //    /**
1436:            //     * Acquires a lock to begin reading some state from the
1437:            //     * document.  There can be multiple readers at the same time.
1438:            //     * Writing blocks the readers until notification of the change
1439:            //     * to the listeners has been completed.  This method should
1440:            //     * be used very carefully to avoid unintended compromise
1441:            //     * of the document.  It should always be balanced with a
1442:            //     * <code>readUnlock</code>.
1443:            //     *
1444:            //     * @todo Consider making this API protected
1445:            //     * @see #readUnlock
1446:            //     */
1447:            //    public final synchronized void readLock() {
1448:            //        webform.getMarkup().readLock();
1449:            //    }
1450:            //
1451:            //    /**
1452:            //     * Does a read unlock.  This signals that one
1453:            //     * of the readers is done.  If there are no more readers
1454:            //     * then writing can begin again.  This should be balanced
1455:            //     * with a readLock, and should occur in a finally statement
1456:            //     * so that the balance is guaranteed.  The following is an
1457:            //     * example.
1458:            //     * <pre><code>
1459:            //     * &nbsp;   readLock();
1460:            //     * &nbsp;   try {
1461:            //     * &nbsp;       // do something
1462:            //     * &nbsp;   } finally {
1463:            //     * &nbsp;       readUnlock();
1464:            //     * &nbsp;   }
1465:            //     * </code></pre>
1466:            //     *
1467:            //     * @todo Consider making this API protected
1468:            //     * @see #readLock
1469:            //     */
1470:            //    public final synchronized void readUnlock() {
1471:            //        webform.getMarkup().readUnlock();
1472:            //    }
1473:
1474:            // XXX Moved to WebForm.isGridModeDocument.
1475:            //    // XXX Also in insync/FacesDnDSupport
1476:            //    /**
1477:            //     *  Return true if this document is in "grid mode" (objects
1478:            //     *  should be positioned by absolute coordinates instead of in
1479:            //     *  "flow" order.
1480:            //     *
1481:            //     *  @return true iff the document should be in grid mode
1482:            //     */
1483:            //    public boolean isGridMode() {
1484:            //        Element b = webform.getHtmlBody();
1485:            //
1486:            //        if (b == null) {
1487:            //            return false;
1488:            //        }
1489:            //
1490:            ////        Value val = CssLookup.getValue(b, XhtmlCss.RAVELAYOUT_INDEX);
1491:            //        CssValue cssValue = CssProvider.getEngineService().getComputedValueForElement(b, XhtmlCss.RAVELAYOUT_INDEX);
1492:            //
1493:            ////        return val == CssValueConstants.GRID_VALUE;
1494:            //        return CssProvider.getValueService().isGridValue(cssValue);
1495:            //    }
1496:
1497:            //    public Element findComponent(String id) {
1498:            //        // Hack for now
1499:            //        return findElement(webform.getHtmlBody(), id);
1500:            //    }
1501:            //
1502:            //    public Element findElement(String id) {
1503:            //        // Hack for now
1504:            //        return findElement(webform.getHtmlBody(), id);
1505:            //    }
1506:            //
1507:            //    private Element findElement(Element element, String id) {
1508:            //        String eid = element.getAttribute(HtmlAttribute.ID);
1509:            //
1510:            //        if ((eid != null) && (eid.equals(id))) {
1511:            //            return element;
1512:            //        }
1513:            //
1514:            //        NodeList list = element.getChildNodes();
1515:            //        int len = list.getLength();
1516:            //
1517:            //        for (int i = 0; i < len; i++) {
1518:            //            Node child = list.item(i);
1519:            //
1520:            //            if (child.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
1521:            //                element = findElement((Element)child, id);
1522:            //
1523:            //                if (element != null) {
1524:            //                    return element;
1525:            //                }
1526:            //            }
1527:            //        }
1528:            //
1529:            //        return null;
1530:            //    }
1531:
1532:            // XXX Moved to InteractionManager.
1533:            //    /**
1534:            //     * Report whether the given node is in a read-only region of
1535:            //     * the document or not.
1536:            //     */
1537:            //    public static boolean isReadOnlyRegion(Position pos) {
1538:            //        Node node = pos.getNode();
1539:            //
1540:            //        // Determine if this node is in a DocumentFragment which means
1541:            //        // it's read only
1542:            //        while (node != null) {
1543:            //            node = node.getParentNode();
1544:            //
1545:            //            if (node instanceof org.w3c.dom.Document) {
1546:            //                break;
1547:            //            }
1548:            //        }
1549:            //
1550:            //        return node == null;
1551:            //    }
1552:
1553:            // >>> Listening support.
1554:            // XXX Temporarily here, then after moved with document interface to the API together don't make it nested class.
1555:
1556:            private void fireInsertUpdate(DomDocumentEvent evt) {
1557:                for (DomDocumentListener l : getDomDocumentListeners()) {
1558:                    l.insertUpdate(evt);
1559:                }
1560:            }
1561:
1562:            private void fireComponentMoved(DomDocumentEvent evt) {
1563:                for (DomDocumentListener l : getDomDocumentListeners()) {
1564:                    l.componentMoved(evt);
1565:                }
1566:            }
1567:
1568:            private void fireComponentsMoved(DomDocumentEvent evt) {
1569:                for (DomDocumentListener l : getDomDocumentListeners()) {
1570:                    l.componentsMoved(evt);
1571:                }
1572:            }
1573:
1574:            private void fireComponentMovedTo(DomDocumentEvent evt) {
1575:                for (DomDocumentListener l : getDomDocumentListeners()) {
1576:                    l.componentMovedTo(evt);
1577:                }
1578:            }
1579:
1580:            private final EventListenerList listenerList = new EventListenerList();
1581:
1582:            public void addDomDocumentListener(DomDocumentListener l) {
1583:                listenerList.add(DomDocumentListener.class, l);
1584:            }
1585:
1586:            public void removeDomDocumentListener(DomDocumentListener l) {
1587:                listenerList.remove(DomDocumentListener.class, l);
1588:            }
1589:
1590:            private DomDocumentListener[] getDomDocumentListeners() {
1591:                return listenerList.getListeners(DomDocumentListener.class);
1592:            }
1593:
1594:            public DomProvider.DomPosition createDomPosition(Node node,
1595:                    int offset, DomPosition.Bias bias) {
1596:                if (node == null) {
1597:                    return DomPosition.NONE;
1598:                }
1599:                return DomPositionImpl.create(this , node, offset, bias);
1600:            }
1601:
1602:            public DomProvider.DomPosition createNextDomPosition(Node node,
1603:                    boolean after) {
1604:                if (node == null) {
1605:                    return DomPosition.NONE;
1606:                }
1607:                return DomPositionImpl.createNext(this , node, after);
1608:            }
1609:
1610:            public DomProvider.DomRange createRange(Node dotNode,
1611:                    int dotOffset, Node markNode, int markOffset) {
1612:                return DomRangeImpl.create(this , dotNode, dotOffset, markNode,
1613:                        markOffset);
1614:            }
1615:
1616:            public int compareBoudaryPoints(Node endPointA, int offsetA,
1617:                    Node endPointB, int offsetB) {
1618:                return DomPositionImpl.compareBoundaryPoints(endPointA,
1619:                        offsetA, endPointB, offsetB);
1620:            }
1621:
1622:            public DomProvider.DomPosition first(
1623:                    DomProvider.DomPosition dot,
1624:                    org.netbeans.modules.visualweb.api.designer.DomProvider.DomPosition mark) {
1625:                return DomPositionImpl.first(dot, mark);
1626:            }
1627:
1628:            public DomProvider.DomPosition last(
1629:                    DomProvider.DomPosition dot,
1630:                    org.netbeans.modules.visualweb.api.designer.DomProvider.DomPosition mark) {
1631:                return DomPositionImpl.last(dot, mark);
1632:            }
1633:
1634:            private static class DefaultDomDocumentEvent implements 
1635:                    DomDocumentEvent {
1636:                private final DomDocument document;
1637:                private final DomPosition position;
1638:
1639:                public DefaultDomDocumentEvent(DomDocument document,
1640:                        DomPosition position) {
1641:                    this .document = document;
1642:                    this .position = position;
1643:                }
1644:
1645:                public DomDocument getDomDocument() {
1646:                    return document;
1647:                }
1648:
1649:                public DomPosition getDomPosition() {
1650:                    return position;
1651:                }
1652:            } // End of DefaultDomDocumentEvent.
1653:
1654:            /** Transfer the given element such that it's parented at the given position */
1655:            //    private boolean reparent(DesignBean bean, Element element, Position pos, WebForm webform) {
1656:            //    private boolean reparentComponent(Element componentRootElement, /*Element element,*/ Position pos, WebForm webform) {
1657:            private boolean reparentComponent(Element componentRootElement, /*Element element,*/
1658:                    DomPosition pos /*, WebForm webform*/) {
1659:                //        if (pos == Position.NONE) {
1660:                if (pos == DomPosition.NONE) {
1661:                    return false;
1662:                }
1663:
1664:                // First see where it's currently located
1665:                //        Position currPos = Position.create(element, false);
1666:                //        Position currPos = Position.create(componentRootElement, false);
1667:                //        DomPosition currPos = webform.createDomPosition(componentRootElement, false);
1668:                DomPosition currPos = createNextDomPosition(
1669:                        componentRootElement, false);
1670:
1671:                if (pos.equals(currPos)) {
1672:                    return true; // Already in the right place - done
1673:                }
1674:
1675:                //        if (pos.isRendered()) {
1676:                //        if (MarkupService.isRenderedNode(pos.getNode())) {
1677:                if (isRenderedNode(pos.getNode())) {
1678:                    pos = pos.getSourcePosition();
1679:                }
1680:
1681:                //        if (pos == Position.NONE) {
1682:                if (pos == DomPosition.NONE) {
1683:                    return false;
1684:                }
1685:
1686:                Node node = pos.getNode();
1687:
1688:                // Ensure the node is not in a DocumentFragment - if it is, moving
1689:                // an element here is going to remove it from the jsp!!
1690:                Node curr = node;
1691:
1692:                while (curr.getParentNode() != null) {
1693:                    curr = curr.getParentNode();
1694:                }
1695:
1696:                //if (curr instanceof DocumentFragment) {
1697:                //        if (curr != webform.getJspDom()) {
1698:                if (curr != jsfForm.getJspDom()) {
1699:                    return false;
1700:                }
1701:
1702:                Node parentNode = node;
1703:                Node before = null;
1704:
1705:                if (node instanceof  Text) {
1706:                    parentNode = node.getParentNode();
1707:
1708:                    if (pos.getOffset() == 0) {
1709:                        before = node;
1710:                    } else {
1711:                        Text txt = (Text) node;
1712:
1713:                        if (pos.getOffset() < txt.getLength()) {
1714:                            before = txt.splitText(pos.getOffset());
1715:                        } else {
1716:                            // Ugh, what if it's the last node here??
1717:                            // XXX won't work right!
1718:                            before = txt.getNextSibling();
1719:                        }
1720:                    }
1721:                } else {
1722:                    before = parentNode.getFirstChild();
1723:
1724:                    for (int i = 0, n = pos.getOffset(); i < n; i++) {
1725:                        if (before == null) {
1726:                            break;
1727:                        }
1728:
1729:                        before = before.getNextSibling();
1730:                    }
1731:                }
1732:
1733:                //        if (before == element) {
1734:                // XXX Comparing rendered with source element can never fit.
1735:                if (before == componentRootElement) {
1736:                    return true;
1737:                }
1738:
1739:                //        LiveUnit lu = webform.getModel().getLiveUnit();
1740:                //        MarkupPosition markupPos = new MarkupPosition(parentNode, before);
1741:                //        DesignBean parentBean = null;
1742:                //        Node e = parentNode;
1743:                //
1744:                //        while (e != null) {
1745:                ////            if (e instanceof RaveElement) {
1746:                ////                parentBean = ((RaveElement)e).getDesignBean();
1747:                //            if (e instanceof Element) {
1748:                ////                parentBean = InSyncService.getProvider().getMarkupDesignBeanForElement((Element)e);
1749:                //                parentBean = WebForm.getDomProviderService().getMarkupDesignBeanForElement((Element)e);
1750:                //                
1751:                //                if (parentBean != null) {
1752:                //                    break;
1753:                //                }
1754:                //            }
1755:                //
1756:                //            e = e.getParentNode();
1757:                //        }
1758:                //
1759:                //        if (bean == parentBean) {
1760:                //            return false;
1761:                //        }
1762:                //
1763:                //        boolean success = lu.moveBean(bean, parentBean, markupPos);
1764:                //        boolean success = webform.moveComponent(componentRootElement, parentNode, before);
1765:                boolean success = jsfForm.moveComponent(componentRootElement,
1766:                        parentNode, before);
1767:
1768:                ////        if (webform.getPane().getCaret() != null) {
1769:                //        if (webform.getPane().hasCaret()) {
1770:                //            pos = ModelViewMapper.getFirstDocumentPosition(webform, false);
1771:                ////            webform.getPane().getCaret().setDot(pos);
1772:                //            webform.getPane().setCaretDot(pos);
1773:                //        }
1774:                fireComponentMoved(new DefaultDomDocumentEvent(this , null));
1775:
1776:                return success;
1777:            }
1778:
1779:            // XXX Moved from designer/../GridHandler
1780:            // TODO 1) Refactor, there should be listener on the designer, informing about user actions.
1781:            // TODO 2) This is very messy, simplify, devide to more methods.
1782:            public void moveComponents(Designer designer, Box[] boxes,
1783:                    Point[] offsetPoints, DomPosition pos, int newX, int newY,
1784:                    boolean snapEnabled) {
1785:                // Locate a grid layout parent
1786:                //        Document doc = editor.getDocument();
1787:                //        WebForm webform = doc.getWebForm();
1788:                //        WebForm webform = editor.getWebForm();
1789:
1790:                //        int numMoved = beans.size();
1791:                //        int numMoved = boxes.size();
1792:                int numMoved = boxes.length;
1793:
1794:                //        Rectangle boundingBox = null;
1795:
1796:                String description;
1797:                if (numMoved > 1) {
1798:                    //            description = NbBundle.getMessage(GridHandler.class, "MoveComponents");
1799:                    description = NbBundle.getMessage(DomDocumentImpl.class,
1800:                            "LBL_MoveComponents");
1801:                } else {
1802:                    description = NbBundle.getMessage(DomDocumentImpl.class,
1803:                            "LBL_MoveComponent");
1804:                }
1805:                //        UndoEvent undoEvent = webform.getModel().writeLock(description);
1806:                //        DomProvider.WriteLock writeLock = webform.writeLock(description);
1807:                //        DomProvider.WriteLock writeLock = jsfForm.writeLock(description);
1808:                UndoEvent writeLock = jsfForm.writeLock(description);
1809:                try {
1810:                    //            String description;
1811:                    //
1812:                    //            if (numMoved > 1) {
1813:                    //                description = NbBundle.getMessage(GridHandler.class, "MoveComponents");
1814:                    //            } else {
1815:                    //                description = NbBundle.getMessage(GridHandler.class, "MoveComponent");
1816:                    //            }
1817:                    //
1818:                    //            doc.writeLock(description);
1819:
1820:                    // Move the components
1821:                    for (int i = 0; i < numMoved; i++) {
1822:                        //                MarkupDesignBean bean = beans.get(i);
1823:                        //                Rectangle offset = offsetRectangles.get(i);
1824:                        //                CssBox box = boxes.get(i);
1825:                        //                CssBox box = boxes[i];
1826:                        Box box = boxes[i];
1827:                        //                Rectangle offset = offsetRectangles[i];
1828:                        Point offset = offsetPoints[i];
1829:
1830:                        //                Element componentRootElement = CssBox.getElementForComponentRootCssBox(box);
1831:                        Element componentRootElement = box
1832:                                .getComponentRootElement();
1833:
1834:                        //                Element e = box.getElement();
1835:                        //
1836:                        //                if (e == null) {
1837:                        //                    e = bean.getElement();
1838:                        //                }
1839:
1840:                        //                int x = newX + offset.x;
1841:                        //                int y = newY + offset.y;
1842:                        //
1843:                        //                if (!snapDisabled) {
1844:                        //                    x = snapX(x, box.getPositionedBy());
1845:                        //                    y = snapY(y, box.getPositionedBy());
1846:                        //                }
1847:
1848:                        int x = newX + offset.x;
1849:                        int y = newY + offset.y;
1850:
1851:                        if (snapEnabled) {
1852:                            x = designer.snapX(x, box.getPositionedBy());
1853:                            y = designer.snapY(y, box.getPositionedBy());
1854:                        }
1855:
1856:                        //                CssBox parentBox = box.getParent();
1857:                        Box parentBox = box.getParent();
1858:
1859:                        //                if (boundingBox == null) {
1860:                        //                    boundingBox = new Rectangle(x, y, box.getWidth(), box.getHeight());
1861:                        //                } else {
1862:                        //                    boundingBox.add(x, y);
1863:                        //                    boundingBox.add(x + box.getWidth(), y + box.getHeight());
1864:                        //                }
1865:
1866:                        try {
1867:                            boolean moveSucceeded = true;
1868:
1869:                            //                    if ((pos != null) && (pos != Position.NONE)) {
1870:                            if ((pos != null) && (pos != DomPosition.NONE)) {
1871:                                // TODO: better batch handling here
1872:                                //                        moveSucceeded = doc.reparent(bean, e, pos);
1873:                                //                        moveSucceeded = reparentComponent(componentRootElement, /*e,*/ pos, webform);
1874:                                //                        moveSucceeded = webForm.getDomDocument().reparentComponent(componentRootElement, /*e,*/ pos);
1875:                                moveSucceeded = reparentComponent(
1876:                                        componentRootElement, /*e,*/pos);
1877:                            } else if (!isAbsolutelyPositioned(componentRootElement)) {
1878:                                // Looks like we've moved a flow position element
1879:                                // out to grid
1880:                                //                        CssBox pb = null;
1881:                                Element parent = null;
1882:                                //                        Element element = box.getDesignBean().getElement();
1883:                                // XXX Possible NPE?
1884:                                //                        Element element = CssBox.getMarkupDesignBeanForCssBox(box).getElement();
1885:                                //                        Element boxComponentRootElement = CssBox.getElementForComponentRootCssBox(box);
1886:                                Element boxComponentRootElement = componentRootElement;
1887:                                // XXX Get rid of using source elements in the designer.
1888:                                Element element = MarkupService
1889:                                        .getSourceElementForElement(boxComponentRootElement);
1890:
1891:                                if (element == null) {
1892:                                    // XXX #124560 Give one more try.
1893:                                    MarkupDesignBean markupDesignBean = MarkupUnit
1894:                                            .getMarkupDesignBeanForElement(boxComponentRootElement);
1895:                                    if (markupDesignBean != null) {
1896:                                        element = markupDesignBean.getElement();
1897:                                    }
1898:
1899:                                    // XXX #109112 This box is not to move.
1900:                                    if (element == null) {
1901:                                        continue;
1902:                                    }
1903:                                }
1904:
1905:                                if (element.getParentNode() != null
1906:                                        && element.getParentNode()
1907:                                                .getNodeType() == org.w3c.dom.Node.ELEMENT_NODE
1908:                                        && element.getParentNode()
1909:                                                .getNodeName().equals(
1910:                                                        HtmlTag.FSUBVIEW.name)) {
1911:                                    //                            pb = parentBox;
1912:                                    parent = (Element) element.getParentNode();
1913:                                    //                        } else if ((parentBox != null) && (parentBox.getDesignBean() != null)) {
1914:                                    //                            MarkupDesignBean parentBean = parentBox.getDesignBean();
1915:                                } else {
1916:                                    //                            MarkupDesignBean parentMarkupDesignBean = CssBox.getMarkupDesignBeanForCssBox(parentBox);
1917:                                    //                            Element parentComponentRootElement = CssBox.getElementForComponentRootCssBox(parentBox);
1918:                                    Element parentComponentRootElement = parentBox == null ? null
1919:                                            : parentBox
1920:                                                    .getComponentRootElement();
1921:                                    if (parentComponentRootElement != null) {
1922:                                        Element parentElement = MarkupService
1923:                                                .getSourceElementForElement(parentComponentRootElement);
1924:
1925:                                        if ((parentElement != null)
1926:                                                && (parentElement.getTagName()
1927:                                                        .equals(HtmlTag.FORM.name))) {
1928:                                            //                                    pb = parentBox;
1929:                                            //                                    parent = parentBox.getSourceElement();
1930:                                            parent = parentElement;
1931:                                        }
1932:                                    }
1933:                                }
1934:
1935:                                //                        Designer[] designers = JsfForm.findDesigners(jsfForm);
1936:                                //                        Designer designer = designers.length == 0 ? null : designers[0];
1937:
1938:                                //                        if (pb == null) {
1939:                                if (parent == null) {
1940:                                    //                            CssBox currentBox = webform.getMapper().findBox(x, y);
1941:                                    //                            CssBox currentBox = ModelViewMapper.findBox(webform.getPane().getPageBox(), x, y);
1942:                                    Box currentBox = designer.findBox(x, y);
1943:                                    if (currentBox != null) {
1944:
1945:                                        //                                for (int j = 0, m = currentBox.getBoxCount(); j < m; j++) {
1946:                                        //                                    HtmlTag tag = currentBox.getBox(j).getTag();
1947:                                        for (Box child : currentBox
1948:                                                .getChildren()) {
1949:                                            HtmlTag tag = child.getTag();
1950:
1951:                                            if (tag == HtmlTag.FORM) {
1952:                                                //                                    pb = currentBox.getBox(j);
1953:                                                //                                        parent = currentBox.getSourceElement();
1954:                                                // #102848 Get the form (not body).
1955:                                                parent = child
1956:                                                        .getSourceElement();
1957:
1958:                                                break;
1959:                                            }
1960:                                        }
1961:
1962:                                        //                            if (pb == null) {
1963:                                        //                                pb = currentBox;
1964:                                        //                            }
1965:                                        if (parent == null) {
1966:                                            parent = currentBox
1967:                                                    .getSourceElement();
1968:                                        }
1969:                                    }
1970:                                }
1971:
1972:                                //                        if (parent == null) {
1973:                                //                            parent = pb.getSourceElement();
1974:                                //                        }
1975:
1976:                                if (element.getParentNode() != parent) {
1977:                                    moveSucceeded =
1978:                                    //                                doc.reparent(bean, e, new Position(parent, 0, Bias.FORWARD));
1979:                                    //                                reparentComponent(componentRootElement, /*e,*/ new Position(parent, 0, Bias.FORWARD), webform);
1980:                                    //                                reparentComponent(componentRootElement, /*e,*/ Position.create(parent, 0, Bias.FORWARD), webform);
1981:                                    //                                reparentComponent(componentRootElement, /*e,*/ webForm.createDomPosition(parent, 0, Bias.FORWARD), webform);
1982:                                    //                                webForm.getDomDocument().reparentComponent(componentRootElement, /*e,*/ webForm.createDomPosition(parent, 0, Bias.FORWARD));
1983:                                    reparentComponent(componentRootElement, /*e,*/
1984:                                            createDomPosition(parent, 0,
1985:                                                    Bias.FORWARD));
1986:                                }
1987:
1988:                                //                        parentBox = pb;
1989:                                //                        CssBox pb = webForm.findCssBoxForElement(parent);
1990:                                Box pb = designer
1991:                                        .findBoxForSourceElement(parent);
1992:                                if (pb != null) {
1993:                                    parentBox = pb;
1994:                                }
1995:                            }
1996:
1997:                            // prevent multiple updates for the same element -
1998:                            // only need a single refresh especially when just changing
1999:                            // from one grid position to another
2000:                            //                    webform.getDomSynchronizer().setUpdatesSuspended(bean, true);
2001:                            //                    webform.setUpdatesSuspended(componentRootElement, true);
2002:                            jsfForm.setUpdatesSuspended(componentRootElement,
2003:                                    true);
2004:
2005:                            List<StyleData> set = new ArrayList<StyleData>(3);
2006:                            List<StyleData> remove = new ArrayList<StyleData>(3);
2007:
2008:                            //                    if ((pos != null) && (pos != Position.NONE)) {
2009:                            if ((pos != null) && (pos != DomPosition.NONE)) {
2010:                                if (moveSucceeded) {
2011:                                    remove.add(new StyleData(
2012:                                            XhtmlCss.POSITION_INDEX));
2013:                                    remove.add(new StyleData(
2014:                                            XhtmlCss.LEFT_INDEX));
2015:                                    remove
2016:                                            .add(new StyleData(
2017:                                                    XhtmlCss.TOP_INDEX));
2018:                                } else {
2019:                                    java.awt.Toolkit.getDefaultToolkit().beep();
2020:                                }
2021:                            } else if (moveSucceeded) {
2022:                                // Translate coordinates from absolute/viewport
2023:                                // to absolute coordinates relative to the target
2024:                                // grid container
2025:                                set.add(new StyleData(XhtmlCss.POSITION_INDEX,
2026:                                //                                CssConstants.CSS_ABSOLUTE_VALUE));
2027:                                        CssProvider.getValueService()
2028:                                                .getAbsoluteValue()));
2029:                                set.add(getHorizontalCssSetting(x, box
2030:                                        .getWidth(), box, parentBox,
2031:                                        componentRootElement));
2032:                                set.add(getVerticalCssSetting(y, box
2033:                                        .getHeight(), box, parentBox,
2034:                                        componentRootElement));
2035:                            }
2036:
2037:                            //                    XhtmlCssEngine engine = webform.getMarkup().getCssEngine();
2038:                            // <removing design bean manipulation in engine>
2039:                            //                    engine.updateLocalStyleValues((RaveElement)e, set, remove);
2040:                            // ====
2041:                            //                    Util.updateLocalStyleValuesForElement(e,
2042:                            //                            (StyleData[])set.toArray(new StyleData[set.size()]),
2043:                            //                            (StyleData[])remove.toArray(new StyleData[remove.size()]));
2044:                            //                    WebForm.getDomProviderService().updateLocalStyleValuesForElement(componentRootElement,
2045:                            //                            set.toArray(new StyleData[set.size()]),
2046:                            //                            remove.toArray(new StyleData[remove.size()]));
2047:                            JsfSupportUtilities
2048:                                    .updateLocalStyleValuesForElement(
2049:                                            componentRootElement, set
2050:                                                    .toArray(new StyleData[set
2051:                                                            .size()]),
2052:                                            remove.toArray(new StyleData[remove
2053:                                                    .size()]));
2054:                            // </removing design bean manipulation in engine>
2055:                        } finally {
2056:                            //                    webform.getDomSynchronizer().setUpdatesSuspended(bean, false);
2057:                            //                    webform.setUpdatesSuspended(componentRootElement, false);
2058:                            jsfForm.setUpdatesSuspended(componentRootElement,
2059:                                    false);
2060:                        }
2061:                    }
2062:                } finally {
2063:                    //            doc.writeUnlock();
2064:                    //            webform.getModel().writeUnlock(undoEvent);
2065:                    //            webform.writeUnlock(writeLock);
2066:                    jsfForm.writeUnlock(writeLock);
2067:                }
2068:
2069:                // XXX #91531 User didn't want to have this kind of autoscroll behavior.
2070:                //        final Rectangle rect = boundingBox;
2071:                //	// #6331237 NPE.
2072:                //	if(rect != null) {
2073:                //	    SwingUtilities.invokeLater(new Runnable() {
2074:                //		public void run() {
2075:                //		    editor.scrollRectToVisible(rect);
2076:                //		}
2077:                //	    });
2078:                //	}
2079:                fireComponentsMoved(new DefaultDomDocumentEvent(this , null));
2080:            }
2081:
2082:            // XXX Copy aldo in designer/../GridHandler.
2083:            /** Report whether the given element is absolutely positioned */
2084:            private boolean isAbsolutelyPositioned(Element element) {
2085:                boolean absolute;
2086:                //        Value val = CssLookup.getValue(element, XhtmlCss.POSITION_INDEX);
2087:                CssValue cssValue = CssProvider.getEngineService()
2088:                        .getComputedValueForElement(element,
2089:                                XhtmlCss.POSITION_INDEX);
2090:
2091:                //        if ((val == CssValueConstants.ABSOLUTE_VALUE) || (val == CssValueConstants.FIXED_VALUE)) {
2092:                if (CssProvider.getValueService().isAbsoluteValue(cssValue)
2093:                        || CssProvider.getValueService().isFixedValue(cssValue)) {
2094:                    absolute = true;
2095:                } else {
2096:                    absolute = false;
2097:                }
2098:
2099:                return absolute;
2100:            }
2101:
2102:            /**
2103:             * Given a target position (referring to the border top left corner) for
2104:             * a box, update its horizontal CSS position properties (left/right) to
2105:             * make the box appear at the target position.
2106:             * This not only converts the coordinates to the margin edge (since the
2107:             * CSS properties are relative to it), but also ensures that if a component
2108:             * is for example only constrained on the right, the "right" property is
2109:             * updated rather than "left".
2110:             */
2111:            //    private StyleData getHorizontalCssSetting(int x, int newWidth, CssBox box, CssBox parentBox, Element e) {
2112:            private StyleData getHorizontalCssSetting(int x, int newWidth,
2113:                    Box box, Box parentBox, Element e) {
2114:                //        int left = CssLookup.getLength(e, XhtmlCss.LEFT_INDEX);
2115:                //        int right = CssLookup.getLength(e, XhtmlCss.RIGHT_INDEX);
2116:                //        int left = CssUtilities.getCssLength(e, XhtmlCss.LEFT_INDEX);
2117:                //        int right = CssUtilities.getCssLength(e, XhtmlCss.RIGHT_INDEX);
2118:                int left = CssProvider.getValueService().getCssLength(e,
2119:                        XhtmlCss.LEFT_INDEX);
2120:                int right = CssProvider.getValueService().getCssLength(e,
2121:                        XhtmlCss.RIGHT_INDEX);
2122:
2123:                //        if ((left == CssBox.AUTO) && (right != CssBox.AUTO)) {
2124:                if ((left == CssValue.AUTO) && (right != CssValue.AUTO)) {
2125:                    //            int rx = right - (x - box.getX()) - (width - box.getWidth());
2126:                    //            Point p = translateCoordinates(parentBox, rx, 0);
2127:                    //            rx = p.x;
2128:                    //
2129:                    //            // The CSS "right" property is relative to the Margin edge
2130:                    //            rx += box.getRightMargin();
2131:                    int rx = translateRight(right, x, newWidth, box, parentBox);
2132:
2133:                    return new StyleData(XhtmlCss.RIGHT_INDEX, Integer
2134:                            .toString(rx)
2135:                            + "px"); // NOI18N
2136:                } else {
2137:                    //            Point p = translateCoordinates(parentBox, x, 0);
2138:                    //            x = p.x;
2139:                    //
2140:                    //            // The CSS "left" property is relative to the Margin edge
2141:                    //            x -= box.getLeftMargin();
2142:                    int rx = translateLeft(x, box, parentBox);
2143:
2144:                    //            return new StyleData(XhtmlCss.LEFT_INDEX, Integer.toString(x) + "px"); // NOI18N
2145:                    return new StyleData(XhtmlCss.LEFT_INDEX, Integer
2146:                            .toString(rx)
2147:                            + "px"); // NOI18N
2148:                }
2149:            }
2150:
2151:            // XXX Copy also in designer/../GridHandler.
2152:            //    private int translateRight(int right, int x, int newWidth, CssBox box, CssBox parentBox) {
2153:            private int translateRight(int right, int x, int newWidth, Box box,
2154:                    Box parentBox) {
2155:                int rx = right - (x - box.getX()) - (newWidth - box.getWidth());
2156:                //        Point p = translateCoordinates(parentBox, rx, 0);
2157:                Point p = JsfSupportUtilities.translateCoordinates(parentBox,
2158:                        rx, 0);
2159:                rx = p.x;
2160:
2161:                // The CSS "right" property is relative to the Margin edge
2162:                rx += box.getRightMargin();
2163:                return rx;
2164:            }
2165:
2166:            // XXX Copy also in designer/../GridHandler
2167:            //    private int translateLeft(int x, CssBox box, CssBox parentBox) {
2168:            private int translateLeft(int x, Box box, Box parentBox) {
2169:                //        Point p = translateCoordinates(parentBox, x, 0);
2170:                Point p = JsfSupportUtilities.translateCoordinates(parentBox,
2171:                        x, 0);
2172:                x = p.x;
2173:
2174:                // The CSS "left" property is relative to the Margin edge
2175:                x -= box.getLeftMargin();
2176:                return x;
2177:            }
2178:
2179:            // XXX Copy also in designer/../GridHandler.
2180:            /** Same as setHorizontalCssPosition, but for the vertical dimension with
2181:             * CSS top/bottom properties */
2182:            //    private StyleData getVerticalCssSetting(int y, int newHeight, CssBox box, CssBox parentBox, Element e) {
2183:            private StyleData getVerticalCssSetting(int y, int newHeight,
2184:                    Box box, Box parentBox, Element e) {
2185:                //        int top = CssLookup.getLength(e, XhtmlCss.TOP_INDEX);
2186:                //        int bottom = CssLookup.getLength(e, XhtmlCss.BOTTOM_INDEX);
2187:                //        int top = CssUtilities.getCssLength(e, XhtmlCss.TOP_INDEX);
2188:                //        int bottom = CssUtilities.getCssLength(e, XhtmlCss.BOTTOM_INDEX);
2189:                int top = CssProvider.getValueService().getCssLength(e,
2190:                        XhtmlCss.TOP_INDEX);
2191:                int bottom = CssProvider.getValueService().getCssLength(e,
2192:                        XhtmlCss.BOTTOM_INDEX);
2193:
2194:                //        if ((top == CssBox.AUTO) && (bottom != CssBox.AUTO)) {
2195:                if ((top == CssValue.AUTO) && (bottom != CssValue.AUTO)) {
2196:                    //            int ry = bottom - (y - box.getY()) - (height - box.getHeight());
2197:                    //            Point p = translateCoordinates(parentBox, 0, ry);
2198:                    //            ry = p.y;
2199:                    //
2200:                    //            // The CSS "bottom" property is relative to the Margin edge
2201:                    //            ry += box.getEffectiveTopMargin();
2202:                    int ry = translateBottom(bottom, y, newHeight, box,
2203:                            parentBox);
2204:
2205:                    return new StyleData(XhtmlCss.BOTTOM_INDEX, Integer
2206:                            .toString(ry)
2207:                            + "px"); // NOI18N
2208:                } else {
2209:                    //            Point p = translateCoordinates(parentBox, 0, y);
2210:                    //            y = p.y;
2211:                    //
2212:                    //            // The CSS "top" property is relative to the Margin edge
2213:                    //            y -= box.getEffectiveTopMargin();
2214:                    int ry = translateTop(y, box, parentBox);
2215:
2216:                    //            return new StyleData(XhtmlCss.TOP_INDEX, Integer.toString(y) + "px"); // NOI18N
2217:                    return new StyleData(XhtmlCss.TOP_INDEX, Integer
2218:                            .toString(ry)
2219:                            + "px"); // NOI18N
2220:                }
2221:            }
2222:
2223:            // XXX Copy also in designer/../GridHandler.
2224:            //    private int translateBottom(int bottom, int y, int newHeight, CssBox box, CssBox parentBox) {
2225:            private int translateBottom(int bottom, int y, int newHeight,
2226:                    Box box, Box parentBox) {
2227:                int ry = bottom - (y - box.getY())
2228:                        - (newHeight - box.getHeight());
2229:                //        Point p = translateCoordinates(parentBox, 0, ry);
2230:                Point p = JsfSupportUtilities.translateCoordinates(parentBox,
2231:                        0, ry);
2232:                ry = p.y;
2233:
2234:                // The CSS "bottom" property is relative to the Margin edge
2235:                ry += box.getEffectiveTopMargin();
2236:                return ry;
2237:            }
2238:
2239:            // XXX Copy also in designer/../GridHandler.
2240:            //    private int translateTop(int y, CssBox box, CssBox parentBox) {
2241:            private int translateTop(int y, Box box, Box parentBox) {
2242:                //        Point p = translateCoordinates(parentBox, 0, y);
2243:                Point p = JsfSupportUtilities.translateCoordinates(parentBox,
2244:                        0, y);
2245:                y = p.y;
2246:
2247:                // The CSS "top" property is relative to the Margin edge
2248:                y -= box.getEffectiveTopMargin();
2249:                return y;
2250:            }
2251:
2252:            //    // XXX Copy aldo in designer/../CssUtilities.
2253:            //    // FIXME This is very suspicious, and should be revisited.
2254:            //    public static final int AUTO = Integer.MAX_VALUE - 1;
2255:            //    
2256:            //    /** XXX Copy also in insync/FacesDnDSupport.
2257:            //     * XXX Copy also in designer/../CssUtilities
2258:            //     * XXX Provides the auto value as <code>AUTO</code>, revise that, it looks very dangerous.
2259:            //     * TODO At least move into designer/cssengine.
2260:            //     */
2261:            //    private static int getCssLength(Element element, int property) {
2262:            ////        Value val = getValue(element, property);
2263:            //        CssValue cssValue = CssProvider.getEngineService().getComputedValueForElement(element, property);
2264:            //        
2265:            //        // XXX #6460007 Possible NPE.
2266:            //        if (cssValue == null) {
2267:            //            // XXX What value to return?
2268:            //            return 0;
2269:            //        }
2270:            //        
2271:            ////        if (val == CssValueConstants.AUTO_VALUE) {
2272:            //        if (CssProvider.getValueService().isAutoValue(cssValue)) {
2273:            //            return AUTO;
2274:            //        }
2275:            //        
2276:            ////        return (int)val.getFloatValue();
2277:            //        return (int)cssValue.getFloatValue();
2278:            //    }
2279:
2280:            //    // XXX Copy also in designer/../GridHandler.
2281:            //    /** Given absolute coordinates x,y in the viewport, compute
2282:            //     * the CSS coordinates to assign to a box if it's parented by
2283:            //     * the given parentBox such that the coordinates will result
2284:            //     * in a box showing up at the absolute coordinates.
2285:            //     * That was a really convoluted explanation, so to be specific:
2286:            //     * If you have an absolutely positioned <div> at 100, 100,
2287:            //     * and you drag a button into it such that it's its child,
2288:            //     * and you drag it to screen coordinate 75, 150, then, in order
2289:            //     * for the button to be rendered at 75, 150 and be a child of
2290:            //     * the div its top/left coordinates must be -25, 50.
2291:            //     */
2292:            ////    private Point translateCoordinates(CssBox parentBox, int x, int y) {
2293:            //    private Point translateCoordinates(Box parentBox, int x, int y) {
2294:            //        while (parentBox != null) {
2295:            ////            if (parentBox.getBoxType().isPositioned()) {
2296:            //            if (parentBox.isPositioned()) {
2297:            //                x -= parentBox.getAbsoluteX();
2298:            //                y -= parentBox.getAbsoluteY();
2299:            //
2300:            //                return new Point(x, y);
2301:            //            }
2302:            //
2303:            //            if (parentBox.getPositionedBy() != null) {
2304:            //                parentBox = parentBox.getPositionedBy();
2305:            //            } else {
2306:            //                parentBox = parentBox.getParent();
2307:            //            }
2308:            //        }
2309:            //
2310:            //        return new Point(x, y);
2311:            //    }
2312:
2313:            private void moveComponentTo(Box box, int x, int y) {
2314:                Element componentRootElement = box.getComponentRootElement();
2315:                // We should already have a locked buffer with a user visible
2316:                // undo event when this methhod is called
2317:                // XXX Not here.
2318:                //        assert webform.getModel().isWriteLocked();
2319:                //        if (!webform.isWriteLocked()) {
2320:                if (!jsfForm.isWriteLocked()) {
2321:                    ErrorManager
2322:                            .getDefault()
2323:                            .notify(
2324:                                    ErrorManager.INFORMATIONAL,
2325:                                    new IllegalStateException(
2326:                                            "This method has to be called under write lock! It is not.")); // NOI18N
2327:                }
2328:
2329:                // prevent multiple updates for the same element - only need a single refresh
2330:                try {
2331:                    //            webform.getDomSynchronizer().setUpdatesSuspended(bean, true);
2332:                    //            webform.setUpdatesSuspended(componentRootElement, true);
2333:                    jsfForm.setUpdatesSuspended(componentRootElement, true);
2334:
2335:                    //            CssBox parentBox = box.getParent();
2336:                    Box parentBox = box.getParent();
2337:
2338:                    List<StyleData> set = new ArrayList<StyleData>(3);
2339:                    //            set.add(new StyleData(XhtmlCss.POSITION_INDEX, CssConstants.CSS_ABSOLUTE_VALUE));
2340:                    set.add(new StyleData(XhtmlCss.POSITION_INDEX, CssProvider
2341:                            .getValueService().getAbsoluteValue()));
2342:                    set.add(getHorizontalCssSetting(x, box.getWidth(), box,
2343:                            parentBox, componentRootElement));
2344:                    set.add(getVerticalCssSetting(y, box.getHeight(), box,
2345:                            parentBox, componentRootElement));
2346:
2347:                    //            XhtmlCssEngine engine = webform.getMarkup().getCssEngine();
2348:                    // <removing design bean manipulation in engine>
2349:                    //            engine.updateLocalStyleValues((RaveElement)e, set, null);
2350:                    // ====
2351:                    //            Util.updateLocalStyleValuesForElement(e,
2352:                    //                    (StyleData[])set.toArray(new StyleData[set.size()]), null);
2353:                    //            WebForm.getDomProviderService().updateLocalStyleValuesForElement(componentRootElement,
2354:                    //                    set.toArray(new StyleData[set.size()]), null);
2355:                    JsfSupportUtilities.updateLocalStyleValuesForElement(
2356:                            componentRootElement, set.toArray(new StyleData[set
2357:                                    .size()]), null);
2358:                    // </removing design bean manipulation in engine>
2359:                } finally {
2360:                    //            webform.getDomSynchronizer().setUpdatesSuspended(bean, false);
2361:                    //            webform.setUpdatesSuspended(componentRootElement, false);
2362:                    jsfForm.setUpdatesSuspended(componentRootElement, false);
2363:                }
2364:
2365:                fireComponentMovedTo(new DefaultDomDocumentEvent(this , null));
2366:            }
2367:
2368:            // XXX Moved from designer/../GridHandler.
2369:            public void frontComponents(Box[] boxes) {
2370:                //        Document doc = webform.getDocument();
2371:
2372:                //        UndoEvent undoEvent = webform.getModel().writeLock(NbBundle.getMessage(GridHandler.class, "BringToFront")); // NOI18N
2373:                //        DomProvider.WriteLock writeLock = webform.writeLock(NbBundle.getMessage(GridHandler.class, "BringToFront")); // NOI18N
2374:                //        DomProvider.WriteLock writeLock = jsfForm.writeLock(NbBundle.getMessage(DomDocumentImpl.class, "LBL_BringToFront")); // NOI18N
2375:                UndoEvent writeLock = jsfForm.writeLock(NbBundle.getMessage(
2376:                        DomDocumentImpl.class, "LBL_BringToFront")); // NOI18N
2377:                try {
2378:                    //            doc.writeLock(NbBundle.getMessage(GridHandler.class, "BringToFront")); // NOI18N
2379:
2380:                    //            int num = boxes.size();
2381:                    int num = boxes.length;
2382:
2383:                    //            for (int i = 0; i < num; i++) {
2384:                    //                CssBox box = boxes.get(i);
2385:                    //            for (CssBox box : boxes) {
2386:                    for (Box box : boxes) {
2387:                        //                MarkupDesignBean bean = box.getDesignBean();
2388:                        //                MarkupDesignBean bean = CssBox.getMarkupDesignBeanForCssBox(box);
2389:                        //                Element componentRootElement = CssBox.getElementForComponentRootCssBox(box);
2390:                        Element componentRootElement = box
2391:                                .getComponentRootElement();
2392:
2393:                        //                assert bean != null;
2394:
2395:                        //                Element e = box.getElement();
2396:
2397:                        //                if (e == null) {
2398:                        //                    e = bean.getElement();
2399:                        //                }
2400:
2401:                        //                assert e != null;
2402:                        if (componentRootElement == null) {
2403:                            ErrorManager.getDefault().notify(
2404:                                    ErrorManager.INFORMATIONAL,
2405:                                    new NullPointerException(
2406:                                            "There is no component root element for box="
2407:                                                    + box));
2408:                            continue;
2409:                        }
2410:
2411:                        // Locate the highest z index in box' parent
2412:                        //                int highest = CssBox.AUTO;
2413:                        int highest = CssValue.AUTO;
2414:                        //                CssBox parent = box.getParent();
2415:                        Box parent = box.getParent();
2416:
2417:                        // #6358276 NPE.
2418:                        if (parent != null) {
2419:                            //                    for (int j = 0, m = parent.getBoxCount(); j < m; j++) {
2420:                            //                        CssBox sibling = parent.getBox(j);
2421:                            for (Box sibling : parent.getChildren()) {
2422:
2423:                                if (sibling == box) {
2424:                                    continue;
2425:                                }
2426:
2427:                                //                        if ((highest == CssBox.AUTO) ||
2428:                                //                                ((sibling.getZ() != CssBox.AUTO) && (sibling.getZ() > highest))) {
2429:                                if ((highest == CssValue.AUTO)
2430:                                        || ((sibling.getZ() != CssValue.AUTO) && (sibling
2431:                                                .getZ() > highest))) {
2432:                                    highest = sibling.getZ();
2433:                                }
2434:                            }
2435:                        }
2436:
2437:                        //                if (highest == CssBox.AUTO) {
2438:                        if (highest == CssValue.AUTO) {
2439:                            highest = 500;
2440:                        } else {
2441:                            highest++;
2442:                        }
2443:
2444:                        try {
2445:                            //                    doc.getWebForm().getDomSynchronizer().setUpdatesSuspended(bean, true);
2446:                            //                    doc.getWebForm().setUpdatesSuspended(componentRootElement, true);
2447:                            //                    webform.setUpdatesSuspended(componentRootElement, true);
2448:                            jsfForm.setUpdatesSuspended(componentRootElement,
2449:                                    true);
2450:
2451:                            //                    XhtmlCssEngine engine = webform.getMarkup().getCssEngine();
2452:
2453:                            List<StyleData> set = new ArrayList<StyleData>(1);
2454:                            set.add(new StyleData(XhtmlCss.Z_INDEX, Integer
2455:                                    .toString(highest)));
2456:                            // <removing design bean manipulation in engine>
2457:                            //                    engine.updateLocalStyleValues((RaveElement)e, set, null);
2458:                            // ====
2459:                            //                    Util.updateLocalStyleValuesForElement(e,
2460:                            //                            (StyleData[])set.toArray(new StyleData[set.size()]), null);
2461:                            //                    WebForm.getDomProviderService().updateLocalStyleValuesForElement(componentRootElement,
2462:                            //                            set.toArray(new StyleData[set.size()]), null);
2463:                            JsfSupportUtilities
2464:                                    .updateLocalStyleValuesForElement(
2465:                                            componentRootElement, set
2466:                                                    .toArray(new StyleData[set
2467:                                                            .size()]), null);
2468:                            // </removing design bean manipulation in engine>
2469:                        } finally {
2470:                            //                    doc.getWebForm().getDomSynchronizer().setUpdatesSuspended(bean, false);
2471:                            //                    doc.getWebForm().setUpdatesSuspended(componentRootElement, false);
2472:                            //                    webform.setUpdatesSuspended(componentRootElement, false);
2473:                            jsfForm.setUpdatesSuspended(componentRootElement,
2474:                                    false);
2475:                        }
2476:                    }
2477:                } finally {
2478:                    //            doc.writeUnlock();
2479:                    //            webform.getModel().writeUnlock(undoEvent);
2480:                    //            webform.writeUnlock(writeLock);
2481:                    jsfForm.writeUnlock(writeLock);
2482:                }
2483:            }
2484:
2485:            // XXX Moved from designer/../GridHandler.
2486:            //    public void back(WebForm webform, List<CssBox> boxes) {
2487:            public void backComponents(Box[] boxes) {
2488:                //        Document doc = webform.getDocument();
2489:
2490:                //        UndoEvent undoEvent = webform.getModel().writeLock(NbBundle.getMessage(GridHandler.class, "SendToBack")); // NOI18N
2491:                //        DomProvider.WriteLock writeLock = webform.writeLock(NbBundle.getMessage(GridHandler.class, "SendToBack")); // NOI18N
2492:                //        DomProvider.WriteLock writeLock = jsfForm.writeLock(NbBundle.getMessage(DomDocumentImpl.class, "LBL_SendToBack")); // NOI18N
2493:                UndoEvent writeLock = jsfForm.writeLock(NbBundle.getMessage(
2494:                        DomDocumentImpl.class, "LBL_SendToBack")); // NOI18N
2495:                try {
2496:                    //            doc.writeLock(NbBundle.getMessage(GridHandler.class, "SendToBack")); // NOI18N
2497:
2498:                    //            int num = boxes.size();
2499:                    int num = boxes.length;
2500:
2501:                    //            for (int i = 0; i < num; i++) {
2502:                    //                CssBox box = boxes.get(i);
2503:                    //            for (CssBox box : boxes) {
2504:                    for (Box box : boxes) {
2505:                        //                MarkupDesignBean bean = box.getDesignBean();
2506:                        //                MarkupDesignBean bean = CssBox.getMarkupDesignBeanForCssBox(box);
2507:                        //                Element componentRootElement = CssBox.getElementForComponentRootCssBox(box);
2508:                        Element componentRootElement = box
2509:                                .getComponentRootElement();
2510:                        //                assert bean != null;
2511:
2512:                        //                Element e = box.getElement();
2513:                        //                Element e = componentRootElement;
2514:
2515:                        //                if (e == null) {
2516:                        //                    e = bean.getElement();
2517:                        //                }
2518:
2519:                        //                assert e != null;
2520:                        if (componentRootElement == null) {
2521:                            ErrorManager.getDefault().notify(
2522:                                    ErrorManager.INFORMATIONAL,
2523:                                    new NullPointerException(
2524:                                            "There is no component root element for box="
2525:                                                    + box));
2526:                            continue;
2527:                        }
2528:
2529:                        // Locate the lowest z index in box' parent
2530:                        // XXX is auto less than 0?
2531:                        //                int lowest = CssBox.AUTO;
2532:                        int lowest = CssValue.AUTO;
2533:                        //                CssBox parent = box.getParent();
2534:                        Box parent = box.getParent();
2535:
2536:                        // #6358276 NPE.
2537:                        if (parent != null) {
2538:                            //                    for (int j = 0, m = parent.getBoxCount(); j < m; j++) {
2539:                            //                        CssBox sibling = parent.getBox(j);
2540:                            for (Box sibling : parent.getChildren()) {
2541:                                if (sibling == box) {
2542:                                    continue;
2543:                                }
2544:
2545:                                //                        if ((lowest == CssBox.AUTO) ||
2546:                                //                                ((sibling.getZ() != CssBox.AUTO) && (sibling.getZ() < lowest))) {
2547:                                //                            lowest = sibling.getZ();
2548:                                //                        }
2549:                                if ((lowest == CssValue.AUTO)
2550:                                        || ((sibling.getZ() != CssValue.AUTO) && (sibling
2551:                                                .getZ() < lowest))) {
2552:                                    lowest = sibling.getZ();
2553:                                }
2554:                            }
2555:                        }
2556:
2557:                        //                if (lowest == CssBox.AUTO) {
2558:                        if (lowest == CssValue.AUTO) {
2559:                            lowest = 500;
2560:                        } else {
2561:                            lowest--;
2562:                        }
2563:
2564:                        try {
2565:                            //                    webform.getDomSynchronizer().setUpdatesSuspended(bean, true);
2566:                            //                    webform.setUpdatesSuspended(componentRootElement, true);
2567:                            jsfForm.setUpdatesSuspended(componentRootElement,
2568:                                    true);
2569:
2570:                            //                    XhtmlCssEngine engine = webform.getMarkup().getCssEngine();
2571:
2572:                            List<StyleData> set = new ArrayList<StyleData>(1);
2573:                            set.add(new StyleData(XhtmlCss.Z_INDEX, Integer
2574:                                    .toString(lowest)));
2575:                            // <removing design bean manipulation in engine>
2576:                            //                    engine.updateLocalStyleValues((RaveElement)e, set, null);
2577:                            // ====
2578:                            //                    Util.updateLocalStyleValuesForElement(e,
2579:                            //                            (StyleData[])set.toArray(new StyleData[set.size()]), null);
2580:                            //                    WebForm.getDomProviderService().updateLocalStyleValuesForElement(componentRootElement,
2581:                            //                            set.toArray(new StyleData[set.size()]), null);
2582:                            JsfSupportUtilities
2583:                                    .updateLocalStyleValuesForElement(
2584:                                            componentRootElement, set
2585:                                                    .toArray(new StyleData[set
2586:                                                            .size()]), null);
2587:                            // </removing design bean manipulation in engine>
2588:                        } finally {
2589:                            //                    webform.getDomSynchronizer().setUpdatesSuspended(bean, false);
2590:                            //                    webform.setUpdatesSuspended(componentRootElement, false);
2591:                            jsfForm.setUpdatesSuspended(componentRootElement,
2592:                                    false);
2593:                        }
2594:                    }
2595:                } finally {
2596:                    //            doc.writeUnlock();
2597:                    //            webform.getModel().writeUnlock(undoEvent);
2598:                    //            webform.writeUnlock(writeLock);
2599:                    jsfForm.writeUnlock(writeLock);
2600:                }
2601:            }
2602:
2603:            // XXX Moved from designer/../GridHandler.
2604:            /** Resize the given component to new dimensions.
2605:             * Note that the x,y position might change too, for example, when
2606:             * you resize the component by dragging a selection handle on the
2607:             * top or left edges of the component.
2608:             *
2609:             * <p>
2610:             * @param editor The editor containing the resized component
2611:             * @param component Component being resized
2612:             * @param element The DOM element for the component
2613:             * @param newX The left edge of the component after resize
2614:             * @param xMoved True iff the left edge position changed during the resize
2615:             * @param newY The top edge of the component after resize
2616:             * @param yMoved True iff the top edge position moved during the resize
2617:             * @param newWidth The new width after resize
2618:             * @param newHeight The new height after resize
2619:             * @param box Box being resized
2620:             * @param snapDisabled If true, skip snapping
2621:             * @todo Should I use floating point coordinates instead?
2622:             */
2623:            //    public void resize(DesignerPane editor, Element componentRootElement, /*MarkupDesignBean bean,*/ int newX, boolean xMoved,
2624:            //        int newY, boolean yMoved, int newWidth, boolean widthChanged, int newHeight,
2625:            //        boolean heightChanged, CssBox box, boolean snapDisabled) {
2626:            public void resizeComponent(Designer designer,
2627:                    Element componentRootElement, /*MarkupDesignBean bean,*/
2628:                    int newX, boolean xMoved, int newY, boolean yMoved,
2629:                    int newWidth, boolean widthChanged, int newHeight,
2630:                    boolean heightChanged, Box box, boolean snapEnabled) {
2631:                // Locate a grid layout parent
2632:                //        Document doc = editor.getDocument();
2633:                //        WebForm webform = doc.getWebForm();
2634:                //        WebForm webform = editor.getWebForm();
2635:
2636:                int x = newX;
2637:                int y = newY;
2638:
2639:                if (snapEnabled) {
2640:                    //            x = snapX(newX, box.getPositionedBy());
2641:                    //            y = snapY(newY, box.getPositionedBy());
2642:                    x = designer.snapX(newX, box.getPositionedBy());
2643:                    y = designer.snapY(newY, box.getPositionedBy());
2644:                }
2645:
2646:                Element element = box.getElement();
2647:
2648:                if (element == null) {
2649:                    //            element = bean.getElement();
2650:                    element = componentRootElement;
2651:                }
2652:
2653:                boolean absolute = isAbsolutelyPositioned(element);
2654:
2655:                //        UndoEvent undoEvent = webform.getModel().writeLock(NbBundle.getMessage(GridHandler.class, "ResizeComponent")); // NOI18N
2656:                //        DomProvider.WriteLock writeLock = webform.writeLock(NbBundle.getMessage(GridHandler.class, "ResizeComponent")); // NOI18N
2657:                //        DomProvider.WriteLock writeLock = jsfForm.writeLock(NbBundle.getMessage(DomDocumentImpl.class, "LBL_ResizeComponent")); // NOI18N
2658:                UndoEvent writeLock = jsfForm.writeLock(NbBundle.getMessage(
2659:                        DomDocumentImpl.class, "LBL_ResizeComponent")); // NOI18N
2660:                // Gotta set width and height attributes!
2661:                try {
2662:                    //            doc.writeLock(NbBundle.getMessage(GridHandler.class, "ResizeComponent")); // NOI18N
2663:
2664:                    // prevent multiple updates for the same element - only need a single refresh
2665:                    //            webform.getDomSynchronizer().setUpdatesSuspended(bean, true);
2666:                    //            webform.setUpdatesSuspended(componentRootElement, true);
2667:                    jsfForm.setUpdatesSuspended(componentRootElement, true);
2668:
2669:                    List<StyleData> set = new ArrayList<StyleData>(5);
2670:                    List<StyleData> remove = new ArrayList<StyleData>(3);
2671:
2672:                    if (absolute && (xMoved || yMoved)) {
2673:                        //                set.add(new StyleData(XhtmlCss.POSITION_INDEX, CssConstants.CSS_ABSOLUTE_VALUE));
2674:                        set.add(new StyleData(XhtmlCss.POSITION_INDEX,
2675:                                CssProvider.getValueService()
2676:                                        .getAbsoluteValue()));
2677:
2678:                        //                CssBox parentBox = box.getParent();
2679:                        Box parentBox = box.getParent();
2680:
2681:                        if (xMoved) {
2682:                            set.add(getHorizontalCssSetting(x, newWidth, box,
2683:                                    parentBox, element));
2684:                        }
2685:
2686:                        if (yMoved) {
2687:                            set.add(getVerticalCssSetting(y, newHeight, box,
2688:                                    parentBox, element));
2689:                        }
2690:                    }
2691:
2692:                    if (widthChanged) {
2693:                        //                if (!DndHandler.setDesignProperty(bean, HtmlAttribute.WIDTH, newWidth, webform)) {
2694:                        //                if (!WebForm.getDomProviderService().setDesignProperty(bean, HtmlAttribute.WIDTH, newWidth)) {
2695:                        //                if (!WebForm.getDomProviderService().setStyleAttribute(componentRootElement, HtmlAttribute.WIDTH, newWidth)) {
2696:                        if (!JsfSupportUtilities.setStyleAttribute(
2697:                                componentRootElement, HtmlAttribute.WIDTH,
2698:                                newWidth)) {
2699:                            set.add(new StyleData(XhtmlCss.WIDTH_INDEX, Integer
2700:                                    .toString(newWidth)
2701:                                    + "px")); // NOI18N
2702:                        } else {
2703:                            // Ensure that we don't have a conflict
2704:                            remove.add(new StyleData(XhtmlCss.WIDTH_INDEX));
2705:                        }
2706:                    }
2707:
2708:                    if (heightChanged) {
2709:                        //                if (!DndHandler.setDesignProperty(bean, HtmlAttribute.HEIGHT, newHeight, webform)) {
2710:                        //                if (!WebForm.getDomProviderService().setDesignProperty(bean, HtmlAttribute.HEIGHT, newHeight)) {
2711:                        if (!JsfSupportUtilities.setStyleAttribute(
2712:                                componentRootElement, HtmlAttribute.HEIGHT,
2713:                                newHeight)) {
2714:                            set.add(new StyleData(XhtmlCss.HEIGHT_INDEX,
2715:                                    Integer.toString(newHeight) + "px")); // NOI18N
2716:                        } else {
2717:                            // Ensure that we don't have a conflict
2718:                            remove.add(new StyleData(XhtmlCss.HEIGHT_INDEX));
2719:                        }
2720:                    }
2721:
2722:                    //            XhtmlCssEngine engine = webform.getMarkup().getCssEngine();
2723:
2724:                    // <removing design bean manipulation in engine>
2725:                    //            engine.updateLocalStyleValues((RaveElement)element, set, remove);
2726:                    // ====
2727:                    //            Util.updateLocalStyleValuesForElement(element,
2728:                    //                    (StyleData[])set.toArray(new StyleData[set.size()]),
2729:                    //                    (StyleData[])remove.toArray(new StyleData[remove.size()]));
2730:                    //            WebForm.getDomProviderService().updateLocalStyleValuesForElement(element,
2731:                    //                    set.toArray(new StyleData[set.size()]),
2732:                    //                    remove.toArray(new StyleData[remove.size()]));
2733:                    JsfSupportUtilities.updateLocalStyleValuesForElement(
2734:                            element, set.toArray(new StyleData[set.size()]),
2735:                            remove.toArray(new StyleData[remove.size()]));
2736:                    // </removing design bean manipulation in engine>
2737:                } finally {
2738:                    //            webform.getDomSynchronizer().setUpdatesSuspended(bean, false);
2739:                    //            webform.setUpdatesSuspended(componentRootElement, false);
2740:                    jsfForm.setUpdatesSuspended(componentRootElement, false);
2741:                    //            doc.writeUnlock();
2742:                    //            webform.getModel().writeUnlock(undoEvent);
2743:                    //            webform.writeUnlock(writeLock);
2744:                    jsfForm.writeUnlock(writeLock);
2745:                }
2746:            }
2747:
2748:            // XXX Moved from designer/../GridHandler.
2749:            public void snapToGrid(Designer designer) {
2750:                ////        GridHandler handler = GridHandler.getInstance();
2751:                ////        DesignerPane editor = webForm.getPane();
2752:                //        SelectionManager sm = webForm.getSelection();
2753:                ////        Iterator it = sm.iterator();
2754:                //        Element[] componentRootElements = sm.getSelectedComponentRootElements();
2755:                ////        ModelViewMapper mapper = webform.getMapper();
2756:                Element[] componentRootElements = designer
2757:                        .getSelectedComponents();
2758:
2759:                boolean haveMoved = false;
2760:                //        Document doc = webform.getDocument();
2761:
2762:                //        UndoEvent undoEvent = webform.getModel().writeLock(NbBundle.getMessage(AlignAction.class, "LBL_SnapToGrid")); // NOI18N
2763:                //        DomProvider.WriteLock writeLock = webForm.writeLock(NbBundle.getMessage(GridHandler.class, "LBL_SnapToGrid")); // NOI18N
2764:                //        DomProvider.WriteLock writeLock = jsfForm.writeLock(NbBundle.getMessage(DomDocumentImpl.class, "LBL_SnapToGrid")); // NOI18N
2765:                UndoEvent writeLock = jsfForm.writeLock(NbBundle.getMessage(
2766:                        DomDocumentImpl.class, "LBL_SnapToGrid")); // NOI18N
2767:                try {
2768:                    //            doc.writeLock(NbBundle.getMessage(AlignAction.class, "LBL_SnapToGrid")); // NOI18N
2769:
2770:                    //            while (it.hasNext()) {
2771:                    //                MarkupDesignBean bean = (MarkupDesignBean)it.next();
2772:                    for (Element componentRootElement : componentRootElements) {
2773:                        //                MarkupDesignBean bean = WebForm.getDomProviderService().getMarkupDesignBeanForElement(componentRootElement);
2774:                        //                CssBox box = mapper.findBox(bean);
2775:                        //                CssBox box = ModelViewMapper.findBoxForComponentRootElement(webForm.getPane().getPageBox(), componentRootElement);
2776:                        Box box = designer
2777:                                .findBoxForComponentRootElement(componentRootElement);
2778:
2779:                        if (box == null) {
2780:                            continue;
2781:                        }
2782:
2783:                        //                boolean canAlign = box.getBoxType().isAbsolutelyPositioned();
2784:                        boolean canAlign = box.isAbsolutelyPositioned();
2785:
2786:                        if (!canAlign) {
2787:                            continue;
2788:                        }
2789:
2790:                        int x = box.getAbsoluteX();
2791:                        int y = box.getAbsoluteY();
2792:
2793:                        // Snap to grid.
2794:                        //                x = snapX(x, box.getPositionedBy());
2795:                        //                y = snapY(y, box.getPositionedBy());
2796:                        x = designer.snapX(x, box.getPositionedBy());
2797:                        y = designer.snapY(y, box.getPositionedBy());
2798:
2799:                        //                moveTo(editor, /*bean,*/ box, x, y /*, false*/);
2800:                        //                webForm.getDomDocument().moveComponentTo(box, x, y);
2801:                        moveComponentTo(box, x, y);
2802:
2803:                        haveMoved = true;
2804:                    }
2805:                } finally {
2806:                    //            doc.writeUnlock();
2807:                    //            webform.getModel().writeUnlock(undoEvent);
2808:                    //            webForm.writeUnlock(writeLock);
2809:                    jsfForm.writeUnlock(writeLock);
2810:                }
2811:
2812:                //        if (!haveMoved) {
2813:                //            StatusDisplayer.getDefault().setStatusText(NbBundle.getMessage(GridHandler.class, "MSG_AlignAbsolute"));
2814:                //            UIManager.getLookAndFeel().provideErrorFeedback(webForm.getPane());
2815:                //        }
2816:
2817:                //        fireComponentsMoved(new DefaultDomDocumentEvent(this, null));
2818:            }
2819:
2820:            // XXX Moved from designer/../GridHandler.
2821:            public void align(Designer designer, JsfForm.Alignment alignment) {
2822:                // Primary
2823:                //        SelectionManager sm = webForm.getSelection();
2824:                //
2825:                //        if (sm.isSelectionEmpty()) {
2826:                //            return;
2827:                //        }
2828:                //
2829:                //        sm.pickPrimary();
2830:                Element primaryComponnetRootElement = designer
2831:                        .getPrimarySelectedComponent();
2832:
2833:                //        ModelViewMapper mapper = webform.getMapper();
2834:                //        CssBox primaryBox = mapper.findBox(sm.getPrimary());
2835:                //        CssBox primaryBox = ModelViewMapper.findBox(webForm.getPane().getPageBox(), sm.getPrimary());
2836:                Box primaryBox = designer
2837:                        .findBoxForComponentRootElement(primaryComponnetRootElement);
2838:
2839:                if (primaryBox == null) {
2840:                    return;
2841:                }
2842:
2843:                boolean haveMoved = false;
2844:                //        Document doc = webform.getDocument();
2845:
2846:                //        UndoEvent undoEvent = webform.getModel().writeLock(NbBundle.getMessage(SelectionManager.class, "Align")); // NOI18N
2847:                //        DomProvider.WriteLock writeLock = webForm.writeLock(NbBundle.getMessage(SelectionManager.class, "Align")); // NOI18N
2848:                //        DomProvider.WriteLock writeLock = jsfForm.writeLock(NbBundle.getMessage(DomDocumentImpl.class, "LBL_Align")); // NOI18N
2849:                UndoEvent writeLock = jsfForm.writeLock(NbBundle.getMessage(
2850:                        DomDocumentImpl.class, "LBL_Align")); // NOI18N
2851:                try {
2852:                    //            doc.writeLock(NbBundle.getMessage(SelectionManager.class, "Align")); // NOI18N
2853:
2854:                    //            GridHandler handler = GridHandler.getInstance();
2855:                    //            DesignerPane editor = webForm.getPane();
2856:                    //            boolean canAlign = primaryBox.getBoxType().isAbsolutelyPositioned();
2857:                    boolean canAlign = primaryBox.isAbsolutelyPositioned();
2858:
2859:                    int x = primaryBox.getAbsoluteX();
2860:                    int y = primaryBox.getAbsoluteY();
2861:                    int w = primaryBox.getWidth();
2862:                    int h = primaryBox.getHeight();
2863:                    //            Iterator it = sm.iterator();
2864:                    //
2865:                    //            while (canAlign && it.hasNext()) {
2866:                    //                MarkupDesignBean bean = (MarkupDesignBean)it.next();
2867:                    //            for (Element componentRootElement : sm.getSelectedComponentRootElements()) {
2868:                    for (Element componentRootElement : designer
2869:                            .getSelectedComponents()) {
2870:                        //                MarkupDesignBean bean = WebForm.getDomProviderService().getMarkupDesignBeanForElement(componentRootElement);
2871:                        //                CssBox box = mapper.findBox(bean);
2872:                        //                CssBox box = ModelViewMapper.findBoxForComponentRootElement(webForm.getPane().getPageBox(), componentRootElement);
2873:                        Box box = designer
2874:                                .findBoxForComponentRootElement(componentRootElement);
2875:
2876:                        if (box == null) {
2877:                            continue;
2878:                        }
2879:
2880:                        // XXX Should I use isPositioned() instead? (e.g. are relative
2881:                        // positioned boxes alignable?
2882:                        //                if (!box.getBoxType().isAbsolutelyPositioned()) {
2883:                        if (!box.isAbsolutelyPositioned()) {
2884:                            continue;
2885:                        }
2886:
2887:                        haveMoved = true;
2888:
2889:                        /*
2890:                         Element element = FacesSupport.getElement(fob.component);
2891:                         if (element == null) {
2892:                         continue;
2893:                         }
2894:                         */
2895:                        switch (alignment) {
2896:                        case TOP:
2897:                            //                    moveTo(editor, /*bean,*/ box, box.getAbsoluteX(), y/*, true*/);
2898:                            //                    webForm.getDomDocument().moveComponentTo(box, box.getAbsoluteX(), y);
2899:                            moveComponentTo(box, box.getAbsoluteX(), y);
2900:
2901:                            break;
2902:
2903:                        case MIDDLE:
2904:                            //                    moveTo(editor, /*bean,*/ box, box.getAbsoluteX(),
2905:                            //                        (y + (h / 2)) - (box.getHeight() / 2)/*, true*/);
2906:                            //                    webForm.getDomDocument().moveComponentTo(box, box.getAbsoluteX(), (y + (h / 2)) - (box.getHeight() / 2));
2907:                            moveComponentTo(box, box.getAbsoluteX(),
2908:                                    (y + (h / 2)) - (box.getHeight() / 2));
2909:
2910:                            break;
2911:
2912:                        case BOTTOM:
2913:                            //                    moveTo(editor, /*bean,*/ box, box.getAbsoluteX(),
2914:                            //                        (y + h) - box.getHeight()/*, true*/);
2915:                            //                    webForm.getDomDocument().moveComponentTo(box, box.getAbsoluteX(), (y + h) - box.getHeight());
2916:                            moveComponentTo(box, box.getAbsoluteX(), (y + h)
2917:                                    - box.getHeight());
2918:
2919:                            break;
2920:
2921:                        case LEFT:
2922:                            //                    moveTo(editor, /*bean,*/ box, x, box.getAbsoluteY()/*, true*/);
2923:                            //                    webForm.getDomDocument().moveComponentTo(box, x, box.getAbsoluteY());
2924:                            moveComponentTo(box, x, box.getAbsoluteY());
2925:
2926:                            break;
2927:
2928:                        case CENTER:
2929:                            //                    moveTo(editor, /*bean,*/ box, (x + (w / 2)) - (box.getWidth() / 2),
2930:                            //                        box.getAbsoluteY()/*, true*/);
2931:                            //                    webForm.getDomDocument().moveComponentTo(box, (x + (w / 2)) - (box.getWidth() / 2), box.getAbsoluteY());
2932:                            moveComponentTo(box, (x + (w / 2))
2933:                                    - (box.getWidth() / 2), box.getAbsoluteY());
2934:
2935:                            break;
2936:
2937:                        case RIGHT:
2938:                            //                    moveTo(editor, /*bean,*/ box, (x + w) - box.getWidth(), box.getAbsoluteY()/*, true*/);
2939:                            //                    webForm.getDomDocument().moveComponentTo(box, (x + w) - box.getWidth(), box.getAbsoluteY());
2940:                            moveComponentTo(box, (x + w) - box.getWidth(), box
2941:                                    .getAbsoluteY());
2942:
2943:                            break;
2944:                        }
2945:                    }
2946:                } finally {
2947:                    //            doc.writeUnlock();
2948:                    //            webform.getModel().writeUnlock(undoEvent);
2949:                    //            webForm.writeUnlock(writeLock);
2950:                    jsfForm.writeUnlock(writeLock);
2951:                }
2952:
2953:                //        if (!haveMoved) {
2954:                //            StatusDisplayer.getDefault().setStatusText(NbBundle.getMessage(GridHandler.class,"MSG_AlignAbsolute"));
2955:                //            UIManager.getLookAndFeel().provideErrorFeedback(webForm.getPane());
2956:                //        }
2957:
2958:                //        fireComponentsMoved(new DefaultDomDocumentEvent(this, null));
2959:            }
2960:
2961:            // XXX Moved from designer/../DesignerCaret
2962:            /**
2963:             * @todo Check deletion back to first char in <body> !
2964:             * @todo Check read-only state etc
2965:             */
2966:            public boolean deleteNextChar(Designer designer, DomRange range) {
2967:                if (range == null) {
2968:                    return false;
2969:                }
2970:
2971:                //            UndoEvent undoEvent = webform.getModel().writeLock(NbBundle.getMessage(DeleteNextCharAction.class, "DeleteText")); // NOI18N
2972:                //        DomProvider.WriteLock writeLock = jsfForm.writeLock(NbBundle.getMessage(DomDocumentImpl.class, "LBL_DeleteText")); // NOI18N
2973:                UndoEvent writeLock = jsfForm.writeLock(NbBundle.getMessage(
2974:                        DomDocumentImpl.class, "LBL_DeleteText")); // NOI18N
2975:                try {
2976:                    // TODO - compute previous visual position, decide if it's
2977:                    //    isWithinEditableRegion(Position pos) 
2978:                    // and if so, set the range to it and delete the range.
2979:                    //        if (hasSelection()) {
2980:                    //            removeSelection();
2981:                    if (!range.isEmpty()) {
2982:                        deleteRangeContents(range);
2983:                        return true;
2984:                    }
2985:
2986:                    //        Document doc = component.getDocument();
2987:                    //        Position mark = range.getMark();
2988:                    DomPosition mark = range.getMark();
2989:                    //        Position dot = ModelViewMapper.computeArrowRight(doc.getWebForm(), mark);
2990:                    //        Position dot = ModelViewMapper.computeArrowRight(component.getWebForm(), mark);
2991:                    //        DomPosition dot = ModelViewMapper.computeArrowRight(component.getWebForm(), mark);
2992:                    DomPosition dot = designer.computeNextPosition(mark);
2993:
2994:                    //        if ((dot == Position.NONE) || !isWithinEditableRegion(dot)) {
2995:                    //        if ((dot == DomPosition.NONE) || !isWithinEditableRegion(dot)) {
2996:                    if ((dot == DomPosition.NONE)
2997:                            || !designer.isInsideEditableRegion(dot)) {
2998:                        //            UIManager.getLookAndFeel().provideErrorFeedback(component); // beep
2999:
3000:                        return false;
3001:                    }
3002:
3003:                    range.setRange(mark.getNode(), mark.getOffset(), dot
3004:                            .getNode(), dot.getOffset());
3005:                    //        range.deleteContents();
3006:                    //        removeSelection();
3007:                    deleteRangeContents(range);
3008:
3009:                    return true;
3010:                } finally {
3011:                    //                doc.writeUnlock();
3012:                    jsfForm.writeUnlock(writeLock);
3013:                }
3014:            }
3015:
3016:            // XXX Moved from designer/../DesignerCaret.
3017:            /**
3018:             * @todo Check deletion back to first char in <body> !
3019:             * @todo Check read-only state etc
3020:             */
3021:            public boolean deletePreviousChar(Designer designer, DomRange range) {
3022:                if (range == null) {
3023:                    return false;
3024:                }
3025:
3026:                //            UndoEvent undoEvent = webform.getModel().writeLock(NbBundle.getMessage(DeleteNextCharAction.class, "DeleteText")); // NOI18N
3027:                //        DomProvider.WriteLock writeLock = jsfForm.writeLock(NbBundle.getMessage(DomDocumentImpl.class, "LBL_DeleteText")); // NOI18N
3028:                UndoEvent writeLock = jsfForm.writeLock(NbBundle.getMessage(
3029:                        DomDocumentImpl.class, "LBL_DeleteText")); // NOI18N
3030:                try {
3031:                    // TODO - compute previous visual position, decide if it's
3032:                    //    isWithinEditableRegion(Position pos) 
3033:                    // and if so, set the range to it and delete the range.
3034:                    //        if (hasSelection()) {
3035:                    //            removeSelection();
3036:                    if (!range.isEmpty()) {
3037:                        deleteRangeContents(range);
3038:
3039:                        return true;
3040:                    }
3041:
3042:                    //        Document doc = component.getDocument();
3043:                    //        Position mark = range.getMark();
3044:                    DomPosition mark = range.getMark();
3045:                    //        Position dot = ModelViewMapper.computeArrowLeft(doc.getWebForm(), mark);
3046:                    //        Position dot = ModelViewMapper.computeArrowLeft(component.getWebForm(), mark);
3047:                    //        DomPosition dot = ModelViewMapper.computeArrowLeft(component.getWebForm(), mark);
3048:                    DomPosition dot = designer.computePreviousPosition(mark);
3049:
3050:                    //        if ((dot == Position.NONE) || !isWithinEditableRegion(dot)) {
3051:                    //        if ((dot == DomPosition.NONE) || !isWithinEditableRegion(dot)) {
3052:                    if ((dot == DomPosition.NONE)
3053:                            || !designer.isInsideEditableRegion(dot)) {
3054:                        //            UIManager.getLookAndFeel().provideErrorFeedback(component); // beep
3055:
3056:                        return false;
3057:                    }
3058:
3059:                    range.setRange(dot.getNode(), dot.getOffset(), mark
3060:                            .getNode(), mark.getOffset());
3061:
3062:                    // XXX DEBUGGING ONLY
3063:                    /*
3064:                    Element element = doc.getBody();
3065:                    if (element != null) {
3066:                        System.out.println("BEFORE DELETION: " + org.netbeans.modules.visualweb.css2.FacesSupport.getHtmlStream(element));
3067:                    }
3068:                     */
3069:                    //        range.deleteContents();
3070:                    //        removeSelection();
3071:                    deleteRangeContents(range);
3072:
3073:                    // XXX DEBUGGING ONLY
3074:
3075:                    /*
3076:                    if (element != null) {
3077:                        System.out.println("BEFORE DELETION: " + org.netbeans.modules.visualweb.css2.FacesSupport.getHtmlStream(element));
3078:                    }
3079:                     */
3080:                    return true;
3081:                } finally {
3082:                    //                doc.writeUnlock();
3083:                    //                webform.getModel().writeUnlock(undoEvent);
3084:                    jsfForm.writeUnlock(writeLock);
3085:                }
3086:
3087:            }
3088:
3089:            public void deleteComponents(Element[] componentRootElements) {
3090:                //        UndoEvent undoEvent = webform.getModel().writeLock(NbBundle.getMessage(SelectionTopComp.class, "DeleteSelection")); // NOI18N
3091:                //        DomProvider.WriteLock writeLock = jsfForm.writeLock(NbBundle.getMessage(DomDocumentImpl.class, "LBL_DeleteComponents")); // NOI18N
3092:                UndoEvent writeLock = jsfForm.writeLock(NbBundle.getMessage(
3093:                        DomDocumentImpl.class, "LBL_DeleteComponents")); // NOI18N
3094:                try {
3095:                    for (Element componentRootElement : componentRootElements) {
3096:                        if (JsfSupportUtilities
3097:                                .isSpecialComponent(componentRootElement)) {
3098:                            continue;
3099:                        }
3100:
3101:                        DesignBean designBean = MarkupUnit
3102:                                .getMarkupDesignBeanForElement(componentRootElement);
3103:                        if (designBean == null) {
3104:                            return;
3105:                        }
3106:                        jsfForm.deleteDesignBean(designBean);
3107:                    }
3108:                } finally {
3109:                    //            doc.writeUnlock();
3110:                    //            webform.getModel().writeUnlock(undoEvent);
3111:                    jsfForm.writeUnlock(writeLock);
3112:
3113:                }
3114:            }
3115:
3116:            // XXX
3117:            boolean isRenderedNode(Node node) {
3118:                return jsfForm.isRenderedNode(node);
3119:            }
3120:
3121:            JsfForm getJsfForm() {
3122:                return jsfForm;
3123:            }
3124:        }
w___w___w.___j_a___v__a___2s__._c_o__m | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.