WebCore/ChangeLog

 12010-11-19 Ryosuke Niwa <rniwa@webkit.org>
 2
 3 Reviewed by NOBODY (OOPS!).
 4
 5 SelectionController::typingStyle() should return EditingStyle*
 6 https://bugs.webkit.org/show_bug.cgi?id=49813
 7
 8 Changed the return type of SelectionController::typingStyle to EditingStyle*.
 9
 10 Extracted textDirection from Editor::textDirectionForSelection to hide the underlying
 11 CSSMutableStyleDeclaration.
 12
 13 Also extracted the code to preserve unicode-bidi and direction CSS properties in
 14 InsertTextCommand::input, and moved into EditingStyle::prepareToApplyAt. ShouldPreserveWritingDirection,
 15 which is added to the argument list of EditingStyle::prepareToApplyAt, decides whether or not
 16 these two properties are preserved.
 17
 18 Also added SelectionController::copyTypingStyle() to copy the typing style as an instance of
 19 CSSMutableStyleDeclaration.
 20
 21 No new tests are added since this is a refactoring.
 22
 23 * editing/EditingStyle.cpp:
 24 (WebCore::EditingStyle::textDirection): Extracted from Editor::textDirectionForSelection.
 25 (WebCore::EditingStyle::removeStyleConflictingWithStyleOfNode): Added a missing null check.
 26 (WebCore::EditingStyle::prepareToApplyAt): See above.
 27 (WebCore::editingStyleIncludingTypingStyle): Calls SelectionController::typingStyle.
 28 * editing/EditingStyle.h: Moved WritingDirection from Editor.h
 29 * editing/Editor.cpp:
 30 (WebCore::Editor::textDirectionForSelection): Calls EditingStyle::textDirection.
 31 (WebCore::Editor::computeAndSetTypingStyle): Calls SelectionController::typingStyle.
 32 (WebCore::Editor::selectionComputedStyle): Ditto.
 33 (WebCore::Editor::styleForSelectionStart): Ditto.
 34 * editing/Editor.h:
 35 * editing/InsertLineBreakCommand.cpp:
 36 (WebCore::InsertLineBreakCommand::doApply): Ditto.
 37 * editing/InsertTextCommand.cpp:
 38 (WebCore::InsertTextCommand::input): Calls EditingStyle::prepareToApplyAt with PreserveWritingDirection.
 39 * editing/SelectionController.h:
 40 (WebCore::SelectionController::typingStyle): Returns EditingStyle* rather than CSSMutableStyleDeclaration*.
 41 (WebCore::SelectionController::copyTypingStyle): Added.
 42
1432010-11-19 Daniel Bates <dbates@rim.com>
244
345 Reviewed by Antonio Gomes.
72423

WebCore/editing/EditingStyle.cpp

3030#include "ApplyStyleCommand.h"
3131#include "CSSComputedStyleDeclaration.h"
3232#include "CSSMutableStyleDeclaration.h"
 33#include "CSSValueKeywords.h"
3334#include "Frame.h"
3435#include "RenderStyle.h"
3536#include "SelectionController.h"

@@bool EditingStyle::isEmpty() const
141142 return !m_mutableStyle || m_mutableStyle->isEmpty();
142143}
143144
 145bool EditingStyle::textDirection(WritingDirection& writingDirection) const
 146{
 147 RefPtr<CSSValue> unicodeBidi = m_mutableStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi);
 148 if (!unicodeBidi)
 149 return false;
 150
 151 ASSERT(unicodeBidi->isPrimitiveValue());
 152 int unicodeBidiValue = static_cast<CSSPrimitiveValue*>(unicodeBidi.get())->getIdent();
 153 if (unicodeBidiValue == CSSValueEmbed) {
 154 RefPtr<CSSValue> direction = m_mutableStyle->getPropertyCSSValue(CSSPropertyDirection);
 155 ASSERT(!direction || direction->isPrimitiveValue());
 156 if (!direction)
 157 return false;
 158
 159 writingDirection = static_cast<CSSPrimitiveValue*>(direction.get())->getIdent() == CSSValueLtr ? LeftToRightWritingDirection : RightToLeftWritingDirection;
 160
 161 return true;
 162 }
 163
 164 if (unicodeBidiValue == CSSValueNormal) {
 165 writingDirection = NaturalWritingDirection;
 166 return true;
 167 }
 168
 169 return false;
 170}
 171
