home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 139 / dpcs0999.iso / Web / CFserver / data1.cab / Java / CFJava.cab / CFJavaRuntime.cab / netscape / application / TextView.class (.txt) < prev    next >
Encoding:
Java Class File  |  1998-10-01  |  56.1 KB  |  3,419 lines

  1. package netscape.application;
  2.  
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import java.net.MalformedURLException;
  6. import java.net.URL;
  7. import netscape.util.ClassInfo;
  8. import netscape.util.Codable;
  9. import netscape.util.CodingException;
  10. import netscape.util.Decoder;
  11. import netscape.util.Encoder;
  12. import netscape.util.Enumeration;
  13. import netscape.util.Hashtable;
  14. import netscape.util.InconsistencyException;
  15. import netscape.util.Vector;
  16.  
  17. public class TextView extends View implements ExtendedTarget, EventFilter, DragDestination, FormElement {
  18.    public static final String TEXT_ATTACHMENT_STRING = "@";
  19.    public static final String PARAGRAPH_FORMAT_KEY = "ParagraphFormatKey";
  20.    public static final String FONT_KEY = "FontKey";
  21.    public static final String TEXT_COLOR_KEY = "TextColorKey";
  22.    public static final String TEXT_ATTACHMENT_KEY = "TextAttachmentKey";
  23.    public static final String TEXT_ATTACHMENT_BASELINE_OFFSET_KEY = "TextAttachmentBaselineOffsetKey";
  24.    public static final String CARET_COLOR_KEY = "CaretColorKey";
  25.    public static final String LINK_KEY = "LinkKey";
  26.    public static final String LINK_DESTINATION_KEY = "LinkDestinationKey";
  27.    public static final String LINK_COLOR_KEY = "LinkColorKey";
  28.    public static final String PRESSED_LINK_COLOR_KEY = "PressedLinkColorKey";
  29.    static final String LINK_IS_PRESSED_KEY = "_IFCLinkPressedKey";
  30.    static Vector attributesChangingFormatting = new Vector();
  31.    Vector _paragraphVector;
  32.    Color _backgroundColor;
  33.    Color _selectionColor;
  34.    TextParagraph _updateParagraph;
  35.    TextPositionInfo _anchorInfo;
  36.    TextPositionInfo _upInfo;
  37.    TextSelection _selection;
  38.    TextFilter _filter;
  39.    TextViewOwner _owner;
  40.    Hashtable _defaultAttributes;
  41.    Hashtable _typingAttributes;
  42.    Timer _updateTimer;
  43.    Vector _eventVector;
  44.    int _charCount;
  45.    int _paragraphSpacing;
  46.    int _updateLine;
  47.    int _downY;
  48.    int _clickCount;
  49.    int _resizeDisabled;
  50.    int _formattingDisabled;
  51.    boolean _drawText;
  52.    boolean _editing;
  53.    boolean _useSingleFont;
  54.    boolean _editable;
  55.    boolean _selectable;
  56.    boolean _drawNextParagraph;
  57.    boolean _resizing;
  58.    boolean insertionPointVisible;
  59.    boolean transparent;
  60.    boolean selectLineBreak;
  61.    private Range _selectedRange;
  62.    private Range _wasSelectedRange;
  63.    private TextAttachment _mouseDownTextAttachment;
  64.    private Point _mouseDownTextAttachmentOrigin;
  65.    private FontMetrics _defaultFontMetricsCache;
  66.    private URL _baseURL;
  67.    private Range _clickedRange;
  68.    private Range _firstRange;
  69.    private HTMLParsingRules _htmlParsingRules;
  70.    private int notifyAttachmentDisabled;
  71.    private Range invalidAttachmentRange;
  72.    private static Vector _rectCache;
  73.    private static Vector _vectorCache;
  74.    private static boolean _shouldCache;
  75.    private static boolean _cacheVectors;
  76.    static ObjectPool hashtablePool;
  77.    static ObjectPool rangePool;
  78.    static final String PARAGRAPHVECTOR_KEY = "paragraphVector";
  79.    static final String BACKGROUNDCOLOR_KEY = "backgroundColor";
  80.    static final String SELECTIONCOLOR_KEY = "selectionColor";
  81.    static final String FILTER_KEY = "filter";
  82.    static final String DEFAULTATTRIBUTES_KEY = "defaultAttributes";
  83.    static final String PARASPACING_KEY = "paragraphSpacing";
  84.    static final String USESINGLEFONT_KEY = "useSingleFont";
  85.    static final String EDITABLE_KEY = "editable";
  86.    static final String SELECTABLE_KEY = "selectable";
  87.    static final String TRANSPARENT_KEY = "transparent";
  88.    static final String HTML_PARSING_RULES_KEY = "htmlParsingRules";
  89.    static final String OWNER_KEY = "owner";
  90.  
  91.    public TextView() {
  92.       this(0, 0, 0, 0);
  93.    }
  94.  
  95.    public TextView(Rect var1) {
  96.       this(var1.x, var1.y, var1.width, var1.height);
  97.    }
  98.  
  99.    public TextView(int var1, int var2, int var3, int var4) {
  100.       super(var1, var2, var3, var4);
  101.       this._drawText = true;
  102.       this._useSingleFont = false;
  103.       this._editable = true;
  104.       this._selectable = true;
  105.       this._resizing = false;
  106.       this.insertionPointVisible = false;
  107.       this.transparent = false;
  108.       this._eventVector = new Vector();
  109.       this._selection = new TextSelection(this);
  110.       this._paragraphVector = new Vector();
  111.       this._paragraphSpacing = 0;
  112.       this._backgroundColor = Color.white;
  113.       this._selectionColor = Color.lightGray;
  114.       this._defaultAttributes = new Hashtable();
  115.       this._defaultAttributes.put("FontKey", Font.defaultFont());
  116.       this._defaultAttributes.put("TextColorKey", Color.black);
  117.       this._defaultAttributes.put("LinkColorKey", Color.blue);
  118.       this._defaultAttributes.put("CaretColorKey", Color.black);
  119.       this._defaultAttributes.put("PressedLinkColorKey", Color.red);
  120.       TextParagraphFormat var6 = new TextParagraphFormat();
  121.       var6.setLeftMargin(3);
  122.       var6.setRightMargin(3);
  123.       var6.setJustification(0);
  124.       int var8 = 30;
  125.  
  126.       for(int var7 = 0; var7 < 20; ++var7) {
  127.          var6.addTabPosition(var8);
  128.          var8 += 30;
  129.       }
  130.  
  131.       this._defaultAttributes.put("ParagraphFormatKey", var6);
  132.       this._wasSelectedRange = new Range(this.selectedRange());
  133.       TextParagraph var5 = new TextParagraph(this);
  134.       var5.addRun(new TextStyleRun(var5, "", (Hashtable)null));
  135.       this.addParagraph(var5);
  136.       this.reformatAll();
  137.       this._typingAttributes = new Hashtable();
  138.    }
  139.  
  140.    public void didMoveBy(int var1, int var2) {
  141.       if (var1 == 0 && var2 == 0 && this._updateTimer != null) {
  142.          this._updateTimer.stop();
  143.          this._updateTimer = null;
  144.          this._updateParagraph = null;
  145.       }
  146.  
  147.       super.didMoveBy(var1, var2);
  148.    }
  149.  
  150.    public void sizeBy(int var1, int var2) {
  151.       if (this.isResizingEnabled()) {
  152.          int var3 = super.bounds.width;
  153.          this._resizing = true;
  154.          super.sizeBy(var1, var2);
  155.          this._resizing = false;
  156.          if (super.bounds.width != var3 + var1) {
  157.             this.disableResizing();
  158.             this.reformatAll();
  159.             this.enableResizing();
  160.             ((View)this).setDirty(true);
  161.          } else {
  162.             if (var1 != 0 || var2 != 0) {
  163.                ((View)this).setDirty(true);
  164.             }
  165.  
  166.          }
  167.       }
  168.    }
  169.  
  170.    public void didSizeBy(int var1, int var2) {
  171.       if (!this._resizing) {
  172.          this.reformatAll();
  173.       }
  174.  
  175.       super.didSizeBy(var1, var2);
  176.    }
  177.  
  178.    public void setTransparent(boolean var1) {
  179.       this.transparent = var1;
  180.    }
  181.  
  182.    public boolean isTransparent() {
  183.       return this.transparent;
  184.    }
  185.  
  186.    public boolean wantsAutoscrollEvents() {
  187.       return true;
  188.    }
  189.  
  190.    public void drawView(Graphics var1) {
  191.       if (!this._drawText) {
  192.          if (this._updateParagraph != null) {
  193.             this._updateParagraph.drawLine(var1, this._updateLine);
  194.          }
  195.       } else {
  196.          int var6 = this._paragraphVector.count();
  197.          int var4 = var1.clipRect().y;
  198.          int var5 = var1.clipRect().maxY();
  199.          Rect var3 = Rect.newRect(0, 0, ((View)this).width(), ((View)this).height());
  200.  
  201.          for(int var7 = 0; var7 < var6; ++var7) {
  202.             TextParagraph var2 = (TextParagraph)this._paragraphVector.elementAt(var7);
  203.             if (var2._y <= var5 && var2._y + var2._height >= var4) {
  204.                var2.drawView(var1, var3);
  205.             }
  206.          }
  207.  
  208.          Rect.returnRect(var3);
  209.       }
  210.  
  211.       if (this._selection._insertionPointShowing) {
  212.          Rect var11 = this._selection.insertionPointRect();
  213.          Color var12 = null;
  214.          if (var1.clipRect().intersects(var11)) {
  215.             TextPositionInfo var10 = this._selection.insertionPointInfo();
  216.             TextStyleRun var9 = this._runForIndex(var10._absPosition);
  217.             Hashtable var8;
  218.             if ((var8 = var9.attributes()) != null) {
  219.                var12 = (Color)var8.get("CaretColorKey");
  220.             }
  221.  
  222.             if (var12 == null) {
  223.                var12 = (Color)this._defaultAttributes.get("CaretColorKey");
  224.             }
  225.  
  226.             if (var12 == null) {
  227.                var12 = Color.black;
  228.             }
  229.  
  230.             var1.setColor(var12);
  231.             var1.fillRect(var11);
  232.          }
  233.       }
  234.  
  235.    }
  236.  
  237.    public Object filterEvents(Vector var1) {
  238.       for(int var2 = 0; var2 < var1.count(); ++var2) {
  239.          Event var3 = (Event)var1.elementAt(var2);
  240.          if (var3 instanceof KeyEvent && var3.type() == -11) {
  241.             if (this._filter != null) {
  242.                if (this._filter.acceptsEvent(this, (KeyEvent)var3, this._eventVector)) {
  243.                   this._eventVector.addElement(var3);
  244.                }
  245.             } else {
  246.                this._eventVector.addElement(var3);
  247.             }
  248.  
  249.             var1.removeElementAt(var2);
  250.             --var2;
  251.          }
  252.       }
  253.  
  254.       return null;
  255.    }
  256.  
  257.    public boolean mouseDown(MouseEvent var1) {
  258.       this._mouseDownTextAttachment = null;
  259.       this._clickedRange = null;
  260.       if (this.isEditable() || this.isSelectable()) {
  261.          ((View)this).setFocusedView();
  262.       }
  263.  
  264.       if (!((View)this).rootView().mouseStillDown()) {
  265.          return true;
  266.       } else {
  267.          this._selection.hideInsertionPoint();
  268.          this._clickCount = var1.clickCount();
  269.          this._anchorInfo = this.positionForPoint(var1.x, var1.y, false);
  270.          TextPositionInfo var2 = this.positionForPoint(var1.x, var1.y, true);
  271.          if (this._anchorInfo != null && this._anchorInfo._endOfLine) {
  272.             Rect var3 = new Rect(this._anchorInfo._x, this._anchorInfo._y, super.bounds.width, this._anchorInfo._lineHeight);
  273.             if (!var3.contains(var1.x, var1.y)) {
  274.                this.selectLineBreak = false;
  275.             } else {
  276.                this.selectLineBreak = true;
  277.             }
  278.          } else {
  279.             this.selectLineBreak = false;
  280.          }
  281.  
  282.          if (var2 != null) {
  283.             TextStyleRun var8 = this._runForIndex(var2._absPosition);
  284.             if (var8 != null) {
  285.                Hashtable var4 = var8.attributes();
  286.                if (var4 != null) {
  287.                   TextAttachment var5;
  288.                   if ((var5 = (TextAttachment)var4.get("TextAttachmentKey")) != null && var8.rangeIndex() == var2._absPosition) {
  289.                      Rect var7 = var8.textAttachmentBoundsForOrigin(var2._x, var2._y, var8._paragraph._baselines[var2._lineNumber]);
  290.                      if (var7 != null && var7.contains(var1.x, var1.y)) {
  291.                         boolean var6 = var5.mouseDown(new MouseEvent(var1.timeStamp, var1.type, var1.x - var7.x, var1.y - var7.y, var1.modifiers));
  292.                         if (var6) {
  293.                            this._mouseDownTextAttachment = var5;
  294.                            this._mouseDownTextAttachmentOrigin = new Point(var7.x, var7.y);
  295.                            return true;
  296.                         }
  297.                      }
  298.                   }
  299.  
  300.                   if (!this.isEditable() && var4.get("LinkKey") != null && this.runUnderMouse(var8, var1.x, var1.y) && this._clickCount == 1) {
  301.                      this._clickedRange = this.linkRangeForPosition(var2._absPosition);
  302.                      this.highlightLinkWithRange(this._clickedRange, true);
  303.                   }
  304.                }
  305.             }
  306.          }
  307.  
  308.          if (!this.isSelectable() && this._clickedRange == null) {
  309.             return false;
  310.          } else {
  311.             this._firstRange = null;
  312.             if (this._clickCount > 1) {
  313.                if (!this.selectLineBreak) {
  314.                   switch (this._clickCount) {
  315.                      case 2:
  316.                         this._firstRange = this.groupForIndex(this._anchorInfo._absPosition);
  317.                         break;
  318.                      default:
  319.                         this._firstRange = this.paragraphForIndex(this._anchorInfo._absPosition);
  320.                   }
  321.  
  322.                   if (this._firstRange != null && !this._firstRange.isNullRange()) {
  323.                      if (var1.isShiftKeyDown()) {
  324.                         Range var9 = new Range(this.selectedRange());
  325.                         var9.unionWith(this._firstRange.index, this._firstRange.length);
  326.                         this._selection.setRange(var9.index, var9.index + var9.length, (TextPositionInfo)null, false);
  327.                      } else {
  328.                         this._selection.setRange(this._firstRange.index, this._firstRange.lastIndex() + 1, (TextPositionInfo)null, false);
  329.                      }
  330.  
  331.                      this._selectionChanged();
  332.                   }
  333.  
  334.                   return true;
  335.                }
  336.  
  337.                this._firstRange = new Range(this._anchorInfo._absPosition, 0);
  338.             }
  339.  
  340.             if (var1.isShiftKeyDown()) {
  341.                this._selection.setRange(this._selection.orderedSelectionStart(), this._anchorInfo._absPosition, (TextPositionInfo)null, false);
  342.             } else {
  343.                this._selection.setInsertionPoint(this._anchorInfo);
  344.             }
  345.  
  346.             this._selectionChanged();
  347.             this._upInfo = null;
  348.             this._downY = this._anchorInfo._y + this._anchorInfo._lineHeight;
  349.             return true;
  350.          }
  351.       }
  352.    }
  353.  
  354.    public void mouseDragged(MouseEvent var1) {
  355.       if (this._mouseDownTextAttachment != null) {
  356.          this._mouseDownTextAttachment.mouseDragged(new MouseEvent(var1.timeStamp, var1.type, var1.x - this._mouseDownTextAttachmentOrigin.x, var1.y - this._mouseDownTextAttachmentOrigin.y, var1.modifiers));
  357.       } else {
  358.          Point var5 = new Point(var1.x, var1.y);
  359.          if (var5.x >= super.bounds.width) {
  360.             var5.x = super.bounds.width - 1;
  361.          } else if (var5.x < 0) {
  362.             var5.x = 0;
  363.          }
  364.  
  365.          if (var5.y >= super.bounds.height) {
  366.             var5.y = super.bounds.height - 1;
  367.          } else if (var5.y < 0) {
  368.             var5.y = 0;
  369.          }
  370.  
  371.          TextPositionInfo var2 = this.positionForPoint(var5.x, var5.y, false);
  372.          if (this._clickedRange != null) {
  373.             TextStyleRun var7 = this._runForIndex(var2._absPosition);
  374.             Hashtable var8;
  375.             if ((var8 = var7.attributes()) != null && var8.get("LinkKey") != null && this.runUnderMouse(var7, var1.x, var1.y)) {
  376.                Range var9 = this.linkRangeForPosition(var2._absPosition);
  377.                if (!var9.equals(this._clickedRange)) {
  378.                   this.highlightLinkWithRange(this._clickedRange, false);
  379.                   this._clickedRange = var9;
  380.                   this.highlightLinkWithRange(this._clickedRange, true);
  381.                }
  382.  
  383.                return;
  384.             }
  385.  
  386.             this.highlightLinkWithRange(this._clickedRange, false);
  387.             this._clickedRange = null;
  388.          }
  389.  
  390.          if (this.isSelectable()) {
  391.             if (var2 != null) {
  392.                if (!((View)this).containsPointInVisibleRect(var1.x, var1.y)) {
  393.                   Rect var3 = newRect(var2._x, var2._y, 1, var2._lineHeight);
  394.                   ((View)this).scrollRectToVisible(var3);
  395.                   returnRect(var3);
  396.                }
  397.  
  398.                int var4 = this._anchorInfo._absPosition;
  399.                boolean var6;
  400.                if (this._upInfo != null && var2._absPosition != this._upInfo._absPosition) {
  401.                   var6 = true;
  402.                } else {
  403.                   var6 = false;
  404.                }
  405.  
  406.                this._upInfo = var2;
  407.                if (var6) {
  408.                   Range var10;
  409.                   switch (this._clickCount) {
  410.                      case 0:
  411.                      case 1:
  412.                         this._selection.setRange(var4, this._upInfo._absPosition, this._upInfo, this.selectLineBreak);
  413.                         this._selectionChanged();
  414.                         return;
  415.                      case 2:
  416.                         var10 = this.groupForIndex(this._upInfo._absPosition);
  417.                         break;
  418.                      default:
  419.                         var10 = this.paragraphForIndex(this._upInfo._absPosition);
  420.                   }
  421.  
  422.                   if (this._firstRange != null && !this._firstRange.isNullRange() && !var10.isNullRange()) {
  423.                      var10.unionWith(this._firstRange);
  424.                      if (!var10.equals(this.selectedRange())) {
  425.                         this._selection.setRange(var10.index, var10.lastIndex() + 1, (TextPositionInfo)null, this.selectLineBreak);
  426.                         this._selectionChanged();
  427.                      }
  428.                   }
  429.                }
  430.  
  431.             }
  432.          }
  433.       }
  434.    }
  435.  
  436.    public void mouseUp(MouseEvent var1) {
  437.       if (this._mouseDownTextAttachment != null) {
  438.          this._mouseDownTextAttachment.mouseUp(new MouseEvent(var1.timeStamp, var1.type, var1.x - this._mouseDownTextAttachmentOrigin.x, var1.y - this._mouseDownTextAttachmentOrigin.y, var1.modifiers));
  439.          this._mouseDownTextAttachment = null;
  440.          this._mouseDownTextAttachmentOrigin = null;
  441.       } else {
  442.          if (this._clickedRange != null) {
  443.             TextPositionInfo var2 = this.positionForPoint(var1.x, var1.y, true);
  444.             Range var3 = this.linkRangeForPosition(var2._absPosition);
  445.             this.highlightLinkWithRange(this._clickedRange, false);
  446.             if (var3 != null && var3.equals(this._clickedRange) && this._owner != null) {
  447.                TextStyleRun var4 = this._runForIndex(this._clickedRange.index);
  448.                Hashtable var5 = var4.attributes();
  449.                Object var6 = null;
  450.                String var7;
  451.                if (var5 != null && (var7 = (String)var5.get("LinkKey")) != null && this.runsUnderMouse(this.runsForRange(this._clickedRange), var1.x, var1.y)) {
  452.                   this._owner.linkWasSelected(this, this._clickedRange, var7);
  453.                }
  454.             }
  455.  
  456.             this._clickedRange = null;
  457.          }
  458.  
  459.          if (this.isSelectable()) {
  460.             if (this._upInfo == null || this._upInfo._absPosition == this._anchorInfo._absPosition) {
  461.                this._selection.showInsertionPoint();
  462.             }
  463.  
  464.             this._firstRange = null;
  465.          }
  466.       }
  467.    }
  468.  
  469.    public int cursorForPoint(int var1, int var2) {
  470.       if (this.isEditable()) {
  471.          return 2;
  472.       } else {
  473.          TextPositionInfo var3 = this.positionForPoint(var1, var2, true);
  474.          if (var3 != null) {
  475.             TextStyleRun var4 = this._runForIndex(var3._absPosition);
  476.             if (var4 != null) {
  477.                Hashtable var5 = var4.attributes();
  478.                if (var5 != null && var5.get("LinkKey") != null && this.runUnderMouse(var4, var1, var2)) {
  479.                   return 12;
  480.                }
  481.             }
  482.          }
  483.  
  484.          return this.isSelectable() ? 2 : 0;
  485.       }
  486.    }
  487.  
  488.    public void performCommand(String var1, Object var2) {
  489.       if (var1.equals("refreshBitmap")) {
  490.          this.refreshBitmap(var2);
  491.       } else {
  492.          if (var1 != null && var1.equals("setFont")) {
  493.             this.processSetFont((Font)var2);
  494.             return;
  495.          }
  496.  
  497.          if (var1.equals("cut")) {
  498.             this.cut();
  499.          } else if (var1.equals("copy")) {
  500.             this.copy();
  501.          } else if (var1.equals("paste")) {
  502.             this.paste();
  503.          } else if (!(var2 instanceof Timer)) {
  504.             return;
  505.          }
  506.       }
  507.  
  508.       if (this._updateParagraph == null) {
  509.          if (this._updateTimer != null) {
  510.             this._updateTimer.stop();
  511.             this._updateTimer = null;
  512.          }
  513.  
  514.       } else {
  515.          this._drawText = false;
  516.          Rect var3 = this._updateParagraph.rectForLine(this._updateLine);
  517.          ((View)this).draw(var3);
  518.          returnRect(var3);
  519.          this._drawText = true;
  520.          ++this._updateLine;
  521.          if (this._updateLine >= this._updateParagraph._breakCount) {
  522.             if (!this._drawNextParagraph) {
  523.                this._updateParagraph = null;
  524.             } else {
  525.                int var4 = this._paragraphVector.indexOfIdentical(this._updateParagraph) + 1;
  526.                if (var4 != 0 && var4 < this._paragraphVector.count()) {
  527.                   this._updateParagraph = (TextParagraph)this._paragraphVector.elementAt(var4);
  528.                   this._updateLine = 0;
  529.                } else {
  530.                   this._updateParagraph = null;
  531.                }
  532.             }
  533.          }
  534.  
  535.          if (this._updateParagraph == null && this._updateTimer != null) {
  536.             this._updateTimer.stop();
  537.             this._updateTimer = null;
  538.          }
  539.  
  540.       }
  541.    }
  542.  
  543.    public boolean canPerformCommand(String var1) {
  544.       if (var1.equals("setFont")) {
  545.          return !this.usesSingleFont() && this.isEditable();
  546.       } else {
  547.          return var1.equals("refreshBitmap") || var1.equals("copy") || this.isEditable() && var1.equals("cut") || this.isEditable() && var1.equals("paste");
  548.       }
  549.    }
  550.  
  551.    public void keyDown(KeyEvent var1) {
  552.       if (var1.isPageUpKey()) {
  553.          Rect var5 = new Rect();
  554.          ((View)this).computeVisibleRect(var5);
  555.          var5.y -= var5.height - 1;
  556.          if (var5.y < 0) {
  557.             var5.y = 0;
  558.          }
  559.  
  560.          TextPositionInfo var6 = this.positionForPoint(var5.x, var5.y, true);
  561.          if (var6 != null) {
  562.             var5.y = var6._y;
  563.          }
  564.  
  565.          ((View)this).scrollRectToVisible(var5);
  566.       } else if (var1.isPageDownKey()) {
  567.          Rect var2 = new Rect();
  568.          ((View)this).computeVisibleRect(var2);
  569.          TextPositionInfo var3 = this.positionForPoint(var2.x, var2.y, true);
  570.          var2.y += var2.height - 1;
  571.          if (var2.y > super.bounds.height - var2.height) {
  572.             var2.y = super.bounds.height - var2.height;
  573.          }
  574.  
  575.          TextPositionInfo var4 = this.positionForPoint(var2.x, var2.y, true);
  576.          if (var4 != null) {
  577.             var2.y = var4._y;
  578.             if (var3 != null && var3._absPosition == var4._absPosition) {
  579.                var2.y += var4._lineHeight;
  580.             }
  581.          }
  582.  
  583.          ((View)this).scrollRectToVisible(var2);
  584.       } else if (this.isEditable()) {
  585.          if (this.hasSelection()) {
  586.             if (this._filter != null) {
  587.                if (this._filter.acceptsEvent(this, var1, this._eventVector)) {
  588.                   this._eventVector.addElement(var1);
  589.                }
  590.             } else {
  591.                this._eventVector.addElement(var1);
  592.             }
  593.  
  594.             ((View)this).application().eventLoop().filterEvents(this);
  595.  
  596.             while(!this._eventVector.isEmpty()) {
  597.                this._keyDown();
  598.             }
  599.  
  600.          }
  601.       }
  602.    }
  603.  
  604.    public DragDestination acceptsDrag(DragSession var1, int var2, int var3) {
  605.       String var4 = var1.dataType();
  606.       return !this.isEditable() || !this.hasSelection() || !"netscape.application.Color".equals(var4) && !"netscape.application.Image".equals(var4) ? null : this;
  607.    }
  608.  
  609.    public boolean dragEntered(DragSession var1) {
  610.       return true;
  611.    }
  612.  
  613.    public boolean dragMoved(DragSession var1) {
  614.       return true;
  615.    }
  616.  
  617.    public void dragExited(DragSession var1) {
  618.    }
  619.  
  620.    public boolean dragDropped(DragSession var1) {
  621.       if (this.isEditable() && this.hasSelection()) {
  622.          Object var2 = var1.data();
  623.          if (var2 == null) {
  624.             return false;
  625.          } else if (var2 instanceof Color) {
  626.             Range var3 = this.selectedRange();
  627.             if (var3.length > 0) {
  628.                this.addAttributeForRange("TextColorKey", var2, var3);
  629.             } else {
  630.                this.addTypingAttribute("TextColorKey", var2);
  631.             }
  632.  
  633.             return true;
  634.          } else if (var2 instanceof Image) {
  635.             this.replaceRangeWithTextAttachment(this.selectedRange(), new ImageAttachment((Image)var2));
  636.             return true;
  637.          } else {
  638.             return false;
  639.          }
  640.       } else {
  641.          return false;
  642.       }
  643.    }
  644.  
  645.    public void startFocus() {
  646.       this._setEditing(true);
  647.       this.showInsertionPoint();
  648.       this._selection._startFlashing();
  649.       if (this.isEditable() && this._owner != null) {
  650.          this._owner.textEditingDidBegin(this);
  651.       }
  652.  
  653.       if (this.hasSelection()) {
  654.          Range var1 = this.selectedRange();
  655.          if (var1.length > 0) {
  656.             this.dirtyRange(var1);
  657.             return;
  658.          }
  659.       } else {
  660.          this.selectRange(new Range(0, 0));
  661.       }
  662.  
  663.    }
  664.  
  665.    public void stopFocus() {
  666.       this._selection._stopFlashing();
  667.       this.hideInsertionPoint();
  668.       this._setEditing(false);
  669.       if (this.isEditable() && this._owner != null) {
  670.          this._owner.textEditingDidEnd(this);
  671.       }
  672.  
  673.       if (this.hasSelection()) {
  674.          Range var1 = this.selectedRange();
  675.          if (var1.length > 0) {
  676.             this.dirtyRange(var1);
  677.          }
  678.       }
  679.  
  680.    }
  681.  
  682.    public void pauseFocus() {
  683.       this._selection._stopFlashing();
  684.       this.hideInsertionPoint();
  685.    }
  686.  
  687.    public void resumeFocus() {
  688.       this.showInsertionPoint();
  689.       this._selection._startFlashing();
  690.    }
  691.  
  692.    public String toString() {
  693.       StringBuffer var3 = new StringBuffer();
  694.       int var1 = 0;
  695.  
  696.       for(int var2 = this._paragraphVector.count(); var1 < var2; ++var1) {
  697.          var3.append(this._paragraphVector.elementAt(var1).toString());
  698.       }
  699.  
  700.       return var3.toString();
  701.    }
  702.  
  703.    public void setFilter(TextFilter var1) {
  704.       this._filter = var1;
  705.    }
  706.  
  707.    public TextFilter filter() {
  708.       return this._filter;
  709.    }
  710.  
  711.    public void setOwner(TextViewOwner var1) {
  712.       this._owner = var1;
  713.    }
  714.  
  715.    public TextViewOwner owner() {
  716.       return this._owner;
  717.    }
  718.  
  719.    public void disableResizing() {
  720.       ++this._resizeDisabled;
  721.    }
  722.  
  723.    public void enableResizing() {
  724.       --this._resizeDisabled;
  725.       if (this._resizeDisabled < 0) {
  726.          this._resizeDisabled = 0;
  727.       }
  728.  
  729.    }
  730.  
  731.    public boolean isResizingEnabled() {
  732.       return this._resizeDisabled == 0;
  733.    }
  734.  
  735.    public void sizeToMinSize() {
  736.       this.sizeBy(0, this.adjustCharCountsAndSpacing() - super.bounds.height);
  737.    }
  738.  
  739.    public void scrollRangeToVisible(Range var1) {
  740.       if (var1.index == 0 && var1.length == 0) {
  741.          ((View)this).scrollRectToVisible(new Rect(0, 0, 1, 1));
  742.       } else if (var1.index >= this.length()) {
  743.          ((View)this).scrollRectToVisible(new Rect(((View)this).width() - 1, ((View)this).height() - 1, 1, 1));
  744.       } else if (var1.length == 0) {
  745.          TextPositionInfo var6 = this.positionInfoForIndex(var1.index);
  746.          ((View)this).scrollRectToVisible(new Rect(var6._x, var6._y + var6._lineHeight, 1, var6._lineHeight));
  747.       } else {
  748.          TextPositionInfo var2 = this.positionInfoForIndex(var1.index);
  749.          TextPositionInfo var3 = this.positionInfoForIndex(var1.index + var1.length);
  750.          int var4 = var2._y;
  751.          int var5 = var3._y + var3._lineHeight;
  752.          if (var2._y == var3._y) {
  753.             ((View)this).scrollRectToVisible(new Rect(var2._x, var4, var3._x - var2._x, var5 - var4));
  754.          } else {
  755.             ((View)this).scrollRectToVisible(new Rect(0, var4, ((View)this).width(), var5 - var4));
  756.          }
  757.       }
  758.    }
  759.  
  760.    public void setUseSingleFont(boolean var1) {
  761.       this._useSingleFont = var1;
  762.    }
  763.  
  764.    public boolean usesSingleFont() {
  765.       return this._useSingleFont;
  766.    }
  767.  
  768.    public void setDefaultAttributes(Hashtable var1) {
  769.       this._defaultAttributes = var1;
  770.       if (var1.get("FontKey") != null) {
  771.          this._defaultFontMetricsCache = null;
  772.       }
  773.  
  774.       if (var1.get("ParagraphFormatKey") == null) {
  775.          TextParagraphFormat var3 = new TextParagraphFormat();
  776.          var3.setLeftMargin(3);
  777.          var3.setRightMargin(3);
  778.          var3.setJustification(0);
  779.          this._defaultAttributes.put("ParagraphFormatKey", var3);
  780.       }
  781.  
  782.       this.reformatAll();
  783.       Range var2 = allocateRange(0, this.length());
  784.       this.dirtyRange(var2);
  785.       recycleRange(var2);
  786.    }
  787.  
  788.    public Hashtable defaultAttributes() {
  789.       return this._defaultAttributes;
  790.    }
  791.  
  792.    public void addTypingAttribute(String var1, Object var2) {
  793.       Hashtable var3 = new Hashtable();
  794.       var3.put(var1, var2);
  795.       var3 = attributesByRemovingStaticAttributes(var3);
  796.       Enumeration var4 = var3.keys();
  797.  
  798.       while(var4.hasMoreElements()) {
  799.          String var5 = (String)var4.nextElement();
  800.          this._typingAttributes.put(var5, var3.get(var5));
  801.       }
  802.  
  803.    }
  804.  
  805.    public Hashtable typingAttributes() {
  806.       return this._typingAttributes;
  807.    }
  808.  
  809.    public void setTypingAttributes(Hashtable var1) {
  810.       if (var1 == null) {
  811.          this._typingAttributes = new Hashtable();
  812.       } else {
  813.          this._typingAttributes = attributesByRemovingStaticAttributes(var1);
  814.       }
  815.    }
  816.  
  817.    public void setBackgroundColor(Color var1) {
  818.       if (var1 != null) {
  819.          this._backgroundColor = var1;
  820.       }
  821.  
  822.    }
  823.  
  824.    public Color backgroundColor() {
  825.       return this._backgroundColor;
  826.    }
  827.  
  828.    public void setSelectionColor(Color var1) {
  829.       if (var1 != null) {
  830.          this._selectionColor = var1;
  831.       }
  832.  
  833.    }
  834.  
  835.    public Color selectionColor() {
  836.       return this._selectionColor;
  837.    }
  838.  
  839.    public void setEditable(boolean var1) {
  840.       if (this._editable != var1) {
  841.          this._editable = var1;
  842.          this.setSelectable(true);
  843.       }
  844.  
  845.    }
  846.  
  847.    public boolean isEditable() {
  848.       return this._editable;
  849.    }
  850.  
  851.    public void setSelectable(boolean var1) {
  852.       if (this._selectable != var1) {
  853.          this._selectable = var1;
  854.          RootView var2 = ((View)this).rootView();
  855.          if (var2 != null) {
  856.             var2.updateCursor();
  857.          }
  858.       }
  859.  
  860.    }
  861.  
  862.    public boolean isSelectable() {
  863.       return this._selectable;
  864.    }
  865.  
  866.    public void setFont(Font var1) {
  867.       if (var1 != null) {
  868.          this.addDefaultAttribute("FontKey", var1);
  869.       }
  870.    }
  871.  
  872.    public Font font() {
  873.       return (Font)this._defaultAttributes.get("FontKey");
  874.    }
  875.  
  876.    public void setTextColor(Color var1) {
  877.       if (var1 != null) {
  878.          this.addDefaultAttribute("TextColorKey", var1);
  879.       }
  880.  
  881.    }
  882.  
  883.    public Color textColor() {
  884.       Color var1 = (Color)this._defaultAttributes.get("TextColorKey");
  885.       return var1 == null ? Color.black : var1;
  886.    }
  887.  
  888.    public void setCaretColor(Color var1) {
  889.       if (var1 != null) {
  890.          this.addDefaultAttribute("CaretColorKey", var1);
  891.       }
  892.  
  893.    }
  894.  
  895.    public Color caretColor() {
  896.       Color var1 = (Color)this._defaultAttributes.get("CaretColorKey");
  897.       return var1 == null ? Color.black : var1;
  898.    }
  899.  
  900.    public void replaceRangeWithString(Range var1, String var2) {
  901.       boolean var8 = true;
  902.       if (this._owner != null) {
  903.          this._owner.textWillChange(this, var1);
  904.       }
  905.  
  906.       if (var1.equals(new Range(0, this.length()))) {
  907.          this.replaceContentWithString(var2);
  908.          if (this._owner != null) {
  909.             this._owner.textDidChange(this, new Range(0, this.length()));
  910.          }
  911.  
  912.       } else {
  913.          this.disableResizing();
  914.          int var9 = this._paragraphIndexForIndex(var1.index);
  915.          this.deleteRange(var1, (Vector)null);
  916.          if (var2 != null && !var2.equals("")) {
  917.             this.disableAttachmentNotification();
  918.             int var4 = var1.index;
  919.             int var5 = 0;
  920.             int var6 = var2.indexOf(10);
  921.             if (var6 == -1) {
  922.                this.insertString(var2, var4);
  923.                this.enableResizing();
  924.                if (var9 > 0) {
  925.                   this.sizeBy(0, this.adjustCharCountsAndSpacing(var9 - 1) - super.bounds.height);
  926.                } else {
  927.                   this.sizeToMinSize();
  928.                }
  929.  
  930.                this.enableAttachmentNotification();
  931.                if (this._owner != null) {
  932.                   this._owner.textDidChange(this, new Range(var1.index, var2.length()));
  933.                }
  934.  
  935.             } else {
  936.                this.insertString(var2.substring(var5, var6), var4);
  937.                this.insertReturn(var4 + (var6 - var5));
  938.                var4 += var6 - var5 + 1;
  939.                int var7 = var2.length() - 1;
  940.  
  941.                while(var6 < var7) {
  942.                   var5 = var6 + 1;
  943.                   var6 = var2.indexOf(10, var5);
  944.                   if (var6 == -1) {
  945.                      var6 = var7 + 1;
  946.                      var8 = false;
  947.                   }
  948.  
  949.                   if (var6 > var5) {
  950.                      String var3 = var2.substring(var5, var6);
  951.                      this.insertString(var3, var4);
  952.                      if (var8) {
  953.                         this.insertReturn(var4 + (var6 - var5));
  954.                      }
  955.  
  956.                      var4 += var6 - var5 + 1;
  957.                   } else {
  958.                      this.insertReturn(var4);
  959.                      ++var4;
  960.                   }
  961.                }
  962.  
  963.                this.enableResizing();
  964.                if (var9 > 0) {
  965.                   this.sizeBy(0, this.adjustCharCountsAndSpacing(var9 - 1) - super.bounds.height);
  966.                } else {
  967.                   this.sizeToMinSize();
  968.                }
  969.  
  970.                this.enableAttachmentNotification();
  971.                if (this._owner != null) {
  972.                   this._owner.textDidChange(this, new Range(var1.index, var2.length()));
  973.                }
  974.  
  975.             }
  976.          } else {
  977.             this.enableResizing();
  978.             if (var9 > 0) {
  979.                this.sizeBy(0, this.adjustCharCountsAndSpacing(var9 - 1) - super.bounds.height);
  980.             } else {
  981.                this.sizeToMinSize();
  982.             }
  983.  
  984.             if (this._owner != null) {
  985.                this._owner.textDidChange(this, new Range(var1.index, 0));
  986.             }
  987.  
  988.          }
  989.       }
  990.    }
  991.  
  992.    public String stringForRange(Range var1) {
  993.       TextParagraph var2 = this._paragraphForIndex(var1.index);
  994.       TextParagraph var3 = this._paragraphForIndex(var1.index + var1.length);
  995.       if (var2 == null) {
  996.          return null;
  997.       } else {
  998.          if (var3 == null) {
  999.             var3 = this.lastParagraph();
  1000.          }
  1001.  
  1002.          if (var2 == var3) {
  1003.             return var2.stringForRange(var1);
  1004.          } else {
  1005.             StringBuffer var5 = new StringBuffer();
  1006.             Range var6 = allocateRange();
  1007.             int var7 = this._paragraphVector.indexOfIdentical(var2);
  1008.  
  1009.             for(int var8 = this._paragraphVector.indexOfIdentical(var3); var7 <= var8; ++var7) {
  1010.                var6.index = var1.index;
  1011.                var6.length = var1.length;
  1012.                TextParagraph var4 = (TextParagraph)this._paragraphVector.elementAt(var7);
  1013.                var6.intersectWith(var4.range());
  1014.                var5.append(var4.stringForRange(var6));
  1015.             }
  1016.  
  1017.             recycleRange(var6);
  1018.             return var5.toString();
  1019.          }
  1020.       }
  1021.    }
  1022.  
  1023.    public void setAttributesForRange(Hashtable var1, Range var2) {
  1024.       Range var3 = this.paragraphsRangeForRange(var2);
  1025.       int var6 = var3.index;
  1026.  
  1027.       for(int var7 = var3.index + var3.length; var6 < var7; ++var6) {
  1028.          ((TextParagraph)this._paragraphVector.elementAt(var6)).setFormat((TextParagraphFormat)null);
  1029.       }
  1030.  
  1031.       Vector var4 = this.createAndReturnRunsForRange(var2);
  1032.       var6 = 0;
  1033.  
  1034.       for(int var9 = var4.count(); var6 < var9; ++var6) {
  1035.          TextStyleRun var5 = (TextStyleRun)var4.elementAt(var6);
  1036.          var5.setAttributes((Hashtable)null);
  1037.       }
  1038.  
  1039.       this.addAttributesForRange(var1, var2);
  1040.    }
  1041.  
  1042.    public Hashtable attributesAtIndex(int var1) {
  1043.       TextStyleRun var2 = this._runForIndex(var1);
  1044.       TextParagraph var3 = this._paragraphForIndex(var1);
  1045.       if (var2 != null && var3 != null) {
  1046.          Hashtable var4 = var2.attributes();
  1047.          if (var4 == null) {
  1048.             TextParagraphFormat var7 = var3.format();
  1049.             if (var7 == null) {
  1050.                return this._defaultAttributes;
  1051.             } else {
  1052.                Hashtable var8 = (Hashtable)this._defaultAttributes.clone();
  1053.                var8.put("ParagraphFormatKey", var7);
  1054.                return var8;
  1055.             }
  1056.          } else {
  1057.             TextParagraphFormat var5 = var3.format();
  1058.             Hashtable var6 = (Hashtable)var4.clone();
  1059.             if (var5 != null) {
  1060.                var6.put("ParagraphFormatKey", var5);
  1061.             } else {
  1062.                var6.put("ParagraphFormatKey", this._defaultAttributes.get("ParagraphFormatKey"));
  1063.             }
  1064.  
  1065.             return var6;
  1066.          }
  1067.       } else {
  1068.          return this._defaultAttributes;
  1069.       }
  1070.    }
  1071.  
  1072.    public int length() {
  1073.       return this._charCount - 1;
  1074.    }
  1075.  
  1076.    public String string() {
  1077.       Range var2 = allocateRange(0, this.length());
  1078.       String var1 = this.stringForRange(var2);
  1079.       recycleRange(var2);
  1080.       return var1;
  1081.    }
  1082.  
  1083.    public void setString(String var1) {
  1084.       Range var2 = allocateRange(0, this.length());
  1085.       this.replaceRangeWithString(var2, var1);
  1086.       recycleRange(var2);
  1087.    }
  1088.  
  1089.    public Range appendString(String var1) {
  1090.       Range var2 = allocateRange(this.length(), 0);
  1091.       this.replaceRangeWithString(var2, var1);
  1092.       var2.length = var1.length();
  1093.       return var2;
  1094.    }
  1095.  
  1096.    public void replaceRangeWithTextAttachment(Range var1, TextAttachment var2) {
  1097.       this.replaceRangeWithString(var1, "@");
  1098.       Hashtable var3 = new Hashtable();
  1099.       var3.put("TextAttachmentKey", var2);
  1100.       Range var4 = allocateRange(var1.index, 1);
  1101.       this.addAttributesForRange(var3, var4);
  1102.       recycleRange(var4);
  1103.    }
  1104.  
  1105.    public void addAttributesForRange(Hashtable var1, Range var2) {
  1106.       if (this._owner != null) {
  1107.          this._owner.attributesWillChange(this, var2);
  1108.       }
  1109.  
  1110.       this.addAttributesForRangeWithoutNotification(var1, var2);
  1111.       if (this._owner != null) {
  1112.          this._owner.attributesDidChange(this, var2);
  1113.       }
  1114.  
  1115.    }
  1116.  
  1117.    public void addAttributeForRange(String var1, Object var2, Range var3) {
  1118.       Hashtable var4 = new Hashtable();
  1119.       var4.put(var1, var2);
  1120.       this.addAttributesForRange(var4, var3);
  1121.    }
  1122.  
  1123.    public void removeAttributeForRange(String var1, Range var2) {
  1124.       Vector var3 = this.runsForRange(var2);
  1125.       Range var7 = allocateRange();
  1126.       int var4 = 0;
  1127.  
  1128.       for(int var5 = var3.count(); var4 < var5; ++var4) {
  1129.          Range var6 = (Range)var3.elementAt(var4);
  1130.          TextStyleRun var8 = this._runForIndex(var6.index);
  1131.          Hashtable var9 = var8.attributes();
  1132.          if (var9 != null && var9.get(var1) != null) {
  1133.             Hashtable var10 = (Hashtable)var9.clone();
  1134.             var10.remove(var1);
  1135.             var7.index = var2.index;
  1136.             var7.length = var2.length;
  1137.             var7.intersectWith(var6);
  1138.             this.setAttributesForRange(var10, var7);
  1139.          }
  1140.       }
  1141.  
  1142.    }
  1143.  
  1144.    public void addDefaultAttribute(String var1, Object var2) {
  1145.       Hashtable var3 = this.defaultAttributes();
  1146.       var3.put(var1, var2);
  1147.       this.setDefaultAttributes(var3);
  1148.    }
  1149.  
  1150.    public Vector runsForRange(Range var1) {
  1151.       Vector var4 = new Vector();
  1152.       boolean var10 = false;
  1153.       if (var1.length == 0) {
  1154.          Range var11 = this.runForIndex(var1.index);
  1155.          if (!var11.isNullRange()) {
  1156.             var4.addElement(var11);
  1157.          }
  1158.  
  1159.          return var4;
  1160.       } else {
  1161.          TextStyleRun var2 = this._runForIndex(var1.index);
  1162.          if (var2 == null) {
  1163.             var2 = this._runForIndex(0);
  1164.          }
  1165.  
  1166.          TextStyleRun var3 = this._runForIndex(var1.index + var1.length() - 1);
  1167.          if (var3 == null) {
  1168.             var3 = this._runForIndex(this.length() - 1);
  1169.          }
  1170.  
  1171.          Vector var5 = var2.paragraph().runVector();
  1172.          int var7;
  1173.          if (var2.paragraph() == var3.paragraph()) {
  1174.             var7 = var5.indexOfIdentical(var3) + 1;
  1175.             var10 = true;
  1176.          } else {
  1177.             var7 = var5.count();
  1178.             var10 = false;
  1179.          }
  1180.  
  1181.          for(int var6 = var5.indexOfIdentical(var2); var6 < var7; ++var6) {
  1182.             var4.addElement(((TextStyleRun)var5.elementAt(var6)).range());
  1183.          }
  1184.  
  1185.          if (!var10) {
  1186.             int var14 = this._paragraphVector.indexOfIdentical(var2.paragraph()) + 1;
  1187.  
  1188.             for(int var16 = this._paragraphVector.indexOfIdentical(var3.paragraph()); var14 < var16; ++var14) {
  1189.                var5 = ((TextParagraph)this._paragraphVector.elementAt(var14)).runVector();
  1190.                int var8 = 0;
  1191.  
  1192.                for(int var9 = var5.count(); var8 < var9; ++var8) {
  1193.                   var4.addElement(((TextStyleRun)var5.elementAt(var8)).range());
  1194.                }
  1195.             }
  1196.  
  1197.             var5 = var3.paragraph().runVector();
  1198.             var14 = 0;
  1199.  
  1200.             for(int var17 = var5.indexOfIdentical(var3); var14 <= var17; ++var14) {
  1201.                var4.addElement(((TextStyleRun)var5.elementAt(var14)).range());
  1202.             }
  1203.          }
  1204.  
  1205.          return var4;
  1206.       }
  1207.    }
  1208.  
  1209.    public Vector paragraphsForRange(Range var1) {
  1210.       Range var2 = this.paragraphsRangeForRange(var1);
  1211.       Vector var5 = new Vector();
  1212.       int var3 = var2.index;
  1213.  
  1214.       for(int var4 = var2.index + var2.length; var3 < var4; ++var3) {
  1215.          Range var6 = ((TextParagraph)this._paragraphVector.elementAt(var3)).range();
  1216.          if (var3 == var4 - 1) {
  1217.             --var6.length;
  1218.          }
  1219.  
  1220.          var5.addElement(var6);
  1221.       }
  1222.  
  1223.       return var5;
  1224.    }
  1225.  
  1226.    public Range runForIndex(int var1) {
  1227.       TextStyleRun var2 = this._runForIndex(var1);
  1228.       return var2 == null ? allocateRange() : var2.range();
  1229.    }
  1230.  
  1231.    public Range paragraphForIndex(int var1) {
  1232.       Range var3 = allocateRange(var1, 0);
  1233.       Vector var2 = this.paragraphsForRange(var3);
  1234.       recycleRange(var3);
  1235.       return var2.count() > 0 ? (Range)var2.elementAt(0) : allocateRange();
  1236.    }
  1237.  
  1238.    public Range paragraphForPoint(int var1, int var2) {
  1239.       TextParagraph var3 = this._paragraphForPoint(var1, var2);
  1240.       return var3 != null ? var3.range() : allocateRange();
  1241.    }
  1242.  
  1243.    public Range runForPoint(int var1, int var2) {
  1244.       TextPositionInfo var3 = this.positionForPoint(var1, var2, true);
  1245.       if (var3 != null) {
  1246.          TextStyleRun var4 = this._runForIndex(var3._absPosition);
  1247.          if (var4 != null) {
  1248.             return var4.range();
  1249.          }
  1250.       }
  1251.  
  1252.       return allocateRange();
  1253.    }
  1254.  
  1255.    public int indexForPoint(int var1, int var2) {
  1256.       TextPositionInfo var3 = this.positionForPoint(var1, var2, true);
  1257.       return var3 != null ? var3._absPosition : -1;
  1258.    }
  1259.  
  1260.    public Vector rectsForRange(Range var1) {
  1261.       return this.rectsForRange(var1, (Rect)null);
  1262.    }
  1263.  
  1264.    public Range selectedRange() {
  1265.       if (this._selectedRange == null) {
  1266.          this._selectedRange = allocateRange();
  1267.       }
  1268.  
  1269.       this._selectedRange.index = this._selection.selectionStart();
  1270.       if (this._selectedRange.index < 0) {
  1271.          return allocateRange();
  1272.       } else {
  1273.          this._selectedRange.length = this._selection.selectionEnd() - this._selection.selectionStart();
  1274.          return this._selectedRange;
  1275.       }
  1276.    }
  1277.  
  1278.    public void selectRange(Range var1) {
  1279.       if (var1.isNullRange()) {
  1280.          this._selection.clearRange();
  1281.       } else {
  1282.          this._selection.setRange(var1.index(), var1.lastIndex() + 1);
  1283.       }
  1284.  
  1285.       this._selectionChanged();
  1286.    }
  1287.  
  1288.    public boolean hasSelection() {
  1289.       Range var1 = this.selectedRange();
  1290.       return !var1.isNullRange();
  1291.    }
  1292.  
  1293.    public void insertHTMLElementsInRange(Vector var1, Range var2, Hashtable var3) {
  1294.       int[] var6 = new int[var1.count()];
  1295.       int var7 = 0;
  1296.       int var8 = 0;
  1297.       Hashtable var9 = new Hashtable();
  1298.       FastStringBuffer var10 = new FastStringBuffer();
  1299.       if (var3 == null) {
  1300.          var3 = this.defaultAttributes();
  1301.       }
  1302.  
  1303.       Hashtable var11 = attributesByRemovingStaticAttributes(var3);
  1304.       ((View)this).setDirty(true);
  1305.       this.disableResizing();
  1306.       var10.setDoublesCapacityWhenGrowing(true);
  1307.       int var4 = 0;
  1308.  
  1309.       for(int var5 = var1.count(); var4 < var5; ++var4) {
  1310.          ((TextViewHTMLElement)var1.elementAt(var4)).appendString(var9, var10);
  1311.          if (var4 == 0) {
  1312.             var8 = var6[0] = var10.length();
  1313.          } else {
  1314.             var6[var4] = var10.length() - var8;
  1315.             var8 += var6[var4];
  1316.          }
  1317.       }
  1318.  
  1319.       this.replaceRangeWithString(var2, var10.toString());
  1320.       this.disableFormatting();
  1321.       var4 = 0;
  1322.  
  1323.       for(int var13 = var1.count(); var4 < var13; ++var4) {
  1324.          ((TextViewHTMLElement)var1.elementAt(var4)).setAttributesStartingAt(var2.index + var7, var11, this, var9);
  1325.          var7 += var6[var4];
  1326.       }
  1327.  
  1328.       this.enableFormatting();
  1329.       this.reformatAll();
  1330.       this.enableResizing();
  1331.       this.sizeToMinSize();
  1332.    }
  1333.  
  1334.    public void importHTMLInRange(InputStream var1, Range var2, URL var3) throws IOException, HTMLParsingException {
  1335.       this.importHTMLInRange(var1, var2, var3, this.defaultAttributes());
  1336.    }
  1337.  
  1338.    public void importHTMLInRange(InputStream var1, Range var2, URL var3, Hashtable var4) throws IOException, HTMLParsingException {
  1339.       Vector var5 = new Vector();
  1340.       this.validateHTMLParsingRules();
  1341.       HTMLParser var6 = new HTMLParser(var1, this._htmlParsingRules);
  1342.  
  1343.       HTMLElement var7;
  1344.       try {
  1345.          while((var7 = var6.nextHTMLElement()) != null) {
  1346.             var5.addElement(var7);
  1347.          }
  1348.       } catch (InstantiationException var8) {
  1349.          throw new InconsistencyException("Cannot intantiate HTML storage");
  1350.       } catch (IllegalAccessException var9) {
  1351.          throw new InconsistencyException("Cannot access HTML storage classes");
  1352.       }
  1353.  
  1354.       this.setBaseURL(var3);
  1355.       this.insertHTMLElementsInRange(var5, var2, var4);
  1356.    }
  1357.  
  1358.    public void importHTMLFromURLString(String var1) {
  1359.       Range var2 = allocateRange(0, this.length());
  1360.  
  1361.       try {
  1362.          URL var3 = new URL(var1);
  1363.          InputStream var4 = var3.openStream();
  1364.          this.importHTMLInRange(var4, var2, var3, this.defaultAttributes());
  1365.          var2.index = 0;
  1366.          var2.length = 0;
  1367.          this.selectRange(var2);
  1368.          this.scrollRangeToVisible(var2);
  1369.       } catch (MalformedURLException var6) {
  1370.          System.err.println("Bad URL " + var1);
  1371.       } catch (IOException var7) {
  1372.          System.err.println("IOException while reading " + var1);
  1373.       } catch (HTMLParsingException var8) {
  1374.          System.err.println("At line " + var8.lineNumber() + ":" + var8);
  1375.       }
  1376.  
  1377.       recycleRange(var2);
  1378.    }
  1379.  
  1380.    public void setHTMLParsingRules(HTMLParsingRules var1) {
  1381.       this._htmlParsingRules = var1;
  1382.    }
  1383.  
  1384.    public HTMLParsingRules htmlParsingRules() {
  1385.       this.validateHTMLParsingRules();
  1386.       return this._htmlParsingRules;
  1387.    }
  1388.  
  1389.    public Range runWithLinkDestinationNamed(String var1) {
  1390.       TextStyleRun var7 = null;
  1391.       Range var9 = null;
  1392.       int var2 = 0;
  1393.  
  1394.       for(int var3 = this._paragraphVector.count(); var2 < var3; ++var2) {
  1395.          TextParagraph var6 = (TextParagraph)this._paragraphVector.elementAt(var2);
  1396.          int var4 = 0;
  1397.  
  1398.          for(int var5 = var6._runVector.count(); var4 < var5; ++var4) {
  1399.             var7 = (TextStyleRun)var6._runVector.elementAt(var4);
  1400.             String var8;
  1401.             if (var7._attributes != null && (var8 = (String)var7._attributes.get("LinkDestinationKey")) != null && var8.equals(var1)) {
  1402.                var9 = var7.range();
  1403.                break;
  1404.             }
  1405.          }
  1406.  
  1407.          if (var9 != null) {
  1408.             break;
  1409.          }
  1410.       }
  1411.  
  1412.       if (var9 == null) {
  1413.          return new Range();
  1414.       } else {
  1415.          if (var7 != null) {
  1416.             for(Range var10 = var9; var9.length == 0; var9 = var7.range()) {
  1417.                var7 = this.runAfter(var7);
  1418.                if (var7 == null) {
  1419.                   var9 = var10;
  1420.                   break;
  1421.                }
  1422.             }
  1423.          }
  1424.  
  1425.          return var9;
  1426.       }
  1427.    }
  1428.  
  1429.    public void describeClassInfo(ClassInfo var1) {
  1430.       super.describeClassInfo(var1);
  1431.       var1.addClass("netscape.application.TextView", 2);
  1432.       var1.addField("paragraphVector", (byte)18);
  1433.       var1.addField("backgroundColor", (byte)18);
  1434.       var1.addField("selectionColor", (byte)18);
  1435.       var1.addField("filter", (byte)18);
  1436.       var1.addField("defaultAttributes", (byte)18);
  1437.       var1.addField("paragraphSpacing", (byte)8);
  1438.       var1.addField("useSingleFont", (byte)0);
  1439.       var1.addField("editable", (byte)0);
  1440.       var1.addField("selectable", (byte)0);
  1441.       var1.addField("transparent", (byte)0);
  1442.       var1.addField("htmlParsingRules", (byte)18);
  1443.       var1.addField("owner", (byte)18);
  1444.    }
  1445.  
  1446.    public void encode(Encoder var1) throws CodingException {
  1447.       super.encode(var1);
  1448.       var1.encodeObject("paragraphVector", this._paragraphVector);
  1449.       var1.encodeObject("backgroundColor", this._backgroundColor);
  1450.       var1.encodeObject("selectionColor", this._selectionColor);
  1451.       var1.encodeObject("filter", (Codable)this._filter);
  1452.       var1.encodeObject("defaultAttributes", this._defaultAttributes);
  1453.       var1.encodeInt("paragraphSpacing", this._paragraphSpacing);
  1454.       var1.encodeBoolean("useSingleFont", this._useSingleFont);
  1455.       var1.encodeBoolean("editable", this._editable);
  1456.       var1.encodeBoolean("selectable", this._selectable);
  1457.       var1.encodeBoolean("transparent", this.transparent);
  1458.       var1.encodeObject("htmlParsingRules", this._htmlParsingRules);
  1459.       var1.encodeObject("owner", this._owner);
  1460.    }
  1461.  
  1462.    public void decode(Decoder var1) throws CodingException {
  1463.       int var2 = var1.versionForClassName("netscape.application.TextView");
  1464.       super.decode(var1);
  1465.       this._paragraphVector = (Vector)var1.decodeObject("paragraphVector");
  1466.       this._backgroundColor = (Color)var1.decodeObject("backgroundColor");
  1467.       this._selectionColor = (Color)var1.decodeObject("selectionColor");
  1468.       this._filter = (TextFilter)var1.decodeObject("filter");
  1469.       this._defaultAttributes = (Hashtable)var1.decodeObject("defaultAttributes");
  1470.       this._paragraphSpacing = var1.decodeInt("paragraphSpacing");
  1471.       this._useSingleFont = var1.decodeBoolean("useSingleFont");
  1472.       this._editable = var1.decodeBoolean("editable");
  1473.       this._selectable = var1.decodeBoolean("selectable");
  1474.       this.transparent = var1.decodeBoolean("transparent");
  1475.       if (var2 >= 2) {
  1476.          this._htmlParsingRules = (HTMLParsingRules)var1.decodeObject("htmlParsingRules");
  1477.          this._owner = (TextViewOwner)var1.decodeObject("owner");
  1478.       }
  1479.  
  1480.    }
  1481.  
  1482.    public void finishDecoding() throws CodingException {
  1483.       super.finishDecoding();
  1484.       this._defaultFontMetricsCache = null;
  1485.       int var2 = this._paragraphVector.count();
  1486.  
  1487.       while(var2-- > 0) {
  1488.          TextParagraph var1 = (TextParagraph)this._paragraphVector.elementAt(var2);
  1489.          var1.setOwner(this);
  1490.       }
  1491.  
  1492.       this.reformatAll();
  1493.    }
  1494.  
  1495.    public int lineCount() {
  1496.       int var3 = 0;
  1497.       int var1 = 0;
  1498.  
  1499.       for(int var2 = this._paragraphVector.count(); var1 < var2; ++var1) {
  1500.          TextParagraph var4 = (TextParagraph)this._paragraphVector.elementAt(var1);
  1501.          var3 += var4.lineCount();
  1502.       }
  1503.  
  1504.       return var3;
  1505.    }
  1506.  
  1507.    public URL baseURL() {
  1508.       return this._baseURL;
  1509.    }
  1510.  
  1511.    public boolean canBecomeSelectedView() {
  1512.       return this.isEditable() || this.isSelectable();
  1513.    }
  1514.  
  1515.    public void willBecomeSelected() {
  1516.       ((View)this).setFocusedView();
  1517.    }
  1518.  
  1519.    public static String stringWithoutCarriageReturns(String var0) {
  1520.       FastStringBuffer var1 = new FastStringBuffer();
  1521.       int var2 = 0;
  1522.  
  1523.       for(int var3 = var0.length(); var2 < var3; ++var2) {
  1524.          char var4 = var0.charAt(var2);
  1525.          if (var4 != '\r' || var2 + 1 >= var3 || var0.charAt(var2 + 1) != '\n') {
  1526.             var1.append(var4);
  1527.          }
  1528.       }
  1529.  
  1530.       return var1.toString();
  1531.    }
  1532.  
  1533.    FontMetrics defaultFontMetrics() {
  1534.       if (this._defaultFontMetricsCache == null) {
  1535.          this._defaultFontMetricsCache = this.font().fontMetrics();
  1536.       }
  1537.  
  1538.       return this._defaultFontMetricsCache;
  1539.    }
  1540.  
  1541.    static Hashtable attributesByRemovingStaticAttributes(Hashtable var0) {
  1542.       if (var0 == null) {
  1543.          return null;
  1544.       } else {
  1545.          Hashtable var1 = (Hashtable)var0.clone();
  1546.          var1.remove("TextAttachmentKey");
  1547.          var1.remove("TextAttachmentBaselineOffsetKey");
  1548.          return var1;
  1549.       }
  1550.    }
  1551.  
  1552.    private void addParagraph(TextParagraph var1) {
  1553.       if (var1 != null) {
  1554.          var1.setOwner(this);
  1555.          this._paragraphVector.addElement(var1);
  1556.       }
  1557.    }
  1558.  
  1559.    synchronized void _setEditing(boolean var1) {
  1560.       this._editing = var1;
  1561.    }
  1562.  
  1563.    synchronized boolean isEditing() {
  1564.       return this._editing;
  1565.    }
  1566.  
  1567.    private void reformatAll() {
  1568.       Range var5 = this.selectedRange();
  1569.       int var2 = 0;
  1570.       this._charCount = 0;
  1571.       int var4 = this._paragraphVector.count();
  1572.       if (this.formattingEnabled()) {
  1573.          for(int var3 = 0; var3 < var4; ++var3) {
  1574.             TextParagraph var1 = (TextParagraph)this._paragraphVector.elementAt(var3);
  1575.             var1._y = var2;
  1576.             var1._startChar = this._charCount;
  1577.             var1.computeLineBreaksAndHeights(super.bounds.width);
  1578.             var2 += var1._height + this._paragraphSpacing;
  1579.             this._charCount += var1._charCount;
  1580.          }
  1581.  
  1582.          this.sizeBy(0, var2 - super.bounds.height);
  1583.          this.notifyAttachmentsForRange(new Range(0, this.length()), true);
  1584.          this.selectRange(var5);
  1585.       }
  1586.    }
  1587.  
  1588.    void disableFormatting() {
  1589.       ++this._formattingDisabled;
  1590.    }
  1591.  
  1592.    void enableFormatting() {
  1593.       --this._formattingDisabled;
  1594.       if (this._formattingDisabled < 0) {
  1595.          this._formattingDisabled = 0;
  1596.       }
  1597.  
  1598.    }
  1599.  
  1600.    boolean formattingEnabled() {
  1601.       return this._formattingDisabled == 0;
  1602.    }
  1603.  
  1604.    private void formatParagraphAtIndex(int var1) {
  1605.       Range var8 = new Range();
  1606.       if (this.formattingEnabled()) {
  1607.          if (var1 != -1) {
  1608.             TextParagraph var3 = (TextParagraph)this._paragraphVector.elementAt(var1);
  1609.             int var4 = var1 - 1;
  1610.             if (var4 >= -1) {
  1611.                int var7;
  1612.                if (var4 == -1) {
  1613.                   this._charCount = 0;
  1614.                   var7 = 0;
  1615.                } else {
  1616.                   TextParagraph var2 = (TextParagraph)this._paragraphVector.elementAt(var4);
  1617.                   this._charCount = var2._startChar + var2._charCount;
  1618.                   var7 = var2._y + var2._height + this._paragraphSpacing;
  1619.                }
  1620.  
  1621.                var3.setY(var7);
  1622.                var3.setStartChar(this._charCount);
  1623.                var3.computeLineBreaksAndHeights(super.bounds.width);
  1624.                this._charCount += var3._charCount;
  1625.                var7 += var3._height + this._paragraphSpacing;
  1626.                int var5 = this._paragraphVector.count();
  1627.  
  1628.                for(int var6 = var1 + 1; var6 < var5; ++var6) {
  1629.                   TextParagraph var9 = (TextParagraph)this._paragraphVector.elementAt(var6);
  1630.                   var9.setY(var7);
  1631.                   var9.setStartChar(this._charCount);
  1632.                   var7 += var9._height + this._paragraphSpacing;
  1633.                   this._charCount += var9._charCount;
  1634.                }
  1635.  
  1636.                var8.index = var3._startChar;
  1637.                var8.unionWith(this.lastParagraph().range());
  1638.                this.sizeBy(0, var7 - super.bounds.height);
  1639.                this.notifyAttachmentsForRange(var8, true);
  1640.             }
  1641.          }
  1642.       }
  1643.    }
  1644.  
  1645.    private void formatParagraph(TextParagraph var1) {
  1646.       this.formatParagraphAtIndex(this._paragraphVector.indexOfIdentical(var1));
  1647.    }
  1648.  
  1649.    private int adjustCharCountsAndSpacing(int var1) {
  1650.       int var3 = this._charCount = 0;
  1651.       if (var1 > 0) {
  1652.          TextParagraph var2 = (TextParagraph)this._paragraphVector.elementAt(var1 - 1);
  1653.          var3 = var2._y + var2._height + this._paragraphSpacing;
  1654.          this._charCount = var2._startChar + var2._charCount;
  1655.       }
  1656.  
  1657.       int var5 = this._paragraphVector.count();
  1658.  
  1659.       for(int var4 = var1; var4 < var5; ++var4) {
  1660.          TextParagraph var6 = (TextParagraph)this._paragraphVector.elementAt(var4);
  1661.          var6._y = var3;
  1662.          var6._startChar = this._charCount;
  1663.          var3 += var6._height + this._paragraphSpacing;
  1664.          this._charCount += var6._charCount;
  1665.       }
  1666.  
  1667.       return var3;
  1668.    }
  1669.  
  1670.    private int adjustCharCountsAndSpacing() {
  1671.       return this.adjustCharCountsAndSpacing(0);
  1672.    }
  1673.  
  1674.    int _paragraphIndexForIndex(int var1) {
  1675.       int var3 = this._paragraphVector.count();
  1676.       if (var1 > this.length() / 2) {
  1677.          for(int var4 = var3 - 1; var4 >= 0; --var4) {
  1678.             TextParagraph var2 = (TextParagraph)this._paragraphVector.elementAt(var4);
  1679.             if (var1 >= var2._startChar && var1 < var2._startChar + var2._charCount) {
  1680.                return var4;
  1681.             }
  1682.          }
  1683.       } else {
  1684.          for(int var6 = 0; var6 < var3; ++var6) {
  1685.             TextParagraph var5 = (TextParagraph)this._paragraphVector.elementAt(var6);
  1686.             if (var1 >= var5._startChar && var1 < var5._startChar + var5._charCount) {
  1687.                return var6;
  1688.             }
  1689.          }
  1690.       }
  1691.  
  1692.       return -1;
  1693.    }
  1694.  
  1695.    TextParagraph _paragraphForIndex(int var1) {
  1696.       int var2 = this._paragraphIndexForIndex(var1);
  1697.       return var2 != -1 ? (TextParagraph)this._paragraphVector.elementAt(var2) : null;
  1698.    }
  1699.  
  1700.    private TextParagraph _paragraphForPoint(int var1, int var2) {
  1701.       if (var2 < 0) {
  1702.          var2 = 0;
  1703.          var1 = 0;
  1704.       }
  1705.  
  1706.       int var4 = this._paragraphVector.count();
  1707.       int var6 = 0;
  1708.  
  1709.       for(int var5 = 0; var5 < var4; ++var5) {
  1710.          TextParagraph var3 = (TextParagraph)this._paragraphVector.elementAt(var5);
  1711.          int var7 = var6 + var3._height;
  1712.          if (var2 >= var6 && var2 < var7) {
  1713.             return var3;
  1714.          }
  1715.  
  1716.          var6 = var7;
  1717.       }
  1718.  
  1719.       return null;
  1720.    }
  1721.  
  1722.    TextPositionInfo positionInfoForIndex(int var1) {
  1723.       TextParagraph var2 = this._paragraphForIndex(var1);
  1724.       if (var2 == null) {
  1725.          var2 = this.lastParagraph();
  1726.       }
  1727.  
  1728.       return var2._infoForPosition(var1);
  1729.    }
  1730.  
  1731.    private TextPositionInfo positionForPoint(int var1, int var2, boolean var3) {
  1732.       if (var2 < 0) {
  1733.          var2 = 0;
  1734.          var1 = 0;
  1735.       }
  1736.  
  1737.       TextParagraph var4 = this._paragraphForPoint(var1, var2);
  1738.       if (var4 == null) {
  1739.          return this._charCount == 0 ? this.lastParagraph().infoForPosition(this._charCount, var2) : this.lastParagraph().infoForPosition(this._charCount - 1, var2);
  1740.       } else {
  1741.          return var4.positionForPoint(var1, var2, var3);
  1742.       }
  1743.    }
  1744.  
  1745.    void drawInsertionPoint() {
  1746.       Rect var1 = this._selection.insertionPointRect();
  1747.       ((View)this).addDirtyRect(var1);
  1748.       returnRect(var1);
  1749.    }
  1750.  
  1751.    private void insertString(String var1, int var2) {
  1752.       int var11 = 0;
  1753.       if (var1 != null) {
  1754.          int var14 = this._paragraphIndexForIndex(var2);
  1755.          if (var14 != -1) {
  1756.             TextParagraph var3 = (TextParagraph)this._paragraphVector.elementAt(var14);
  1757.             if (var3 != null) {
  1758.                TextParagraph var4 = this.lastParagraph();
  1759.                if (var4 != null) {
  1760.                   int var10000 = var4._y + var4._height;
  1761.                } else {
  1762.                   boolean var9 = false;
  1763.                }
  1764.  
  1765.                TextPositionInfo var7 = this.positionInfoForIndex(var2);
  1766.                if (var7 == null) {
  1767.                   var7 = var3.infoForPosition(var2, -1);
  1768.                }
  1769.  
  1770.                TextPositionInfo var6 = var3.insertCharOrStringAt('\u0000', var1, var2);
  1771.                var11 = var1.length();
  1772.                this._charCount += var11;
  1773.                if (var6 == null) {
  1774.                   this._selection.showInsertionPoint();
  1775.                } else if (((View)this).isDirty() && super.dirtyRect == null) {
  1776.                   Range var17 = new Range(var3._startChar, this.length() - var3._startChar);
  1777.                   this.notifyAttachmentsForRange(var17, true);
  1778.                } else {
  1779.                   var6.setAbsPosition(var2 + var11);
  1780.                   TextParagraphFormat var13 = var3.currentParagraphFormat();
  1781.                   if (var6._redrawCurrentLineOnly && var13._justification == 0) {
  1782.                      TextParagraph var5 = this._updateParagraph;
  1783.                      int var10 = this._updateLine;
  1784.                      this._updateParagraph = var3;
  1785.                      this._updateLine = var6._updateLine;
  1786.                      this._drawText = false;
  1787.                      Rect var8 = var3.rectForLine(var6._lineNumber);
  1788.                      var8.setBounds(var7._x, var8.y, var8.width - (var7._x - var8.x), var8.height);
  1789.                      ((View)this).addDirtyRect(var8);
  1790.                      returnRect(var8);
  1791.                      this._drawText = true;
  1792.                      this._updateParagraph = var5;
  1793.                      this._updateLine = var10;
  1794.                      this.notifyAttachmentsForRange(var6.lineRange(), true);
  1795.                   } else if (!var6._redrawCurrentParagraphOnly && !var6._redrawCurrentLineOnly) {
  1796.                      Range var16 = new Range(var3._startChar, this.length() - var3._startChar);
  1797.                      this.notifyAttachmentsForRange(var16, true);
  1798.                      this.dirtyRange(var16);
  1799.                   } else {
  1800.                      Range var12 = var3.range();
  1801.                      this.notifyAttachmentsForRange(var12, true);
  1802.                      this.dirtyRange(var12);
  1803.                   }
  1804.                }
  1805.             }
  1806.          }
  1807.       }
  1808.    }
  1809.  
  1810.    private void fastDeleteChar(boolean var1) {
  1811.       if (this.isEditing()) {
  1812.          int var12 = this._selection.insertionPoint();
  1813.          if (var1 || var12 != 0) {
  1814.             if (!var1 || var12 != this.length()) {
  1815.                if (var1) {
  1816.                   ++var12;
  1817.                }
  1818.  
  1819.                TextParagraph var2 = this._paragraphForIndex(var12);
  1820.                if (var2 != null) {
  1821.                   this.notifyAttachmentsForRange(new Range(var12, 1), false);
  1822.                   TextParagraph var3 = this.lastParagraph();
  1823.                   if (var3 != null) {
  1824.                      int var10000 = var3._y + var3._height;
  1825.                   } else {
  1826.                      boolean var9 = false;
  1827.                   }
  1828.  
  1829.                   TextPositionInfo var6;
  1830.                   if (var2._startChar == var12 && !this.isOnlyParagraph(var2)) {
  1831.                      int var11 = this._paragraphVector.indexOfIdentical(var2);
  1832.                      TextParagraph var4 = (TextParagraph)this._paragraphVector.elementAt(var11 - 1);
  1833.                      if (var4 != null) {
  1834.                         var4.subsumeParagraph(var2);
  1835.                         this._paragraphVector.removeElement(var2);
  1836.                         var2 = var4;
  1837.                         this.formatParagraph(var4);
  1838.                      }
  1839.  
  1840.                      if (var12 == 0) {
  1841.                         var6 = var2.infoForPosition(0, -1);
  1842.                      } else {
  1843.                         var6 = var2.infoForPosition(var12 - 1, -1);
  1844.                      }
  1845.                   } else {
  1846.                      var6 = var2.removeCharAt(var12);
  1847.                      --this._charCount;
  1848.                   }
  1849.  
  1850.                   int var10 = this.adjustCharCountsAndSpacing();
  1851.                   this.sizeBy(0, var10 - super.bounds.height);
  1852.                   if (var6 == null) {
  1853.                      this._selection.showInsertionPoint();
  1854.                   } else {
  1855.                      this.notifyAttachmentsForRange(var6._textRun._paragraph.range(), true);
  1856.                      if (!var1) {
  1857.                         if (var12 == 0) {
  1858.                            var6.setAbsPosition(0);
  1859.                         } else {
  1860.                            var6.setAbsPosition(var12 - 1);
  1861.                         }
  1862.  
  1863.                         this._selection.setInsertionPoint(var6);
  1864.                         this._selectionChanged();
  1865.                      } else {
  1866.                         this._selection.setInsertionPoint(var6);
  1867.                      }
  1868.  
  1869.                      TextParagraphFormat var14 = var2.currentParagraphFormat();
  1870.                      if (var6._redrawCurrentLineOnly && var14._justification == 0) {
  1871.                         TextParagraph var5 = this._updateParagraph;
  1872.                         int var13 = this._updateLine;
  1873.                         this._updateParagraph = var2;
  1874.                         this._updateLine = var6._updateLine;
  1875.                         this._drawText = false;
  1876.                         Rect var8 = var2.rectForLine(var6._lineNumber);
  1877.                         var8.setBounds(var6._x, var8.y, var8.width - (var6._x - var8.x), var8.height);
  1878.                         ((View)this).addDirtyRect(var8);
  1879.                         returnRect(var8);
  1880.                         this._drawText = true;
  1881.                         this._updateParagraph = var5;
  1882.                         this._updateLine = var13;
  1883.                      } else if (!var6._redrawCurrentParagraphOnly && !var6._redrawCurrentLineOnly) {
  1884.                         Range var15 = allocateRange(var2._startChar, this.length() - var2._startChar);
  1885.                         this.dirtyRange(var15);
  1886.                         recycleRange(var15);
  1887.                      } else {
  1888.                         this.dirtyRange(var2.range());
  1889.                      }
  1890.                   }
  1891.                }
  1892.             }
  1893.          }
  1894.       }
  1895.    }
  1896.  
  1897.    private Rect insertReturn() {
  1898.       if (this._selection.isARange()) {
  1899.          this.deleteSelection();
  1900.       }
  1901.  
  1902.       int var2 = this._selection.insertionPoint();
  1903.       Rect var1 = this.insertReturn(var2);
  1904.       this._selection.setRange(var2 + 1, var2 + 1);
  1905.       this._selectionChanged();
  1906.       return var1;
  1907.    }
  1908.  
  1909.    private Rect insertReturn(int var1) {
  1910.       int var4 = this._paragraphIndexForIndex(var1);
  1911.       if (var4 == -1) {
  1912.          var4 = this._paragraphVector.count() - 1;
  1913.       }
  1914.  
  1915.       TextParagraph var2 = (TextParagraph)this._paragraphVector.elementAt(var4);
  1916.       TextParagraph var3 = var2;
  1917.       var2 = var2.createNewParagraphAt(var1);
  1918.       this.formatParagraphAtIndex(var4);
  1919.       ++this._charCount;
  1920.       this._paragraphVector.insertElementAt(var2, var4 + 1);
  1921.       this.formatParagraphAtIndex(var4 + 1);
  1922.       return newRect(0, var3._y, super.bounds.width, super.bounds.height - var3._y);
  1923.    }
  1924.  
  1925.    private TextStyleRun _runForIndex(int var1) {
  1926.       int var2 = this.length();
  1927.       if (var2 > 0 && var1 >= var2) {
  1928.          return this._runForIndex(var2 - 1);
  1929.       } else if (var1 >= 0) {
  1930.          TextParagraph var3 = this._paragraphForIndex(var1);
  1931.          return var3 != null ? var3.runForCharPosition(var1) : null;
  1932.       } else {
  1933.          return null;
  1934.       }
  1935.    }
  1936.  
  1937.    private boolean equalsAttributesHint(Hashtable var1, Hashtable var2) {
  1938.       if (var1 == var2) {
  1939.          return true;
  1940.       } else {
  1941.          return var1 != null && var2 != null ? false : false;
  1942.       }
  1943.    }
  1944.  
  1945.    private void _keyDown() {
  1946.       Event var6 = (Event)this._eventVector.removeFirstElement();
  1947.       if (var6 instanceof KeyEvent) {
  1948.          KeyEvent var5 = (KeyEvent)var6;
  1949.          this._selection.disableInsertionPoint();
  1950.          int var7 = this._selection.insertionPoint();
  1951.          this._paragraphForIndex(var7);
  1952.          boolean var9 = true;
  1953.          if (var5.isReturnKey()) {
  1954.             Range var10 = new Range(this.selectedRange());
  1955.             if (this._owner != null) {
  1956.                this._owner.textWillChange(this, var10);
  1957.             }
  1958.  
  1959.             Rect var4 = this.insertReturn();
  1960.             if (this._owner != null) {
  1961.                var10.length = 1;
  1962.                this._owner.textDidChange(this, var10);
  1963.             }
  1964.  
  1965.             ((View)this).draw(var4);
  1966.             returnRect(var4);
  1967.          } else if (var5.isLeftArrowKey()) {
  1968.             if (var5.isShiftKeyDown()) {
  1969.                int var8 = this._selection.orderedSelectionEnd() - 1;
  1970.                if (var8 < 0) {
  1971.                   var8 = 0;
  1972.                }
  1973.  
  1974.                this._selection.setRange(this._selection.orderedSelectionStart(), var8, true);
  1975.             } else if (var7 == -1) {
  1976.                this._selection.setRange(this._selection.selectionStart(), this._selection.selectionStart(), true);
  1977.             } else {
  1978.                int var15 = var7 - 1;
  1979.                if (var15 < 0) {
  1980.                   var15 = 0;
  1981.                }
  1982.  
  1983.                this._selection.setRange(var15, var15, true);
  1984.             }
  1985.  
  1986.             this._selectionChanged();
  1987.          } else if (var5.isRightArrowKey()) {
  1988.             if (var5.isShiftKeyDown()) {
  1989.                this._selection.setRange(this._selection.orderedSelectionStart(), this._selection.orderedSelectionEnd() + 1, false);
  1990.             } else if (var7 == -1) {
  1991.                this._selection.setRange(this._selection.selectionEnd(), this._selection.selectionEnd());
  1992.             } else {
  1993.                this._selection.setRange(var7 + 1, var7 + 1, false);
  1994.             }
  1995.  
  1996.             this._selectionChanged();
  1997.          } else if (var5.isUpArrowKey()) {
  1998.             TextPositionInfo var3 = this._selection.orderedSelectionEndInfo();
  1999.             TextPositionInfo var2 = this.positionForPoint(var3._x, var3._y - 1, false);
  2000.             if (var2 != null) {
  2001.                var2.representCharacterBeforeEndOfLine();
  2002.                if (var5.isShiftKeyDown()) {
  2003.                   if (var2._absPosition == var3._absPosition && var2._absPosition > 0) {
  2004.                      this._selection.setRange(this._selection.orderedSelectionStart(), var2._absPosition - 1, (TextPositionInfo)null, false, true);
  2005.                   } else {
  2006.                      this._selection.setRange(this._selection.orderedSelectionStart(), var2._absPosition, var2, false, true);
  2007.                   }
  2008.                } else if (var3._lineNumber != 0 || var3._textRun._paragraph != this._paragraphVector.elementAt(0)) {
  2009.                   this._selection.setInsertionPoint(var2);
  2010.                }
  2011.  
  2012.                this._selectionChanged();
  2013.             }
  2014.          } else if (var5.isDownArrowKey()) {
  2015.             TextPositionInfo var14 = this._selection.orderedSelectionEndInfo();
  2016.             var14.representCharacterBeforeEndOfLine();
  2017.             TextPositionInfo var13 = this.positionForPoint(var14._x, var14._y + var14._lineHeight + 1, false);
  2018.             if (var13 != null) {
  2019.                if (var5.isShiftKeyDown()) {
  2020.                   this._selection.setRange(this._selection.orderedSelectionStart(), var13._absPosition, var13, false, false);
  2021.                } else if (var13._textRun._paragraph != var14._textRun._paragraph || var13._y != var14._y) {
  2022.                   this._selection.setInsertionPoint(var13);
  2023.                }
  2024.  
  2025.                this._selectionChanged();
  2026.             }
  2027.          } else if (var5.isHomeKey()) {
  2028.             this.selectedRange();
  2029.             TextPositionInfo var16 = this._selection.orderedSelectionEndInfo();
  2030.             Range var11 = this.lineForPosition(var16);
  2031.             TextPositionInfo var12 = this.positionInfoForIndex(var11.index);
  2032.             if (var12 != null) {
  2033.                if (var12._y != var16._y) {
  2034.                   var12.representCharacterAfterEndOfLine();
  2035.                }
  2036.  
  2037.                if (var5.isShiftKeyDown()) {
  2038.                   if (var12._absPosition != var16._absPosition) {
  2039.                      this._selection.setRange(this._selection.orderedSelectionStart(), var12._absPosition, var12, false, false);
  2040.                   }
  2041.                } else {
  2042.                   this._selection.setInsertionPoint(var12);
  2043.                }
  2044.             }
  2045.  
  2046.             this._selectionChanged();
  2047.          } else if (var5.isEndKey()) {
  2048.             this.selectedRange();
  2049.             TextPositionInfo var17 = this._selection.orderedSelectionEndInfo();
  2050.             Range var23 = this.lineForPosition(var17);
  2051.             TextPositionInfo var26 = this.positionInfoForIndex(var23.index + var23.length);
  2052.             if (var26 != null) {
  2053.                if (var26._y != var17._y) {
  2054.                   var26.representCharacterAfterEndOfLine();
  2055.                }
  2056.  
  2057.                if (var5.isShiftKeyDown()) {
  2058.                   if (var26._absPosition != var17._absPosition) {
  2059.                      this._selection.setRange(this._selection.orderedSelectionStart(), var26._absPosition, var26, false, false);
  2060.                   }
  2061.                } else {
  2062.                   this._selection.setInsertionPoint(var26);
  2063.                }
  2064.             }
  2065.  
  2066.             this._selectionChanged();
  2067.          } else if (var5.isBackspaceKey()) {
  2068.             Range var18 = new Range(this.selectedRange());
  2069.             if (this._selection.isARange()) {
  2070.                if (this._owner != null) {
  2071.                   this._owner.textWillChange(this, var18);
  2072.                }
  2073.  
  2074.                this.deleteSelection();
  2075.                if (this._owner != null) {
  2076.                   var18.length = 0;
  2077.                   this._owner.textDidChange(this, var18);
  2078.                }
  2079.             } else {
  2080.                if (this._owner != null) {
  2081.                   --var18.index;
  2082.                   var18.length = 1;
  2083.                   this._owner.textWillChange(this, var18);
  2084.                }
  2085.  
  2086.                this.fastDeleteChar(false);
  2087.                if (this._owner != null) {
  2088.                   var18.length = 0;
  2089.                   this._owner.textDidChange(this, var18);
  2090.                }
  2091.             }
  2092.          } else if (var5.isDeleteKey()) {
  2093.             Range var19 = this.selectedRange();
  2094.             if (this._selection.isARange()) {
  2095.                if (this._owner != null) {
  2096.                   this._owner.textWillChange(this, var19);
  2097.                }
  2098.  
  2099.                this.deleteSelection();
  2100.                if (this._owner != null) {
  2101.                   var19.length = 0;
  2102.                   this._owner.textDidChange(this, var19);
  2103.                }
  2104.             } else if (var19.index < this.length()) {
  2105.                var19.length = 1;
  2106.                if (this._owner != null) {
  2107.                   this._owner.textWillChange(this, var19);
  2108.                }
  2109.  
  2110.                this.fastDeleteChar(true);
  2111.                var19.length = 0;
  2112.                if (this._owner != null) {
  2113.                   this._owner.textDidChange(this, var19);
  2114.                }
  2115.             }
  2116.          } else if (var5.isPrintableKey()) {
  2117.             Range var20 = this.selectedRange();
  2118.             Range var24 = allocateRange();
  2119.             this.replaceRangeWithString(var20, "" + (char)var5.key);
  2120.             if (this._typingAttributes.count() > 0) {
  2121.                var24.index = var20.index;
  2122.                var24.length = 1;
  2123.                this.addAttributesForRangeWithoutNotification(this._typingAttributes, var24);
  2124.                this.clearTypingAttributes();
  2125.             }
  2126.  
  2127.             var24.index = var20.index + 1;
  2128.             var24.length = 0;
  2129.             this.selectRange(var24);
  2130.             recycleRange(var24);
  2131.          } else if (var5.isTabKey()) {
  2132.             Range var21 = this.selectedRange();
  2133.             Range var25 = allocateRange();
  2134.             this.replaceRangeWithString(var21, "\t");
  2135.             var25.index = var21.index + 1;
  2136.             var25.length = 0;
  2137.             this.selectRange(var25);
  2138.             recycleRange(var25);
  2139.          } else {
  2140.             var9 = false;
  2141.          }
  2142.  
  2143.          if (var9) {
  2144.             Range var22 = new Range(this._selection.orderedSelectionEnd(), 0);
  2145.             if (var22.index > 0) {
  2146.                --var22.index;
  2147.                ++var22.length;
  2148.             }
  2149.  
  2150.             this.scrollRangeToVisible(var22);
  2151.          }
  2152.  
  2153.          this._selection.enableInsertionPoint();
  2154.       }
  2155.    }
  2156.  
  2157.    private Range paragraphsRangeForRange(Range var1) {
  2158.       Range var6 = allocateRange();
  2159.       boolean var7 = false;
  2160.       int var3 = this._paragraphVector.count();
  2161.       int var5 = var1.index + var1.length;
  2162.  
  2163.       for(int var4 = 0; var4 < var3; ++var4) {
  2164.          TextParagraph var2 = (TextParagraph)this._paragraphVector.elementAt(var4);
  2165.          if (!var7 && var1.index >= var2._startChar && var1.index < var2._startChar + var2._charCount) {
  2166.             var6.index = var4;
  2167.             var7 = true;
  2168.          }
  2169.  
  2170.          if (var7 && var5 >= var2._startChar && var5 < var2._startChar + var2._charCount) {
  2171.             var6.length = var4 - var6.index + 1;
  2172.             break;
  2173.          }
  2174.       }
  2175.  
  2176.       return var6;
  2177.    }
  2178.  
  2179.    private Vector createAndReturnRunsForRange(Range var1) {
  2180.       int var13 = var1.index;
  2181.       int var14 = var1.index + var1.length;
  2182.       TextParagraph var2 = this._paragraphForIndex(var13);
  2183.       TextParagraph var3 = this._paragraphForIndex(var14);
  2184.       boolean var12 = var2 == var3;
  2185.       if (var1.length == 0) {
  2186.          TextStyleRun var16 = var2.createNewRunAt(var13);
  2187.          if (var16.charCount() > 0) {
  2188.             var16 = var2.createNewRunAt(var13);
  2189.          }
  2190.  
  2191.          Vector var18 = newVector();
  2192.          var18.addElement(var16);
  2193.          return var18;
  2194.       } else {
  2195.          TextStyleRun var5 = var2.runForCharPosition(var13);
  2196.          if (var5.rangeIndex() != var13) {
  2197.             var5 = var2.createNewRunAt(var13);
  2198.          }
  2199.  
  2200.          TextStyleRun var6 = var3.runForCharPosition(var14);
  2201.          if (var14 <= var6.rangeIndex() + var6.charCount() - 1) {
  2202.             var6 = var3.createNewRunAt(var14);
  2203.             var6 = var3.runBefore(var6);
  2204.          }
  2205.  
  2206.          if (var12) {
  2207.             if (var5 == var6) {
  2208.                Vector var20 = new Vector();
  2209.                var20.addElement(var5);
  2210.                return var20;
  2211.             } else {
  2212.                Vector var15 = var2.runsFromTo(var5, var6);
  2213.                return var15;
  2214.             }
  2215.          } else {
  2216.             Vector var7 = newVector();
  2217.             var7.addElement(var5);
  2218.             Vector var8 = var2.runsAfter(var5);
  2219.             var7.addElementsIfAbsent(var8);
  2220.             returnVector(var8);
  2221.             int var11 = this._paragraphVector.indexOfIdentical(var2) + 1;
  2222.  
  2223.             for(int var10 = this._paragraphVector.indexOfIdentical(var3); var11 < var10; ++var11) {
  2224.                TextParagraph var4 = (TextParagraph)this._paragraphVector.elementAt(var11);
  2225.                var7.addElementsIfAbsent(var4.runVector());
  2226.             }
  2227.  
  2228.             var8 = var3.runsBefore(var6);
  2229.             var8.addElement(var6);
  2230.             var7.addElementsIfAbsent(var8);
  2231.             returnVector(var8);
  2232.             return var7;
  2233.          }
  2234.       }
  2235.    }
  2236.  
  2237.    private void processSetFont(Font var1) {
  2238.       Range var2 = this.selectedRange();
  2239.       if (var2.length > 0) {
  2240.          Hashtable var3 = new Hashtable();
  2241.          var3.put("FontKey", var1);
  2242.          this.addAttributesForRange(var3, var2);
  2243.       } else {
  2244.          this.addTypingAttribute("FontKey", var1);
  2245.       }
  2246.    }
  2247.  
  2248.    private void deleteSelection(Vector var1) {
  2249.       Range var2 = this.selectedRange();
  2250.       this.deleteRange(var2, var1);
  2251.       this._selection.setRange(var2.index, var2.index);
  2252.       this._selectionChanged();
  2253.    }
  2254.  
  2255.    private void deleteRange(Range var1, Vector var2) {
  2256.       Object var3 = null;
  2257.       if (var1.length != 0) {
  2258.          Range var18 = allocateRange(var1.index, this.length() - var1.index);
  2259.          this.dirtyRange(var18);
  2260.          recycleRange(var18);
  2261.          this.notifyAttachmentsForRange(var1, false);
  2262.          TextPositionInfo var7 = this.positionInfoForIndex(var1.index);
  2263.          TextPositionInfo var8 = this.positionInfoForIndex(var1.index + var1.length);
  2264.          TextParagraph var5 = var7._textRun._paragraph;
  2265.          TextParagraph var6 = var8._textRun._paragraph;
  2266.          boolean var17 = var5 == var6;
  2267.          TextStyleRun var9 = var7._textRun;
  2268.          if (var9.rangeIndex() != var7._absPosition) {
  2269.             var9 = var5.createNewRunAt(var7._absPosition);
  2270.          }
  2271.  
  2272.          if (!var17) {
  2273.             Vector var11 = var5.runsAfter(var9);
  2274.             var5.removeRun(var9);
  2275.             var5.removeRuns(var11);
  2276.             if (var2 != null) {
  2277.                TextParagraph var19 = new TextParagraph(this);
  2278.                var19.setFormat(var5._format);
  2279.                var19.addRun(var9);
  2280.                var19.addRuns(var11);
  2281.                var2.addElement(var19);
  2282.             }
  2283.  
  2284.             var11.removeAllElements();
  2285.             returnVector(var11);
  2286.          }
  2287.  
  2288.          TextStyleRun var10 = var8._textRun;
  2289.          if (var10.rangeIndex() != var8._absPosition) {
  2290.             var10 = var6.createNewRunAt(var8._absPosition);
  2291.          }
  2292.  
  2293.          if (var17) {
  2294.             Vector var22 = var5.runsFromTo(var9, var10);
  2295.             var22.removeElement(var10);
  2296.             var5.removeRuns(var22);
  2297.             if (var2 != null) {
  2298.                TextParagraph var20 = new TextParagraph(this);
  2299.                var20.setFormat(var5._format);
  2300.                var20.addRuns(var22);
  2301.                var2.addElement(var20);
  2302.             }
  2303.  
  2304.             var22.removeAllElements();
  2305.             returnVector(var22);
  2306.          } else {
  2307.             int var12;
  2308.             int var13 = var12 = this._paragraphVector.indexOfIdentical(var5) + 1;
  2309.  
  2310.             for(int var14 = this._paragraphVector.indexOfIdentical(var6); var12 < var14; ++var12) {
  2311.                TextParagraph var4 = (TextParagraph)this._paragraphVector.removeElementAt(var13);
  2312.                if (var2 != null) {
  2313.                   var2.addElement(var4);
  2314.                }
  2315.             }
  2316.  
  2317.             Vector var23 = var6.runsBefore(var10);
  2318.             var6.removeRuns(var23);
  2319.             if (var2 != null) {
  2320.                TextParagraph var21 = new TextParagraph(this);
  2321.                var21.setFormat(var5._format);
  2322.                var21.addRuns(var23);
  2323.                var2.addElement(var21);
  2324.             }
  2325.  
  2326.             var23.removeAllElements();
  2327.             returnVector(var23);
  2328.             var5.subsumeParagraph(var6);
  2329.             this._paragraphVector.removeElement(var6);
  2330.          }
  2331.  
  2332.          if (var5.isEmpty() && !this.isOnlyParagraph(var5)) {
  2333.             this._paragraphVector.indexOfIdentical(var5);
  2334.             this._paragraphVector.removeElement(var5);
  2335.             int var15 = this.adjustCharCountsAndSpacing();
  2336.             this.sizeBy(0, var15 - super.bounds.height);
  2337.          } else {
  2338.             this.formatParagraph(var5);
  2339.          }
  2340.       }
  2341.    }
  2342.  
  2343.    private void deleteSelection() {
  2344.       this.deleteSelection((Vector)null);
  2345.    }
  2346.  
  2347.    boolean isOnlyParagraph(TextParagraph var1) {
  2348.       return this._paragraphVector.count() == 1 && this._paragraphVector.contains(var1);
  2349.    }
  2350.  
  2351.    int selectionStart() {
  2352.       return this._selection.selectionStart();
  2353.    }
  2354.  
  2355.    TextPositionInfo selectionStartInfo() {
  2356.       return this._selection.selectionStartInfo();
  2357.    }
  2358.  
  2359.    int selectionEnd() {
  2360.       return this._selection.selectionEnd();
  2361.    }
  2362.  
  2363.    TextPositionInfo selectionEndInfo() {
  2364.       return this._selection.selectionEndInfo();
  2365.    }
  2366.  
  2367.    boolean hasSelectionRange() {
  2368.       return this._selection.isARange();
  2369.    }
  2370.  
  2371.    TextParagraph lastParagraph() {
  2372.       return (TextParagraph)this._paragraphVector.lastElement();
  2373.    }
  2374.  
  2375.    char characterAt(int var1) {
  2376.       if (var1 >= 0 && var1 <= this._charCount) {
  2377.          TextParagraph var2 = this._paragraphForIndex(var1);
  2378.          if (var2 == null) {
  2379.             var2 = this.lastParagraph();
  2380.          }
  2381.  
  2382.          return var2.characterAt(var1);
  2383.       } else {
  2384.          return '\u0000';
  2385.       }
  2386.    }
  2387.  
  2388.    int _positionOfPreviousWord(int var1) {
  2389.       boolean var3 = false;
  2390.       if (var1 == 0) {
  2391.          return 0;
  2392.       } else {
  2393.          char var2 = this.characterAt(var1--);
  2394.          if (var2 == '\n') {
  2395.             return var1 + 1;
  2396.          } else {
  2397.             if (var2 != ' ' && var2 != '\t') {
  2398.                do {
  2399.                   var2 = this.characterAt(var1--);
  2400.                   var3 = var2 == ' ' || var2 == '\t' || var2 >= '!' && var2 <= '/' || var2 >= ':' && var2 <= '@' || var2 >= '[' && var2 <= '\'' || var2 >= '{' && var2 <= '~' || var2 == '\n';
  2401.                } while(var1 > -1 && !var3);
  2402.             } else {
  2403.                do {
  2404.                   var2 = this.characterAt(var1--);
  2405.                   var3 = var2 != ' ' && var2 != '\t' || var2 == '\n';
  2406.                } while(var1 > -1 && !var3);
  2407.             }
  2408.  
  2409.             return var3 ? var1 + 2 : 0;
  2410.          }
  2411.       }
  2412.    }
  2413.  
  2414.    int _positionOfNextWord(int var1) {
  2415.       boolean var4 = false;
  2416.       if (var1 >= this._charCount) {
  2417.          return this._charCount;
  2418.       } else {
  2419.          if (var1 > 0) {
  2420.             char var2 = this.characterAt(var1 - 1);
  2421.             if (var2 == '\n') {
  2422.                return var1 - 1;
  2423.             }
  2424.          }
  2425.  
  2426.          char var3 = this.characterAt(var1++);
  2427.          if (var3 != ' ' && var3 != '\t') {
  2428.             do {
  2429.                var3 = this.characterAt(var1++);
  2430.                var4 = var3 == ' ' || var3 == '\t' || var3 >= '!' && var3 <= '/' || var3 >= ':' && var3 <= '@' || var3 >= '[' && var3 <= '\'' || var3 >= '{' && var3 <= '~' || var3 == '\n';
  2431.             } while(var1 < this._charCount && !var4);
  2432.          } else {
  2433.             do {
  2434.                var3 = this.characterAt(var1++);
  2435.                var4 = var3 != ' ' && var3 != '\t' || var3 == '\n';
  2436.             } while(var1 < this._charCount && !var4);
  2437.          }
  2438.  
  2439.          return var4 ? var1 - 1 : this._charCount;
  2440.       }
  2441.    }
  2442.  
  2443.    private void hideInsertionPoint() {
  2444.       if (this.insertionPointVisible) {
  2445.          this.insertionPointVisible = false;
  2446.       }
  2447.  
  2448.    }
  2449.  
  2450.    private void showInsertionPoint() {
  2451.       if (!this.insertionPointVisible) {
  2452.          this.insertionPointVisible = true;
  2453.       }
  2454.  
  2455.    }
  2456.  
  2457.    static Rect newRect(int var0, int var1, int var2, int var3) {
  2458.       Vector var5 = _rectCache;
  2459.       synchronized(var5){}
  2460.  
  2461.       Rect var4;
  2462.       label47: {
  2463.          Rect var7;
  2464.          try {
  2465.             if (_shouldCache && !_rectCache.isEmpty()) {
  2466.                var4 = (Rect)_rectCache.removeLastElement();
  2467.                break label47;
  2468.             }
  2469.  
  2470.             var7 = new Rect(var0, var1, var2, var3);
  2471.          } catch (Throwable var9) {
  2472.             throw var9;
  2473.          }
  2474.  
  2475.          return var7;
  2476.       }
  2477.  
  2478.       var4.setBounds(var0, var1, var2, var3);
  2479.       return var4;
  2480.    }
  2481.  
  2482.    static Rect newRect(Rect var0) {
  2483.       Vector var2 = _rectCache;
  2484.       synchronized(var2){}
  2485.  
  2486.       Rect var1;
  2487.       label47: {
  2488.          Rect var4;
  2489.          try {
  2490.             if (_shouldCache && !_rectCache.isEmpty()) {
  2491.                var1 = (Rect)_rectCache.removeLastElement();
  2492.                break label47;
  2493.             }
  2494.  
  2495.             var4 = new Rect(var0);
  2496.          } catch (Throwable var6) {
  2497.             throw var6;
  2498.          }
  2499.  
  2500.          return var4;
  2501.       }
  2502.  
  2503.       var1.setBounds(var0);
  2504.       return var1;
  2505.    }
  2506.  
  2507.    static Rect newRect() {
  2508.       return newRect(0, 0, 0, 0);
  2509.    }
  2510.  
  2511.    static void returnRect(Rect var0) {
  2512.       if (var0 != null) {
  2513.          if (_shouldCache) {
  2514.             Vector var1 = _rectCache;
  2515.             synchronized(var1){}
  2516.  
  2517.             try {
  2518.                if (_rectCache.count() < 50) {
  2519.                   _rectCache.addElement(var0);
  2520.                }
  2521.             } catch (Throwable var3) {
  2522.                throw var3;
  2523.             }
  2524.  
  2525.          }
  2526.       }
  2527.    }
  2528.  
  2529.    static void returnRects(Vector var0) {
  2530.       if (var0 != null && _shouldCache) {
  2531.          int var1 = var0.count();
  2532.  
  2533.          while(var1-- > 0) {
  2534.             returnRect((Rect)var0.elementAt(var1));
  2535.          }
  2536.  
  2537.          var0.removeAllElements();
  2538.       }
  2539.    }
  2540.  
  2541.    static void setShouldCacheRects(boolean var0) {
  2542.       Vector var1 = _rectCache;
  2543.       synchronized(var1){}
  2544.  
  2545.       try {
  2546.          _shouldCache = var0;
  2547.          if (!_shouldCache) {
  2548.             _rectCache.removeAllElements();
  2549.          }
  2550.       } catch (Throwable var3) {
  2551.          throw var3;
  2552.       }
  2553.  
  2554.    }
  2555.  
  2556.    static Vector newVector() {
  2557.       Vector var1 = _vectorCache;
  2558.       synchronized(var1){}
  2559.  
  2560.       Vector var3;
  2561.       try {
  2562.          if (_shouldCache && !_vectorCache.isEmpty()) {
  2563.             Vector var0 = (Vector)_vectorCache.removeLastElement();
  2564.             return var0;
  2565.          }
  2566.  
  2567.          var3 = new Vector();
  2568.       } catch (Throwable var5) {
  2569.          throw var5;
  2570.       }
  2571.  
  2572.       return var3;
  2573.    }
  2574.  
  2575.    static void returnVector(Vector var0) {
  2576.       if (_shouldCache) {
  2577.          Vector var1 = _vectorCache;
  2578.          synchronized(var1){}
  2579.  
  2580.          try {
  2581.             if (var0 != null && _vectorCache.count() < 15) {
  2582.                var0.removeAllElements();
  2583.                _vectorCache.addElement(var0);
  2584.             }
  2585.          } catch (Throwable var3) {
  2586.             throw var3;
  2587.          }
  2588.  
  2589.       }
  2590.    }
  2591.  
  2592.    static void setShouldCacheVectors(boolean var0) {
  2593.       Vector var1 = _vectorCache;
  2594.       synchronized(var1){}
  2595.  
  2596.       try {
  2597.          _shouldCache = var0;
  2598.          if (!_cacheVectors) {
  2599.             _vectorCache.removeAllElements();
  2600.          }
  2601.       } catch (Throwable var3) {
  2602.          throw var3;
  2603.       }
  2604.  
  2605.    }
  2606.  
  2607.    private void _selectionChanged() {
  2608.       int var1 = this._selection.selectionStart();
  2609.       int var2 = this._selection.selectionEnd();
  2610.       if (var1 != this._wasSelectedRange.index || var2 - var1 != this._wasSelectedRange.length) {
  2611.          this._wasSelectedRange.index = var1;
  2612.          this._wasSelectedRange.length = var2 - var1;
  2613.          this.clearTypingAttributes();
  2614.          if (this._owner != null) {
  2615.             this._owner.selectionDidChange(this);
  2616.          }
  2617.  
  2618.       }
  2619.    }
  2620.  
  2621.    void dirtyRange(Range var1) {
  2622.       if (!((View)this).isDirty() || super.dirtyRect != null) {
  2623.          Range var2 = allocateRange(var1);
  2624.          Rect var3 = new Rect();
  2625.          ((View)this).computeVisibleRect(var3);
  2626.          var2.intersectWith(0, this.length());
  2627.          if (super._superview != null && var2 != null && !var2.isNullRange() && var2.length > 0) {
  2628.             Vector var5 = this.rectsForRange(var2, var3);
  2629.             int var6 = 0;
  2630.  
  2631.             for(int var7 = var5.count(); var6 < var7; ++var6) {
  2632.                Rect var4 = (Rect)var5.elementAt(var6);
  2633.                var4.x = 0;
  2634.                var4.width = super.bounds.width;
  2635.                if (var4.width > 0 && var4.height > 0) {
  2636.                   ((View)this).addDirtyRect(var4);
  2637.                }
  2638.             }
  2639.          }
  2640.  
  2641.          recycleRange(var2);
  2642.       }
  2643.    }
  2644.  
  2645.    private TextParagraphFormat _formatForTextPositionInfo(TextPositionInfo var1) {
  2646.       TextParagraphFormat var2 = var1._textRun.paragraph().format();
  2647.       if (var2 == null) {
  2648.          var2 = (TextParagraphFormat)this._defaultAttributes.get("ParagraphFormatKey");
  2649.       }
  2650.  
  2651.       return var2;
  2652.    }
  2653.  
  2654.    private TextPositionInfo positionInfoForNextLine(TextPositionInfo var1) {
  2655.       int var3 = var1._textRun.paragraph().characterStartingLine(var1._lineNumber + 1);
  2656.       if (var3 == -1) {
  2657.          int var4 = this._paragraphVector.indexOfIdentical(var1._textRun.paragraph()) + 1;
  2658.          if (var4 < this._paragraphVector.count()) {
  2659.             TextParagraph var5 = (TextParagraph)this._paragraphVector.elementAt(var4);
  2660.             return this.positionInfoForIndex(var5._startChar);
  2661.          } else {
  2662.             return null;
  2663.          }
  2664.       } else {
  2665.          TextPositionInfo var2 = this.positionInfoForIndex(var3);
  2666.          return var2;
  2667.       }
  2668.    }
  2669.  
  2670.    void setBaseURL(URL var1) {
  2671.       this._baseURL = var1;
  2672.    }
  2673.  
  2674.    private TextStyleRun runBefore(TextStyleRun var1) {
  2675.       TextStyleRun var2 = var1.paragraph().runBefore(var1);
  2676.       if (var2 == null) {
  2677.          int var3 = this._paragraphVector.indexOfIdentical(var1.paragraph());
  2678.          if (var3 > 0) {
  2679.             return ((TextParagraph)this._paragraphVector.elementAt(var3 - 1)).lastRun();
  2680.          }
  2681.       }
  2682.  
  2683.       return var2;
  2684.    }
  2685.  
  2686.    private TextStyleRun runAfter(TextStyleRun var1) {
  2687.       TextStyleRun var2 = var1.paragraph().runAfter(var1);
  2688.       if (var2 == null) {
  2689.          int var3 = this._paragraphVector.indexOfIdentical(var1.paragraph());
  2690.          if (var3 < this._paragraphVector.count() - 1) {
  2691.             return ((TextParagraph)this._paragraphVector.elementAt(var3 + 1)).firstRun();
  2692.          }
  2693.       }
  2694.  
  2695.       return var2;
  2696.    }
  2697.  
  2698.    private Range linkRangeForPosition(int var1) {
  2699.       TextStyleRun var3 = this._runForIndex(var1);
  2700.       Hashtable var6;
  2701.       String var7;
  2702.       if ((var6 = var3.attributes()) != null && (var7 = (String)var6.get("LinkKey")) != null) {
  2703.          TextStyleRun var4 = var3;
  2704.          TextStyleRun var2 = var3;
  2705.  
  2706.          while(true) {
  2707.             var2 = this.runBefore(var2);
  2708.             if (var2 == null || (var6 = var2.attributes()) == null || !var7.equals((String)var6.get("LinkKey"))) {
  2709.                TextStyleRun var5 = var3;
  2710.                var2 = var3;
  2711.  
  2712.                while(true) {
  2713.                   var2 = this.runAfter(var2);
  2714.                   if (var2 == null || (var6 = var2.attributes()) == null || !var7.equals((String)var6.get("LinkKey"))) {
  2715.                      Range var8 = var4.range();
  2716.                      var8.unionWith(var5.range());
  2717.                      return var8;
  2718.                   }
  2719.  
  2720.                   var5 = var2;
  2721.                }
  2722.             }
  2723.  
  2724.             var4 = var2;
  2725.          }
  2726.       } else {
  2727.          return null;
  2728.       }
  2729.    }
  2730.  
  2731.    private void highlightLinkWithRange(Range var1, boolean var2) {
  2732.       if (var2) {
  2733.          this.addAttributeForRange("_IFCLinkPressedKey", "", var1);
  2734.       } else {
  2735.          this.removeAttributeForRange("_IFCLinkPressedKey", var1);
  2736.       }
  2737.  
  2738.       Range var3 = this.paragraphsRangeForRange(var1);
  2739.       int var4 = var3.index;
  2740.  
  2741.       for(int var5 = var3.index + var3.length; var4 < var5; ++var4) {
  2742.          ((TextParagraph)this._paragraphVector.elementAt(var4)).collectEmptyRuns();
  2743.       }
  2744.  
  2745.    }
  2746.  
  2747.    private boolean runUnderMouse(TextStyleRun var1, int var2, int var3) {
  2748.       Vector var6 = this.rectsForRange(var1.range());
  2749.       int var4 = 0;
  2750.  
  2751.       for(int var5 = var6.count(); var4 < var5; ++var4) {
  2752.          if (((Rect)var6.elementAt(var4)).contains(var2, var3)) {
  2753.             return true;
  2754.          }
  2755.       }
  2756.  
  2757.       return false;
  2758.    }
  2759.  
  2760.    private boolean runsUnderMouse(Vector var1, int var2, int var3) {
  2761.       int var4 = 0;
  2762.  
  2763.       for(int var5 = var1.count(); var4 < var5; ++var4) {
  2764.          Range var6 = (Range)var1.elementAt(var4);
  2765.          TextStyleRun var7 = this._runForIndex(var6.index);
  2766.          if (this.runUnderMouse(var7, var2, var3)) {
  2767.             return true;
  2768.          }
  2769.       }
  2770.  
  2771.       return false;
  2772.    }
  2773.  
  2774.    boolean lastParagraphIsEmpty() {
  2775.       return this.lastParagraph()._charCount == 0;
  2776.    }
  2777.  
  2778.    char charAt(int var1) {
  2779.       String var2 = this.stringForRange(new Range(var1, 1));
  2780.       return var2 != null && var2.length() > 0 ? var2.charAt(0) : '\u0000';
  2781.    }
  2782.  
  2783.    boolean isWordCharacter(char var1) {
  2784.       return var1 >= '0' && var1 <= '9' || var1 >= 'A' && var1 <= 'Z' || var1 >= 'a' && var1 <= 'z';
  2785.    }
  2786.  
  2787.    Range groupForIndex(int var1) {
  2788.       int var2 = this.length();
  2789.       int var5 = var1;
  2790.       char var6 = this.charAt(var1);
  2791.       if (var6 == '\n') {
  2792.          return new Range(var1, 1);
  2793.       } else if (var6 != ' ' && var6 != '\t') {
  2794.          if (!this.isWordCharacter(var6)) {
  2795.             return new Range(var1, 1);
  2796.          } else {
  2797.             int var7;
  2798.             for(var7 = var1; var7 > 0; --var7) {
  2799.                var6 = this.charAt(var7 - 1);
  2800.                if (!this.isWordCharacter(var6)) {
  2801.                   break;
  2802.                }
  2803.             }
  2804.  
  2805.             int var8;
  2806.             for(var8 = var1; var8 < var2 - 1; ++var8) {
  2807.                var6 = this.charAt(var8 + 1);
  2808.                if (!this.isWordCharacter(var6)) {
  2809.                   break;
  2810.                }
  2811.             }
  2812.  
  2813.             return new Range(var7, var8 - var7 + 1);
  2814.          }
  2815.       } else {
  2816.          while(var5 > 0) {
  2817.             var6 = this.charAt(var5);
  2818.             if (var6 != ' ' && var6 != '\t') {
  2819.                break;
  2820.             }
  2821.  
  2822.             --var5;
  2823.          }
  2824.  
  2825.          int var3 = var5 + 1;
  2826.  
  2827.          for(var5 = var1; var5 < this.length(); ++var5) {
  2828.             var6 = this.charAt(var5);
  2829.             if (var6 != ' ' && var6 != '\t') {
  2830.                break;
  2831.             }
  2832.          }
  2833.  
  2834.          int var4 = var5 - 1;
  2835.          return new Range(var3, var4 - var3 + 1);
  2836.       }
  2837.    }
  2838.  
  2839.    Range lineForPosition(TextPositionInfo var1) {
  2840.       TextParagraph var2 = var1._textRun._paragraph;
  2841.       if (var2 != null) {
  2842.          int var3;
  2843.          if (var1._lineNumber == 0) {
  2844.             var3 = var2._startChar;
  2845.          } else {
  2846.             var3 = var2._startChar + var2._lineBreaks[var1._lineNumber - 1];
  2847.          }
  2848.  
  2849.          int var4 = var2._startChar + var2._lineBreaks[var1._lineNumber] - 1;
  2850.          return new Range(var3, var4 - var3 + 1);
  2851.       } else {
  2852.          return new Range();
  2853.       }
  2854.    }
  2855.  
  2856.    void replaceContentWithString(String var1) {
  2857.       this.notifyAttachmentsForRange(new Range(0, this.length()), false);
  2858.       this._paragraphVector.removeAllElements();
  2859.       int var4 = 0;
  2860.       int var5 = var1.length();
  2861.  
  2862.       while(var4 < var5) {
  2863.          int var6 = var1.indexOf(10, var4);
  2864.          int var7;
  2865.          int var8;
  2866.          if (var6 == -1) {
  2867.             var7 = var4;
  2868.             var8 = var5;
  2869.             var4 = var5;
  2870.          } else {
  2871.             var7 = var4;
  2872.             var8 = var6;
  2873.             var4 = var6 + 1;
  2874.          }
  2875.  
  2876.          TextParagraph var2 = new TextParagraph(this);
  2877.          TextStyleRun var3 = new TextStyleRun(var2, var1, var7, var8, (Hashtable)null);
  2878.          var2.addRun(var3);
  2879.          this._paragraphVector.addElement(var2);
  2880.       }
  2881.  
  2882.       if (this._paragraphVector.count() == 0 || var1.charAt(var5 - 1) == '\n') {
  2883.          TextParagraph var9 = new TextParagraph(this);
  2884.          TextStyleRun var10 = new TextStyleRun(var9, "", (Hashtable)null);
  2885.          var9.addRun(var10);
  2886.          this._paragraphVector.addElement(var9);
  2887.       }
  2888.  
  2889.       ((View)this).setDirty(true);
  2890.       this.reformatAll();
  2891.    }
  2892.  
  2893.    Vector rectsForRange(Range var1, Rect var2) {
  2894.       Range var3 = allocateRange(var1.index, var1.length);
  2895.       Vector var4 = new Vector();
  2896.       var3.intersectWith(0, this.length());
  2897.       if (var3.length != 0 && !var3.isNullRange()) {
  2898.          TextPositionInfo var5 = this.positionInfoForIndex(var3.index);
  2899.          if (var5._endOfLine && !var5._endOfParagraph) {
  2900.             var5.representCharacterAfterEndOfLine();
  2901.          }
  2902.  
  2903.          TextPositionInfo var6 = this.positionInfoForIndex(var3.index + var3.length());
  2904.          if (var5 != null && var6 != null) {
  2905.             if (var5._textRun.paragraph() == var6._textRun.paragraph() && var5._lineNumber == var6._lineNumber) {
  2906.                TextParagraphFormat var16 = this._formatForTextPositionInfo(var5);
  2907.                if (var6._endOfLine) {
  2908.                   TextParagraph var20 = var5._textRun.paragraph();
  2909.                   int var22 = var20._lineRemainders[var5._lineNumber];
  2910.                   switch (var16._justification) {
  2911.                      case 0:
  2912.                      default:
  2913.                         var4.addElement(new Rect(var5._x, var5._y, super.bounds.width - var16._rightMargin - var5._x - var22, var5._lineHeight));
  2914.                         break;
  2915.                      case 1:
  2916.                         var4.addElement(new Rect(var5._x, var5._y, super.bounds.width - var16._rightMargin - var5._x - var22 / 2, var5._lineHeight));
  2917.                         break;
  2918.                      case 2:
  2919.                         var4.addElement(new Rect(var5._x, var5._y, super.bounds.width - var16._rightMargin - var5._x, var5._lineHeight));
  2920.                   }
  2921.                } else {
  2922.                   var4.addElement(new Rect(var5._x, var5._y, var6._x - var5._x, var5._lineHeight));
  2923.                }
  2924.  
  2925.                recycleRange(var3);
  2926.                return var4;
  2927.             } else {
  2928.                TextParagraphFormat var8 = this._formatForTextPositionInfo(var5);
  2929.                TextParagraph var13 = var5._textRun.paragraph();
  2930.                int var14 = var13._lineRemainders[var5._lineNumber];
  2931.                Rect var9;
  2932.                switch (var8._justification) {
  2933.                   case 0:
  2934.                   default:
  2935.                      var9 = new Rect(var5._x, var5._y, super.bounds.width - var8._rightMargin - var5._x - var14, var5._lineHeight);
  2936.                      break;
  2937.                   case 1:
  2938.                      var9 = new Rect(var5._x, var5._y, super.bounds.width - var8._rightMargin - var5._x - var14 / 2, var5._lineHeight);
  2939.                      break;
  2940.                   case 2:
  2941.                      var9 = new Rect(var5._x, var5._y, super.bounds.width - var8._rightMargin - var5._x, var5._lineHeight);
  2942.                }
  2943.  
  2944.                if (var9.height > 0) {
  2945.                   var4.addElement(var9);
  2946.                }
  2947.  
  2948.                var9 = new Rect(0, 0, 0, 0);
  2949.                TextPositionInfo var7 = var5;
  2950.                boolean var12 = false;
  2951.                int var11 = -1;
  2952.  
  2953.                while(!var12) {
  2954.                   var7 = this.positionInfoForNextLine(var7);
  2955.                   if (var7 == null) {
  2956.                      break;
  2957.                   }
  2958.  
  2959.                   if (var7._endOfLine && !var7._endOfParagraph) {
  2960.                      var7.representCharacterAfterEndOfLine();
  2961.                   }
  2962.  
  2963.                   if (var7._y <= var11) {
  2964.                      break;
  2965.                   }
  2966.  
  2967.                   var11 = var7._y;
  2968.                   if (var2 != null) {
  2969.                      if (var7._y < var2.y) {
  2970.                         continue;
  2971.                      }
  2972.  
  2973.                      if (var7._y > var2.y + var2.height) {
  2974.                         var12 = true;
  2975.                         break;
  2976.                      }
  2977.                   }
  2978.  
  2979.                   var8 = this._formatForTextPositionInfo(var7);
  2980.                   if (var7._textRun.paragraph() == var6._textRun.paragraph() && var7._lineNumber >= var6._lineNumber) {
  2981.                      var9.x = var7._x;
  2982.                      var9.y = var7._y;
  2983.                      var9.width = var6._x - var9.x;
  2984.                      var9.height = var7._lineHeight;
  2985.                      var12 = true;
  2986.                   } else {
  2987.                      var9.x = var7._x;
  2988.                      var9.y = var7._y;
  2989.                      var13 = var7._textRun.paragraph();
  2990.                      var14 = var13._lineRemainders[var7._lineNumber];
  2991.                      switch (var8._justification) {
  2992.                         case 0:
  2993.                         default:
  2994.                            var9.width = super.bounds.width - var8._rightMargin - var9.x - var14;
  2995.                            break;
  2996.                         case 1:
  2997.                            var9.width = super.bounds.width - var8._rightMargin - var9.x - var14 / 2;
  2998.                            break;
  2999.                         case 2:
  3000.                            var9.width = super.bounds.width - var8._rightMargin - var9.x;
  3001.                      }
  3002.  
  3003.                      var9.height = var7._lineHeight;
  3004.                   }
  3005.  
  3006.                   if (var9.height > 0) {
  3007.                      Rect var10 = (Rect)var4.lastElement();
  3008.                      if (var10 != null && var10.x == var9.x && var10.width == var9.width) {
  3009.                         var10.height = var9.y + var9.height - var10.y;
  3010.                      } else {
  3011.                         var4.addElement(new Rect(var9));
  3012.                      }
  3013.                   }
  3014.                }
  3015.  
  3016.                recycleRange(var3);
  3017.                return var4;
  3018.             }
  3019.          } else {
  3020.             recycleRange(var3);
  3021.             return var4;
  3022.          }
  3023.       } else {
  3024.          recycleRange(var3);
  3025.          return var4;
  3026.       }
  3027.    }
  3028.  
  3029.    Vector rangesOfVisibleAttachmentsWithBitmap(Bitmap var1) {
  3030.       Vector var2 = new Vector();
  3031.       Rect var7 = new Rect();
  3032.       ((View)this).computeVisibleRect(var7);
  3033.       TextPositionInfo var3 = this.positionForPoint(var7.x, var7.y, true);
  3034.       int var5;
  3035.       if (var3 == null) {
  3036.          var5 = 0;
  3037.       } else if (var3._absPosition > 0) {
  3038.          var5 = var3._absPosition - 1;
  3039.       } else {
  3040.          var5 = 0;
  3041.       }
  3042.  
  3043.       var3 = this.positionForPoint(var7.x + var7.width, var7.y + var7.height, true);
  3044.       int var6;
  3045.       if (var3 == null) {
  3046.          var6 = this.length() - 1;
  3047.       } else if (var3._absPosition < this.length() - 1) {
  3048.          var6 = var3._absPosition + 1;
  3049.       } else {
  3050.          var6 = this.length() - 1;
  3051.       }
  3052.  
  3053.       TextStyleRun var4 = this._runForIndex(var5);
  3054.  
  3055.       while(var4 != null) {
  3056.          Hashtable var8 = var4.attributes();
  3057.          TextAttachment var9;
  3058.          if (var8 != null && (var9 = (TextAttachment)var8.get("TextAttachmentKey")) != null && var9 instanceof ImageAttachment && ((ImageAttachment)var9).image() == var1) {
  3059.             var2.addElement(var4.range());
  3060.          }
  3061.  
  3062.          var4 = this.runAfter(var4);
  3063.          if (var4.rangeIndex() > var6) {
  3064.             break;
  3065.          }
  3066.       }
  3067.  
  3068.       return var2;
  3069.    }
  3070.  
  3071.    void refreshBitmap(Object var1) {
  3072.       Bitmap var3 = (Bitmap)var1;
  3073.       Vector var2 = this.rangesOfVisibleAttachmentsWithBitmap(var3);
  3074.       int var9 = 0;
  3075.  
  3076.       for(int var10 = var2.count(); var9 < var10; ++var9) {
  3077.          Range var4 = (Range)var2.elementAt(var9);
  3078.          if (!var4.isNullRange()) {
  3079.             Vector var11 = this.rectsForRange(var4);
  3080.             Rect var5 = var3.updateRect();
  3081.             if (var11.count() > 0) {
  3082.                Rect var6 = (Rect)var11.elementAt(0);
  3083.                int var7 = 1;
  3084.  
  3085.                for(int var8 = var11.count(); var7 < var8; ++var7) {
  3086.                   var6.unionWith((Rect)var11.elementAt(var7));
  3087.                }
  3088.  
  3089.                var6.x = 0;
  3090.                var6.width = super.bounds.width;
  3091.                var6.y += var5.y;
  3092.                var6.height = var5.height;
  3093.                ((View)this).addDirtyRect(var6);
  3094.             }
  3095.          }
  3096.       }
  3097.  
  3098.    }
  3099.  
  3100.    boolean attributesChangingFormatting(Hashtable var1) {
  3101.       if (var1 != null) {
  3102.          Vector var4 = var1.keysVector();
  3103.          int var2 = 0;
  3104.  
  3105.          for(int var3 = var4.count(); var2 < var3; ++var2) {
  3106.             if (attributesChangingFormatting.indexOf(var4.elementAt(var2)) != -1) {
  3107.                return true;
  3108.             }
  3109.          }
  3110.       }
  3111.  
  3112.       return false;
  3113.    }
  3114.  
  3115.    void clearTypingAttributes() {
  3116.       if (this._typingAttributes != null) {
  3117.          this._typingAttributes.clear();
  3118.       }
  3119.  
  3120.    }
  3121.  
  3122.    void addAttributesForRangeWithoutNotification(Hashtable var1, Range var2) {
  3123.       Range var11 = this.selectedRange();
  3124.       Range var12 = allocateRange();
  3125.       Vector var13 = new Vector();
  3126.       if (var1 == null) {
  3127.          recycleRange(var12);
  3128.       } else {
  3129.          TextAttachment var14;
  3130.          if ((var14 = (TextAttachment)var1.get("TextAttachmentKey")) != null) {
  3131.             var14.setOwner(this);
  3132.          }
  3133.  
  3134.          TextParagraphFormat var6;
  3135.          if ((var6 = (TextParagraphFormat)var1.get("ParagraphFormatKey")) != null) {
  3136.             Range var3 = this.paragraphsRangeForRange(var2);
  3137.             int var8 = var3.index;
  3138.  
  3139.             for(int var9 = var3.index + var3.length; var8 < var9; ++var8) {
  3140.                TextParagraph var7 = (TextParagraph)this._paragraphVector.elementAt(var8);
  3141.                var7.setFormat(var6);
  3142.                var13.addElementIfAbsent(var7);
  3143.                var12.unionWith(var7.range());
  3144.             }
  3145.  
  3146.             if (var1.count() == 1) {
  3147.                var8 = 0;
  3148.  
  3149.                for(int var29 = var13.count(); var8 < var29; ++var8) {
  3150.                   this.formatParagraph((TextParagraph)var13.elementAt(var8));
  3151.                }
  3152.  
  3153.                this.dirtyRange(var12);
  3154.                if (this.formattingEnabled()) {
  3155.                   this._selection.setRange(var11.index, var11.index + var11.length);
  3156.                }
  3157.  
  3158.                recycleRange(var12);
  3159.                recycleRange(var3);
  3160.                return;
  3161.             }
  3162.  
  3163.             recycleRange(var3);
  3164.          }
  3165.  
  3166.          TextStyleRun var5 = this._runForIndex(var2.index);
  3167.          if (var5 != null) {
  3168.             Range var10 = var5.range();
  3169.             if (var2.equals(var10)) {
  3170.                var5.appendAttributes(var1);
  3171.                var12.unionWith(var5.range());
  3172.                if (this.attributesChangingFormatting(var1)) {
  3173.                   var13.addElementIfAbsent(this._paragraphForIndex(var2.index));
  3174.                }
  3175.  
  3176.                int var23 = 0;
  3177.  
  3178.                for(int var28 = var13.count(); var23 < var28; ++var23) {
  3179.                   TextParagraph var19 = (TextParagraph)var13.elementAt(var23);
  3180.                   this.formatParagraph(var19);
  3181.                   var12.unionWith(var19.range());
  3182.                }
  3183.  
  3184.                this.dirtyRange(var12);
  3185.                if (this.formattingEnabled()) {
  3186.                   this._selection.setRange(var11.index, var11.index + var11.length);
  3187.                }
  3188.  
  3189.                recycleRange(var12);
  3190.                recycleRange(var10);
  3191.                return;
  3192.             }
  3193.  
  3194.             if (var2.index >= var10.index && var2.index + var2.length <= var10.index + var10.length && this.equalsAttributesHint(var1, var5.attributes())) {
  3195.                recycleRange(var12);
  3196.                recycleRange(var10);
  3197.                return;
  3198.             }
  3199.          }
  3200.  
  3201.          Vector var4 = this.createAndReturnRunsForRange(var2);
  3202.          int var20 = 0;
  3203.  
  3204.          for(int var25 = var4.count(); var20 < var25; ++var20) {
  3205.             var5 = (TextStyleRun)var4.elementAt(var20);
  3206.             var5.appendAttributes(var1);
  3207.             Range var30 = var5.range();
  3208.             var12.unionWith(var30);
  3209.             recycleRange(var30);
  3210.          }
  3211.  
  3212.          if (this.attributesChangingFormatting(var1)) {
  3213.             Range var16 = this.paragraphsRangeForRange(var2);
  3214.             var20 = var16.index;
  3215.  
  3216.             for(int var26 = var16.index + var16.length; var20 < var26; ++var20) {
  3217.                var13.addElementIfAbsent(this._paragraphVector.elementAt(var20));
  3218.             }
  3219.  
  3220.             recycleRange(var16);
  3221.          }
  3222.  
  3223.          var20 = 0;
  3224.  
  3225.          for(int var27 = var13.count(); var20 < var27; ++var20) {
  3226.             TextParagraph var18 = (TextParagraph)var13.elementAt(var20);
  3227.             this.formatParagraph(var18);
  3228.             Range var15 = var18.range();
  3229.             var12.unionWith(var15);
  3230.             recycleRange(var15);
  3231.          }
  3232.  
  3233.          this.dirtyRange(var12);
  3234.          if (this.formattingEnabled()) {
  3235.             this._selection.setRange(var11.index, var11.index + var11.length);
  3236.          }
  3237.  
  3238.          recycleRange(var12);
  3239.       }
  3240.    }
  3241.  
  3242.    void validateHTMLParsingRules() {
  3243.       if (this._htmlParsingRules == null) {
  3244.          String[] var3 = new String[]{"BODY", "H1", "H2", "H3", "H4", "H5", "H6", "B", "STRONG", "CENTER", "EM", "I", "PRE", "A", "OL", "UL", "LI", "ADDRESS", "BLOCKQUOTE", "DIR", "MENU", "TT", "SAMP", "CODE", "KBD", "VAR", "CITE", "DL", "DT", "DD", "TITLE", "P"};
  3245.          String[] var4 = new String[]{"BR", "HR", "IMG"};
  3246.          this._htmlParsingRules = new HTMLParsingRules();
  3247.          int var1 = 0;
  3248.  
  3249.          for(int var2 = var3.length; var1 < var2; ++var1) {
  3250.             this._htmlParsingRules.setClassNameForMarker("netscape.application.TextViewHTMLContainerImp", var3[var1]);
  3251.          }
  3252.  
  3253.          var1 = 0;
  3254.  
  3255.          for(int var6 = var4.length; var1 < var6; ++var1) {
  3256.             this._htmlParsingRules.setClassNameForMarker("netscape.application.TextViewHTMLMarkerImp", var4[var1]);
  3257.          }
  3258.  
  3259.          this._htmlParsingRules.setStringClassName("netscape.application.TextViewHTMLString");
  3260.       }
  3261.  
  3262.    }
  3263.  
  3264.    void disableAttachmentNotification() {
  3265.       ++this.notifyAttachmentDisabled;
  3266.    }
  3267.  
  3268.    void enableAttachmentNotification() {
  3269.       --this.notifyAttachmentDisabled;
  3270.       if (this.notifyAttachmentDisabled < 0) {
  3271.          this.notifyAttachmentDisabled = 0;
  3272.       }
  3273.  
  3274.       if (this.notifyAttachmentDisabled == 0 && this.invalidAttachmentRange != null) {
  3275.          this.notifyAttachmentsForRange(this.invalidAttachmentRange, true);
  3276.          this.invalidAttachmentRange = null;
  3277.       }
  3278.  
  3279.    }
  3280.  
  3281.    void _notifyAttachmentsForRange(Range var1, boolean var2) {
  3282.       int var3 = this._paragraphIndexForIndex(var1.index);
  3283.       int var7 = var1.index;
  3284.       int var8 = var1.index + var1.length;
  3285.       if (var3 != -1) {
  3286.          TextParagraph var5 = (TextParagraph)this._paragraphVector.elementAt(var3);
  3287.          int var4 = var5.runIndexForCharPosition(var7);
  3288.          if (var4 != -1) {
  3289.             TextStyleRun var6 = (TextStyleRun)var5._runVector.elementAt(var4);
  3290.             var7 = var6.rangeIndex();
  3291.  
  3292.             while(var7 < var8) {
  3293.                Hashtable var9 = var6.attributes();
  3294.                TextAttachment var10;
  3295.                if (var9 != null && (var10 = (TextAttachment)var9.get("TextAttachmentKey")) != null) {
  3296.                   if (var2) {
  3297.                      TextPositionInfo var11 = var6._paragraph._infoForPosition(var6.rangeIndex());
  3298.                      if (var11 != null) {
  3299.                         var11.representCharacterAfterEndOfLine();
  3300.                         Rect var12 = var6.textAttachmentBoundsForOrigin(var11._x, var11._y, var6._paragraph._baselines[var11._lineNumber]);
  3301.                         var10._willShowWithBounds(var12);
  3302.                      }
  3303.                   } else {
  3304.                      var10._willHide();
  3305.                   }
  3306.                }
  3307.  
  3308.                var7 += var6.charCount();
  3309.                ++var4;
  3310.                if (var4 < var5._runVector.count()) {
  3311.                   var6 = (TextStyleRun)var5._runVector.elementAt(var4);
  3312.                } else {
  3313.                   ++var3;
  3314.                   ++var7;
  3315.                   if (var3 >= this._paragraphVector.count()) {
  3316.                      break;
  3317.                   }
  3318.  
  3319.                   var5 = (TextParagraph)this._paragraphVector.elementAt(var3);
  3320.                   var4 = 0;
  3321.                   if (var5._runVector.count() <= 0) {
  3322.                      break;
  3323.                   }
  3324.  
  3325.                   var6 = (TextStyleRun)var5._runVector.elementAt(var4);
  3326.                }
  3327.             }
  3328.  
  3329.          }
  3330.       }
  3331.    }
  3332.  
  3333.    void notifyAttachmentsForRange(Range var1, boolean var2) {
  3334.       if (!var2) {
  3335.          this._notifyAttachmentsForRange(var1, false);
  3336.       } else if (this.notifyAttachmentDisabled > 0) {
  3337.          if (this.invalidAttachmentRange != null) {
  3338.             this.invalidAttachmentRange.unionWith(var1);
  3339.          } else {
  3340.             this.invalidAttachmentRange = new Range(var1);
  3341.          }
  3342.       } else {
  3343.          this._notifyAttachmentsForRange(var1, true);
  3344.       }
  3345.    }
  3346.  
  3347.    boolean isLeftHalfOfCharacter(int var1, int var2) {
  3348.       TextPositionInfo var3 = this.positionForPoint(var1, var2, false);
  3349.       TextPositionInfo var4 = this.positionForPoint(var1, var2, true);
  3350.       if (var3 != null && var4 != null) {
  3351.          return var3._absPosition == var4._absPosition;
  3352.       } else {
  3353.          return true;
  3354.       }
  3355.    }
  3356.  
  3357.    static Range allocateRange() {
  3358.       return allocateRange(Range.nullRange().index, Range.nullRange().length);
  3359.    }
  3360.  
  3361.    static Range allocateRange(Range var0) {
  3362.       return allocateRange(var0.index, var0.length);
  3363.    }
  3364.  
  3365.    static Range allocateRange(int var0, int var1) {
  3366.       Range var2 = (Range)rangePool.allocateObject();
  3367.       var2.index = var0;
  3368.       var2.length = var1;
  3369.       return var2;
  3370.    }
  3371.  
  3372.    static void recycleRange(Range var0) {
  3373.       rangePool.recycleObject(var0);
  3374.    }
  3375.  
  3376.    public void copy() {
  3377.       Application.setClipboardText(this.stringForRange(this.selectedRange()));
  3378.    }
  3379.  
  3380.    public void cut() {
  3381.       if (this.isEditable()) {
  3382.          Range var1 = this.selectedRange();
  3383.          Application.setClipboardText(this.stringForRange(var1));
  3384.          this.replaceRangeWithString(var1, "");
  3385.          this.selectRange(new Range(var1.index(), 0));
  3386.       }
  3387.  
  3388.    }
  3389.  
  3390.    public void paste() {
  3391.       if (this.isEditable()) {
  3392.          Range var1 = this.selectedRange();
  3393.          String var2 = Application.clipboardText();
  3394.          this._selection.disableInsertionPoint();
  3395.          this.replaceRangeWithString(var1, var2);
  3396.          var1 = new Range(var1.index() + var2.length(), 0);
  3397.          this.selectRange(var1);
  3398.          this.scrollRangeToVisible(var1);
  3399.          this._selection.enableInsertionPoint();
  3400.       }
  3401.  
  3402.    }
  3403.  
  3404.    public String formElementText() {
  3405.       return this.string();
  3406.    }
  3407.  
  3408.    static {
  3409.       attributesChangingFormatting.addElement("TextAttachmentKey");
  3410.       attributesChangingFormatting.addElement("TextAttachmentBaselineOffsetKey");
  3411.       attributesChangingFormatting.addElement("FontKey");
  3412.       attributesChangingFormatting.addElement("ParagraphFormatKey");
  3413.       _rectCache = new Vector();
  3414.       _vectorCache = new Vector();
  3415.       hashtablePool = new ObjectPool("netscape.util.Hashtable", 32);
  3416.       rangePool = new ObjectPool("netscape.application.Range", 32);
  3417.    }
  3418. }
  3419.