Ответ 1
Хороший вопрос. Вы можете определить смещения (и, следовательно, необходимые позиции каретки в JEditorPane
) в соответствии с несколькими правилами - вы уже упоминали наиболее важные из них.
Возможно, несколько ключевых тегов:
-
<head>
+1 -
<title>
+2 -
<meta>
+1 -
<p>
длина текста +1 (для CR)
Если вы еще не нашли его, самый простой способ увидеть этот список смещений и то, как они разбиваются, это HTMLDocument.dump(System.out);
, Например, для примера HTML выше:
<html
name=html
>
<head
name=head
>
<p-implied
name=p-implied
>
<title
name=title
>
[0,1][ ]
<title
endtag=true
name=title
>
[1,2][ ]
<content
CR=true
name=content
>
[2,3][
]
<body
name=body
>
<div
id=BOX
name=div
>
<p
name=p
>
<content
name=content
>
[3,14][Paragraph 1]
<content
CR=true
name=content
>
[14,15][
]
<p
name=p
>
<content
name=content
>
[15,26][Paragraph 2]
<content
CR=true
name=content
>
[26,27][
]
<bidi root>
<bidi level
bidiLevel=0
>
[0,27][
Paragraph 1
Paragraph 2
]
Если вам интересно углубиться, это будет означать изучение правил в логике разбора Swing для HTML. Существует множество правил для разных типов тегов - вы можете увидеть список в источнике.
Каждый тег использует класс "Action" в этой иерархии:
Например, <p>
является ParagraphAction
, а <head>
является HeadAction
, и оба они являются типами BlockAction
. A <div>
также является прямым BlockAction
.
BlockAction
может добавить этот дополнительный элемент <content CR...>
, чтобы закончить блок, следовательно, дополнительный +1 в смещении. Обычно это происходит только в том случае, если в теге есть прямой текстовый контент. Однако для <head>
подкласс HeadAction
добавляет <p-implied>
вы можете увидеть в дампе выше, что вызывает один из дополнительных смещений. (Вы не можете видеть это в этом примере, но стоит отметить, что <div>
с текстовым контентом также вставляет дополнительный <p-implied>
- для хранения текста блока).
Вещи становятся все более конкретными оттуда. Например, <title>
(вместе с <applet>
и <object>
) кажется "непустым" HiddenActions
. Это означает, что элемент вставлен как для начального, так и для концевого тегов. <meta>
хотя, например, это пустой HiddenAction
, поэтому просто получает один элемент для стартового тега.
Надеюсь, этого достаточно для объяснения того, как определить смещение для любого заданного тега. Если вы просматриваете источник для классов XxxActions
, найдите строки, такие как new ElementSpec(..., 0, 1)
- последний параметр - это длина.
Вы также указали, что пробелы игнорируются. Это, по крайней мере, нормально в разборе HTML, в браузерах тоже. Пробелы между тегами или до и после текста обычно игнорируются - сохраняется только пробел между словами. И тогда последовательности пробелов сворачиваются в одно пробелы.
Все сказанное, я все еще не понимаю, зачем нужны дополнительные смещения для <head>
и <title>
. Например, если вы используете setCaretPosition(x)
для JEditorPane
на основе doc
и htmlKit
выше, вы видите только htmlKit
, если x
равен 3 или более. Возможно, кто-то еще может пролить свет на это...