144172void EditingStyle::setStyle(PassRefPtr<CSSMutableStyleDeclaration> style)
145173{
146174 m_mutableStyle = style;

@@void EditingStyle::removeStyleAddedByNod
175203
176204void EditingStyle::removeStyleConflictingWithStyleOfNode(Node* node)
177205{
178  if (!node || !node->parentNode())
 206 if (!node || !node->parentNode() || !m_mutableStyle)
179207 return;
180208 RefPtr<CSSMutableStyleDeclaration> parentStyle = editingStyleFromComputedStyle(computedStyle(node->parentNode()));
181209 RefPtr<CSSMutableStyleDeclaration> nodeStyle = editingStyleFromComputedStyle(computedStyle(node));

@@void EditingStyle::removeNonEditingPrope
192220 m_mutableStyle = copyEditingProperties(m_mutableStyle.get());
193221}
194222
195 void EditingStyle::prepareToApplyAt(const Position& position)
 223void EditingStyle::prepareToApplyAt(const Position& position, ShouldPreserveWritingDirection shouldPreserveWritingDirection)
196224{
 225 if (!m_mutableStyle)
 226 return;
 227
197228 // ReplaceSelectionCommand::handleStyleSpans() requires that this function only removes the editing style.
198229 // If this function was modified in the future to delete all redundant properties, then add a boolean value to indicate
199230 // which one of editingStyleAtPosition or computedStyle is called.
200231 RefPtr<EditingStyle> style = EditingStyle::create(position);
 232
 233 RefPtr<CSSValue> unicodeBidi;
 234 RefPtr<CSSValue> direction;
 235 if (shouldPreserveWritingDirection) {
 236 unicodeBidi = m_mutableStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi);
 237 direction = m_mutableStyle->getPropertyCSSValue(CSSPropertyDirection);
 238 }
 239
201240 style->m_mutableStyle->diff(m_mutableStyle.get());
202241
203242 // if alpha value is zero, we don't add the background color.

@@void EditingStyle::prepareToApplyAt(cons
207246 ExceptionCode ec;
208247 m_mutableStyle->removeProperty(CSSPropertyBackgroundColor, ec);
209248 }
 249
 250 if (unicodeBidi) {
 251 ASSERT(unicodeBidi->isPrimitiveValue());
 252 m_mutableStyle->setProperty(CSSPropertyUnicodeBidi, static_cast<CSSPrimitiveValue*>(unicodeBidi.get())->getIdent());
 253 if (direction) {
 254 ASSERT(direction->isPrimitiveValue());
 255 m_mutableStyle->setProperty(CSSPropertyDirection, static_cast<CSSPrimitiveValue*>(direction.get())->getIdent());
 256 }
 257 }
210258}
211259
212260PassRefPtr<EditingStyle> editingStyleIncludingTypingStyle(const Position& position)
213261{
214262 RefPtr<EditingStyle> editingStyle = EditingStyle::create(position);
215  RefPtr<CSSMutableStyleDeclaration> typingStyle = position.node()->document()->frame()->selection()->typingStyle();
216  if (typingStyle)
217  editingStyle->style()->merge(copyEditingProperties(typingStyle.get()).get());
 263 RefPtr<EditingStyle> typingStyle = position.node()->document()->frame()->selection()->typingStyle();
 264 if (typingStyle && typingStyle->style())
 265 editingStyle->style()->merge(copyEditingProperties(typingStyle->style()).get());
218266 return editingStyle;
219267}
220268
72423

