|
Lines 150-158
void ApplyBlockElementCommand::formatSel
Source/WebCore/editing/ApplyBlockElementCommand.cpp_sec1
|
| 150 |
|
150 |
|
| 151 |
static bool isNewLineAtPosition(const Position& position) |
151 |
static bool isNewLineAtPosition(const Position& position) |
| 152 |
{ |
152 |
{ |
| 153 |
if (position.anchorType() != Position::PositionIsOffsetInAnchor) |
|
|
| 154 |
return false; |
| 155 |
|
| 156 |
Node* textNode = position.containerNode(); |
153 |
Node* textNode = position.containerNode(); |
| 157 |
int offset = position.offsetInContainerNode(); |
154 |
int offset = position.offsetInContainerNode(); |
| 158 |
if (!textNode || !textNode->isTextNode() || offset < 0 || offset >= textNode->maxCharacterOffset()) |
155 |
if (!textNode || !textNode->isTextNode() || offset < 0 || offset >= textNode->maxCharacterOffset()) |
|
Lines 181-191
void ApplyBlockElementCommand::rangeForP
Source/WebCore/editing/ApplyBlockElementCommand.cpp_sec2
|
| 181 |
start = startOfParagraph(endOfCurrentParagraph).deepEquivalent(); |
178 |
start = startOfParagraph(endOfCurrentParagraph).deepEquivalent(); |
| 182 |
end = endOfCurrentParagraph.deepEquivalent(); |
179 |
end = endOfCurrentParagraph.deepEquivalent(); |
| 183 |
|
180 |
|
| 184 |
RenderStyle* startStyle = renderStyleOfEnclosingTextNode(start); |
|
|
| 185 |
bool isStartAndEndOnSameNode = false; |
181 |
bool isStartAndEndOnSameNode = false; |
| 186 |
if (startStyle) { |
182 |
if (RenderStyle* startStyle = renderStyleOfEnclosingTextNode(start)) { |
| 187 |
isStartAndEndOnSameNode = renderStyleOfEnclosingTextNode(end) && start.deprecatedNode() == end.deprecatedNode(); |
183 |
isStartAndEndOnSameNode = renderStyleOfEnclosingTextNode(end) && start.containerNode() == end.containerNode(); |
| 188 |
bool isStartAndEndOfLastParagraphOnSameNode = renderStyleOfEnclosingTextNode(m_endOfLastParagraph) && start.deprecatedNode() == m_endOfLastParagraph.deprecatedNode(); |
184 |
bool isStartAndEndOfLastParagraphOnSameNode = renderStyleOfEnclosingTextNode(m_endOfLastParagraph) && start.containerNode() == m_endOfLastParagraph.containerNode(); |
| 189 |
|
185 |
|
| 190 |
// Avoid obtanining the start of next paragraph for start |
186 |
// Avoid obtanining the start of next paragraph for start |
| 191 |
if (startStyle->preserveNewline() && isNewLineAtPosition(start) && !isNewLineAtPosition(start.previous()) && start.offsetInContainerNode() > 0) |
187 |
if (startStyle->preserveNewline() && isNewLineAtPosition(start) && !isNewLineAtPosition(start.previous()) && start.offsetInContainerNode() > 0) |
|
Lines 194-240
void ApplyBlockElementCommand::rangeForP
Source/WebCore/editing/ApplyBlockElementCommand.cpp_sec3
|
| 194 |
// If start is in the middle of a text node, split. |
190 |
// If start is in the middle of a text node, split. |
| 195 |
if (!startStyle->collapseWhiteSpace() && start.offsetInContainerNode() > 0) { |
191 |
if (!startStyle->collapseWhiteSpace() && start.offsetInContainerNode() > 0) { |
| 196 |
int startOffset = start.offsetInContainerNode(); |
192 |
int startOffset = start.offsetInContainerNode(); |
| 197 |
splitTextNode(static_cast<Text*>(start.deprecatedNode()), startOffset); |
193 |
Text* startText = start.containerText(); |
| 198 |
start = firstPositionInOrBeforeNode(start.deprecatedNode()); |
194 |
splitTextNode(startText, startOffset); |
|
|
195 |
start = firstPositionInNode(startText); |
| 199 |
if (isStartAndEndOnSameNode) { |
196 |
if (isStartAndEndOnSameNode) { |
| 200 |
ASSERT(end.offsetInContainerNode() >= startOffset); |
197 |
ASSERT(end.offsetInContainerNode() >= startOffset); |
| 201 |
end = Position(end.deprecatedNode(), end.offsetInContainerNode() - startOffset, Position::PositionIsOffsetInAnchor); |
198 |
end = Position(startText, end.offsetInContainerNode() - startOffset); |
| 202 |
} |
199 |
} |
| 203 |
if (isStartAndEndOfLastParagraphOnSameNode) { |
200 |
if (isStartAndEndOfLastParagraphOnSameNode) { |
| 204 |
ASSERT(m_endOfLastParagraph.offsetInContainerNode() >= startOffset); |
201 |
ASSERT(m_endOfLastParagraph.offsetInContainerNode() >= startOffset); |
| 205 |
m_endOfLastParagraph = Position(m_endOfLastParagraph.deprecatedNode(), m_endOfLastParagraph.offsetInContainerNode() - startOffset, |
202 |
m_endOfLastParagraph = Position(startText, m_endOfLastParagraph.offsetInContainerNode() - startOffset); |
| 206 |
Position::PositionIsOffsetInAnchor); |
|
|
| 207 |
} |
203 |
} |
| 208 |
} |
204 |
} |
| 209 |
} |
205 |
} |
| 210 |
|
206 |
|
| 211 |
RenderStyle* endStyle = renderStyleOfEnclosingTextNode(end); |
207 |
if (RenderStyle* endStyle = renderStyleOfEnclosingTextNode(end)) { |
| 212 |
if (endStyle) { |
|
|
| 213 |
bool isEndAndEndOfLastParagraphOnSameNode = renderStyleOfEnclosingTextNode(m_endOfLastParagraph) && end.deprecatedNode() == m_endOfLastParagraph.deprecatedNode(); |
208 |
bool isEndAndEndOfLastParagraphOnSameNode = renderStyleOfEnclosingTextNode(m_endOfLastParagraph) && end.deprecatedNode() == m_endOfLastParagraph.deprecatedNode(); |
| 214 |
// Include \n at the end of line if we're at an empty paragraph |
209 |
// Include \n at the end of line if we're at an empty paragraph |
| 215 |
if (endStyle->preserveNewline() && start == end |
210 |
if (endStyle->preserveNewline() && start == end && end.offsetInContainerNode() < end.containerNode()->maxCharacterOffset()) { |
| 216 |
&& end.offsetInContainerNode() < end.containerNode()->maxCharacterOffset()) { |
|
|
| 217 |
int endOffset = end.offsetInContainerNode(); |
211 |
int endOffset = end.offsetInContainerNode(); |
| 218 |
if (!isNewLineAtPosition(end.previous()) && isNewLineAtPosition(end)) |
212 |
if (!isNewLineAtPosition(end.previous()) && isNewLineAtPosition(end)) |
| 219 |
end = Position(end.deprecatedNode(), endOffset + 1, Position::PositionIsOffsetInAnchor); |
213 |
end = Position(end.containerText(), endOffset + 1); |
| 220 |
if (isEndAndEndOfLastParagraphOnSameNode && end.offsetInContainerNode() >= m_endOfLastParagraph.offsetInContainerNode()) |
214 |
if (isEndAndEndOfLastParagraphOnSameNode && end.offsetInContainerNode() >= m_endOfLastParagraph.offsetInContainerNode()) |
| 221 |
m_endOfLastParagraph = end; |
215 |
m_endOfLastParagraph = end; |
| 222 |
} |
216 |
} |
| 223 |
|
217 |
|
| 224 |
// If end is in the middle of a text node, split. |
218 |
// If end is in the middle of a text node, split. |
| 225 |
if (!endStyle->collapseWhiteSpace() && end.offsetInContainerNode() |
219 |
if (!endStyle->collapseWhiteSpace() && end.offsetInContainerNode() && end.offsetInContainerNode() < end.containerNode()->maxCharacterOffset()) { |
| 226 |
&& end.offsetInContainerNode() < end.containerNode()->maxCharacterOffset()) { |
220 |
RefPtr<Text> endContainer = end.containerText(); |
| 227 |
splitTextNode(static_cast<Text*>(end.deprecatedNode()), end.offsetInContainerNode()); |
221 |
splitTextNode(endContainer, end.offsetInContainerNode()); |
| 228 |
if (isStartAndEndOnSameNode) |
222 |
if (isStartAndEndOnSameNode) |
| 229 |
start = firstPositionInOrBeforeNode(end.deprecatedNode()->previousSibling()); |
223 |
start = firstPositionInOrBeforeNode(endContainer->previousSibling()); |
| 230 |
if (isEndAndEndOfLastParagraphOnSameNode) { |
224 |
if (isEndAndEndOfLastParagraphOnSameNode) { |
| 231 |
if (m_endOfLastParagraph.offsetInContainerNode() == end.offsetInContainerNode()) |
225 |
if (m_endOfLastParagraph.offsetInContainerNode() == end.offsetInContainerNode()) |
| 232 |
m_endOfLastParagraph = lastPositionInNode(end.deprecatedNode()->previousSibling()); |
226 |
m_endOfLastParagraph = lastPositionInOrAfterNode(endContainer->previousSibling()); |
| 233 |
else |
227 |
else |
| 234 |
m_endOfLastParagraph = Position(end.deprecatedNode(), m_endOfLastParagraph.offsetInContainerNode() - end.offsetInContainerNode(), |
228 |
m_endOfLastParagraph = Position(endContainer, m_endOfLastParagraph.offsetInContainerNode() - end.offsetInContainerNode()); |
| 235 |
Position::PositionIsOffsetInAnchor); |
|
|
| 236 |
} |
229 |
} |
| 237 |
end = lastPositionInNode(end.deprecatedNode()->previousSibling()); |
230 |
end = lastPositionInNode(endContainer->previousSibling()); |
| 238 |
} |
231 |
} |
| 239 |
} |
232 |
} |
| 240 |
} |
233 |
} |
|
Lines 247-278
VisiblePosition ApplyBlockElementCommand
Source/WebCore/editing/ApplyBlockElementCommand.cpp_sec4
|
| 247 |
if (!style) |
240 |
if (!style) |
| 248 |
return endOfNextParagraph; |
241 |
return endOfNextParagraph; |
| 249 |
|
242 |
|
| 250 |
RefPtr<Node> containerNode = position.containerNode(); |
243 |
RefPtr<Text> text = position.containerText(); |
| 251 |
if (!style->preserveNewline() || !position.offsetInContainerNode() |
244 |
if (!style->preserveNewline() || !position.offsetInContainerNode() || !isNewLineAtPosition(firstPositionInNode(text.get()))) |
| 252 |
|| !isNewLineAtPosition(Position(containerNode.get(), 0, Position::PositionIsOffsetInAnchor))) |
|
|
| 253 |
return endOfNextParagraph; |
245 |
return endOfNextParagraph; |
| 254 |
|
246 |
|
| 255 |
// \n at the beginning of the text node immediately following the current paragraph is trimmed by moveParagraphWithClones. |
247 |
// \n at the beginning of the text node immediately following the current paragraph is trimmed by moveParagraphWithClones. |
| 256 |
// If endOfNextParagraph was pointing at this same text node, endOfNextParagraph will be shifted by one paragraph. |
248 |
// If endOfNextParagraph was pointing at this same text node, endOfNextParagraph will be shifted by one paragraph. |
| 257 |
// Avoid this by splitting "\n" |
249 |
// Avoid this by splitting "\n" |
| 258 |
splitTextNode(static_cast<Text*>(containerNode.get()), 1); |
250 |
splitTextNode(text, 1); |
| 259 |
|
251 |
|
| 260 |
if (start.anchorType() == Position::PositionIsOffsetInAnchor && containerNode.get() == start.containerNode()) { |
252 |
if (text == start.containerNode() && text->previousSibling() && text->previousSibling()->isTextNode()) { |
| 261 |
ASSERT(start.offsetInContainerNode() < position.offsetInContainerNode()); |
253 |
ASSERT(start.offsetInContainerNode() < position.offsetInContainerNode()); |
| 262 |
start = Position(containerNode->previousSibling(), start.offsetInContainerNode(), Position::PositionIsOffsetInAnchor); |
254 |
start = Position(static_cast<Text*>(text->previousSibling()), start.offsetInContainerNode()); |
| 263 |
} |
255 |
} |
| 264 |
if (end.anchorType() == Position::PositionIsOffsetInAnchor && containerNode.get() == end.containerNode()) { |
256 |
if (text == end.containerNode() && text->previousSibling() && text->previousSibling()->isTextNode()) { |
| 265 |
ASSERT(end.offsetInContainerNode() < position.offsetInContainerNode()); |
257 |
ASSERT(end.offsetInContainerNode() < position.offsetInContainerNode()); |
| 266 |
end = Position(containerNode->previousSibling(), end.offsetInContainerNode(), Position::PositionIsOffsetInAnchor); |
258 |
end = Position(static_cast<Text*>(text->previousSibling()), end.offsetInContainerNode()); |
| 267 |
} |
259 |
} |
| 268 |
if (m_endOfLastParagraph.anchorType() == Position::PositionIsOffsetInAnchor && containerNode.get() == m_endOfLastParagraph.containerNode()) { |
260 |
if (text == m_endOfLastParagraph.containerNode()) { |
| 269 |
if (m_endOfLastParagraph.offsetInContainerNode() < position.offsetInContainerNode()) |
261 |
if (m_endOfLastParagraph.offsetInContainerNode() < position.offsetInContainerNode()) { |
| 270 |
m_endOfLastParagraph = Position(containerNode->previousSibling(), m_endOfLastParagraph.offsetInContainerNode(), Position::PositionIsOffsetInAnchor); |
262 |
// We can only fix endOfLastParagraph if the previous node was still text and hasn't been modified by script. |
| 271 |
else |
263 |
if (text->previousSibling()->isTextNode() |
| 272 |
m_endOfLastParagraph = Position(containerNode, m_endOfLastParagraph.offsetInContainerNode() - 1, Position::PositionIsOffsetInAnchor); |
264 |
&& static_cast<unsigned>(m_endOfLastParagraph.offsetInContainerNode()) <= static_cast<Text*>(text->previousSibling())->length()) |
|
|
265 |
m_endOfLastParagraph = Position(static_cast<Text*>(text->previousSibling()), m_endOfLastParagraph.offsetInContainerNode()); |
| 266 |
} else |
| 267 |
m_endOfLastParagraph = Position(text.get(), m_endOfLastParagraph.offsetInContainerNode() - 1); |
| 273 |
} |
268 |
} |
| 274 |
|
269 |
|
| 275 |
return Position(containerNode.get(), position.offsetInContainerNode() - 1, Position::PositionIsOffsetInAnchor); |
270 |
return Position(text.get(), position.offsetInContainerNode() - 1); |
| 276 |
} |
271 |
} |
| 277 |
|
272 |
|
| 278 |
PassRefPtr<Element> ApplyBlockElementCommand::createBlockElement() const |
273 |
PassRefPtr<Element> ApplyBlockElementCommand::createBlockElement() const |