WebCore/editing/EditingStyle.h

@@namespace WebCore {
4040class CSSStyleDeclaration;
4141class CSSComputedStyleDeclaration;
4242
 43enum WritingDirection { NaturalWritingDirection, LeftToRightWritingDirection, RightToLeftWritingDirection };
 44
4345class EditingStyle : public RefCounted<EditingStyle> {
4446public:
 47
 48 enum ShouldPreserveWritingDirection { PreserveWritingDirection, DoNotPreserveWritingDirection };
4549
4650 static PassRefPtr<EditingStyle> create()
4751 {

@@public:
6468 }
6569
6670 CSSMutableStyleDeclaration* style() { return m_mutableStyle.get(); }
 71 bool textDirection(WritingDirection&) const;
6772 bool isEmpty() const;
6873 void setStyle(PassRefPtr<CSSMutableStyleDeclaration>);
6974 void clear();

@@public:
7176 void removeStyleAddedByNode(Node* node);
7277 void removeStyleConflictingWithStyleOfNode(Node* node);
7378 void removeNonEditingProperties();
74  void prepareToApplyAt(const Position&);
 79 void prepareToApplyAt(const Position&, ShouldPreserveWritingDirection = DoNotPreserveWritingDirection);
7580
7681private:
7782 EditingStyle();
72423

WebCore/editing/Editor.cpp

@@WritingDirection Editor::textDirectionFo
608608 }
609609
610610 if (m_frame->selection()->isCaret()) {
611  RefPtr<CSSMutableStyleDeclaration> typingStyle = m_frame->selection()->typingStyle();
612  if (typingStyle) {
613  RefPtr<CSSValue> unicodeBidi = typingStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi);
614  if (unicodeBidi) {
615  ASSERT(unicodeBidi->isPrimitiveValue());
616  int unicodeBidiValue = static_cast<CSSPrimitiveValue*>(unicodeBidi.get())->getIdent();
617  if (unicodeBidiValue == CSSValueEmbed) {
618  RefPtr<CSSValue> direction = typingStyle->getPropertyCSSValue(CSSPropertyDirection);
619  ASSERT(!direction || direction->isPrimitiveValue());
620  if (direction) {
621  hasNestedOrMultipleEmbeddings = false;
622  return static_cast<CSSPrimitiveValue*>(direction.get())->getIdent() == CSSValueLtr ? LeftToRightWritingDirection : RightToLeftWritingDirection;
623  }
624  } else if (unicodeBidiValue == CSSValueNormal) {
625  hasNestedOrMultipleEmbeddings = false;
626  return NaturalWritingDirection;
627  }
628  }
 611 RefPtr<EditingStyle> typingStyle = m_frame->selection()->typingStyle();
 612 WritingDirection direction;
 613 if (typingStyle && typingStyle->textDirection(direction)) {
 614 hasNestedOrMultipleEmbeddings = false;
 615 return direction;
629616 }
630617 node = m_frame->selection()->selection().visibleStart().deepEquivalent().node();
631618 }

@@void Editor::computeAndSetTypingStyle(CS
30062993
30072994 // Calculate the current typing style.
30082995 RefPtr<CSSMutableStyleDeclaration> mutableStyle = style->makeMutable();
3009  if (m_frame->selection()->typingStyle()) {
3010  m_frame->selection()->typingStyle()->merge(mutableStyle.get());
3011  mutableStyle = m_frame->selection()->typingStyle();
 2996 RefPtr<EditingStyle> typingStyle = m_frame->selection()->typingStyle();
 2997 if (typingStyle && typingStyle->style()) {
 2998 typingStyle->style()->merge(mutableStyle.get());
 2999 mutableStyle = typingStyle->style();
30123000 }
30133001
30143002 RefPtr<CSSValue> unicodeBidi;

@@PassRefPtr<CSSMutableStyleDeclaration> E
30683056 if (!m_frame->selection()->typingStyle())
30693057 return mutableStyle;
30703058
3071  RefPtr<EditingStyle> typingStyle = EditingStyle::create(m_frame->selection()->typingStyle());
 3059 RefPtr<EditingStyle> typingStyle = m_frame->selection()->typingStyle();
30723060 typingStyle->removeNonEditingProperties();
30733061 typingStyle->prepareToApplyAt(position);
30743062 mutableStyle->merge(typingStyle->style());

@@RenderStyle* Editor::styleForSelectionSt
31523140 if (!position.node())
31533141 return 0;
31543142
3155  if (!m_frame->selection()->typingStyle())
 3143 RefPtr<EditingStyle> typingStyle = m_frame->selection()->typingStyle();
 3144 if (!typingStyle || !typingStyle->style())
31563145 return position.node()->renderer()->style();
31573146
31583147 RefPtr<Element> styleElement = m_frame->document()->createElement(spanTag, false);
31593148
31603149 ExceptionCode ec = 0;
3161  String styleText = m_frame->selection()->typingStyle()->cssText() + " display: inline";
 3150 String styleText = typingStyle->style()->cssText() + " display: inline";
31623151 styleElement->setAttribute(styleAttr, styleText.impl(), ec);
31633152 ASSERT(!ec);
31643153
72423

WebCore/editing/Editor.h

@@struct CompositionUnderline {
7070
7171enum TriState { FalseTriState, TrueTriState, MixedTriState };
7272enum EditorCommandSource { CommandFromMenuOrKeyBinding, CommandFromDOM, CommandFromDOMWithUserInterface };
73 enum WritingDirection { NaturalWritingDirection, LeftToRightWritingDirection, RightToLeftWritingDirection };
7473
7574class Editor {
7675public:
72423

WebCore/editing/InsertLineBreakCommand.cpp

@@void InsertLineBreakCommand::doApply()
164164 }
165165
166166 // Handle the case where there is a typing style.
167 
168  RefPtr<CSSMutableStyleDeclaration> typingStyle = document()->frame()->selection()->typingStyle();
169 
170  if (typingStyle && typingStyle->length() > 0) {
 167
 168 RefPtr<EditingStyle> typingStyle = document()->frame()->selection()->typingStyle();
 169
 170 if (typingStyle && !typingStyle->isEmpty()) {
171171 // Apply the typing style to the inserted line break, so that if the selection
172172 // leaves and then comes back, new input will have the right style.
173173 // FIXME: We shouldn't always apply the typing style to the line break here,
174174 // see <rdar://problem/5794462>.
175  applyStyle(typingStyle.get(), firstDeepEditingPositionForNode(nodeToInsert.get()), lastDeepEditingPositionForNode(nodeToInsert.get()));
 175 applyStyle(typingStyle->style(), firstDeepEditingPositionForNode(nodeToInsert.get()), lastDeepEditingPositionForNode(nodeToInsert.get()));
176176 // Even though this applyStyle operates on a Range, it still sets an endingSelection().
177177 // It tries to set a VisibleSelection around the content it operated on. So, that VisibleSelection
178178 // will either (a) select the line break we inserted, or it will (b) be a caret just
72423

WebCore/editing/InsertTextCommand.cpp

@@void InsertTextCommand::input(const Stri
190190 setEndingSelection(forcedEndingSelection);
191191
192192 // Handle the case where there is a typing style.
193  RefPtr<CSSMutableStyleDeclaration> typingStyle = document()->frame()->selection()->typingStyle();
194  RefPtr<CSSComputedStyleDeclaration> endingStyle = endPosition.computedStyle();
195  RefPtr<CSSValue> unicodeBidi;
196  RefPtr<CSSValue> direction;
197  if (typingStyle) {
198  unicodeBidi = typingStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi);
199  direction = typingStyle->getPropertyCSSValue(CSSPropertyDirection);
 193 if (RefPtr<EditingStyle> typingStyle = document()->frame()->selection()->typingStyle()) {
 194 typingStyle->prepareToApplyAt(endPosition, EditingStyle::PreserveWritingDirection);
 195 if (!typingStyle->isEmpty())
 196 applyStyle(typingStyle->style());
200197 }
201  endingStyle->diff(typingStyle.get());
202  if (typingStyle && unicodeBidi) {
203  ASSERT(unicodeBidi->isPrimitiveValue());
204  typingStyle->setProperty(CSSPropertyUnicodeBidi, static_cast<CSSPrimitiveValue*>(unicodeBidi.get())->getIdent());
205  if (direction) {
206  ASSERT(direction->isPrimitiveValue());
207  typingStyle->setProperty(CSSPropertyDirection, static_cast<CSSPrimitiveValue*>(direction.get())->getIdent());
208  }
209  }
210 
211  if (typingStyle && typingStyle->length())
212  applyStyle(typingStyle.get());
213198
214199 if (!selectInsertedText)
215200 setEndingSelection(VisibleSelection(endingSelection().end(), endingSelection().affinity()));
72423

WebCore/editing/SelectionController.h

@@public:
160160
161161 void paintDragCaret(GraphicsContext*, int tx, int ty, const IntRect& clipRect) const;
162162
163  CSSMutableStyleDeclaration* typingStyle() const;
 163 EditingStyle* typingStyle() const;
 164 PassRefPtr<CSSMutableStyleDeclaration> copyTypingStyle() const;
164165 void setTypingStyle(PassRefPtr<EditingStyle>);
165166 void clearTypingStyle();
166167

@@private:
233234 bool m_caretPaint;
234235};
235236
236 inline CSSMutableStyleDeclaration* SelectionController::typingStyle() const
 237inline EditingStyle* SelectionController::typingStyle() const
237238{
238  return m_typingStyle ? m_typingStyle->style() : 0;
 239 return m_typingStyle.get();
 240}
 241
 242inline PassRefPtr<CSSMutableStyleDeclaration> SelectionController::copyTypingStyle() const
 243{
 244 if (!m_typingStyle || !m_typingStyle->style())
 245 return 0;
 246 return m_typingStyle->style()->copy();
239247}
240248
241249inline void SelectionController::clearTypingStyle()
72423

WebKit/mac/ChangeLog

 12010-11-19 Ryosuke Niwa <rniwa@webkit.org>
 2
 3 Reviewed by NOBODY (OOPS!).
 4
 5 SelectionController::typingStyle() should return EditingStyle*
 6 https://bugs.webkit.org/show_bug.cgi?id=49813
 7
 8 Changed the return value of SelectionController::typingStyle() to EditingStyle*.
 9 Also added SelectionController::copyTypingStyle() to copy the typing style
 10 as an instance of CSSMutableStyleDeclaration.
 11
 12 No tests are added since this is no behavioral change.
 13
 14 * WebView/WebFrame.mm:
 15 (-[WebFrame _typingStyle]): Calls SelectionController::copyTypingStyle()
 16
1172010-11-19 Nikolas Zimmermann <nzimmermann@rim.com>
218
319 Reviewed by Dirk Schulze.
72429

WebKit/mac/WebView/WebFrame.mm

@@- (DOMRange *)_characterRangeAtPoint:(NS
901901
902902- (DOMCSSStyleDeclaration *)_typingStyle
903903{
904  if (!_private->coreFrame || !_private->coreFrame->selection()->typingStyle())
 904 if (!_private->coreFrame)
 905 return nil;
 906 RefPtr<CSSMutableStyleDeclaration> typingStyle = _private->coreFrame->selection()->copyTypingStyle();
 907 if (!typingStyle)
905908 return nil;
906  return kit(_private->coreFrame->selection()->typingStyle()->copy().get());
 909 return kit(typingStyle.get());
907910}
908911
909912- (void)_setTypingStyle:(DOMCSSStyleDeclaration *)style withUndoAction:(EditAction)undoAction
72423