?? htmlediting.cpp
字號:
}
void EditCommandPtr::setParent(const EditCommandPtr &cmd) const
{
IF_IMPL_NULL_RETURN;
get()->setParent(cmd.get());
}
EditCommandPtr &EditCommandPtr::emptyCommand()
{
static EditCommandPtr m_emptyCommand;
return m_emptyCommand;
}
//------------------------------------------------------------------------------------------
// StyleChange
StyleChange::StyleChange(CSSStyleDeclarationImpl *style, ELegacyHTMLStyles usesLegacyStyles)
: m_applyBold(false), m_applyItalic(false), m_usesLegacyStyles(usesLegacyStyles)
{
init(style, Position());
}
StyleChange::StyleChange(CSSStyleDeclarationImpl *style, const Position &position, ELegacyHTMLStyles usesLegacyStyles)
: m_applyBold(false), m_applyItalic(false), m_usesLegacyStyles(usesLegacyStyles)
{
init(style, position);
}
void StyleChange::init(CSSStyleDeclarationImpl *style, const Position &position)
{
style->ref();
CSSMutableStyleDeclarationImpl *mutableStyle = style->makeMutable();
mutableStyle->ref();
style->deref();
QString styleText("");
QValueListConstIterator<CSSProperty> end;
for (QValueListConstIterator<CSSProperty> it = mutableStyle->valuesIterator(); it != end; ++it) {
const CSSProperty *property = &*it;
// If position is empty or the position passed in already has the
// style, just move on.
if (position.isNotNull() && currentlyHasStyle(position, property))
continue;
// If needed, figure out if this change is a legacy HTML style change.
if (m_usesLegacyStyles && checkForLegacyHTMLStyleChange(property))
continue;
// Add this property
if (property->id() == CSS_PROP__KHTML_TEXT_DECORATIONS_IN_EFFECT) {
// we have to special-case text decorations
CSSProperty alteredProperty = CSSProperty(CSS_PROP_TEXT_DECORATION, property->value(), property->isImportant());
styleText += alteredProperty.cssText().string();
} else {
styleText += property->cssText().string();
}
}
mutableStyle->deref();
// Save the result for later
m_cssStyle = styleText.stripWhiteSpace();
}
StyleChange::ELegacyHTMLStyles StyleChange::styleModeForParseMode(bool isQuirksMode)
{
return isQuirksMode ? UseLegacyHTMLStyles : DoNotUseLegacyHTMLStyles;
}
bool StyleChange::checkForLegacyHTMLStyleChange(const CSSProperty *property)
{
if (!property || !property->value()) {
return false;
}
DOMString valueText(property->value()->cssText());
switch (property->id()) {
case CSS_PROP_FONT_WEIGHT:
if (strcasecmp(valueText, "bold") == 0) {
m_applyBold = true;
return true;
}
break;
case CSS_PROP_FONT_STYLE:
if (strcasecmp(valueText, "italic") == 0 || strcasecmp(valueText, "oblique") == 0) {
m_applyItalic = true;
return true;
}
break;
case CSS_PROP_COLOR: {
QColor color(CSSParser::parseColor(valueText));
m_applyFontColor = color.name();
return true;
}
case CSS_PROP_FONT_FAMILY:
m_applyFontFace = valueText;
return true;
case CSS_PROP_FONT_SIZE:
if (property->value()->cssValueType() == CSSValue::CSS_PRIMITIVE_VALUE) {
CSSPrimitiveValueImpl *value = static_cast<CSSPrimitiveValueImpl *>(property->value());
float number = value->getFloatValue(CSSPrimitiveValue::CSS_PX);
if (number <= 9)
m_applyFontSize = "1";
else if (number <= 10)
m_applyFontSize = "2";
else if (number <= 13)
m_applyFontSize = "3";
else if (number <= 16)
m_applyFontSize = "4";
else if (number <= 18)
m_applyFontSize = "5";
else if (number <= 24)
m_applyFontSize = "6";
else
m_applyFontSize = "7";
// Huge quirk in Microsft Entourage is that they understand CSS font-size, but also write
// out legacy 1-7 values in font tags (I guess for mailers that are not CSS-savvy at all,
// like Eudora). Yes, they write out *both*. We need to write out both as well. Return false.
return false;
}
else {
// Can't make sense of the number. Put no font size.
return true;
}
}
return false;
}
bool StyleChange::currentlyHasStyle(const Position &pos, const CSSProperty *property)
{
ASSERT(pos.isNotNull());
CSSComputedStyleDeclarationImpl *style = pos.computedStyle();
ASSERT(style);
style->ref();
CSSValueImpl *value = style->getPropertyCSSValue(property->id(), DoNotUpdateLayout);
style->deref();
if (!value)
return false;
value->ref();
bool result = strcasecmp(value->cssText(), property->value()->cssText()) == 0;
value->deref();
return result;
}
//------------------------------------------------------------------------------------------
// EditCommand
EditCommand::EditCommand(DocumentImpl *document)
: m_document(document), m_state(NotApplied), m_typingStyle(0), m_parent(0)
{
ASSERT(m_document);
ASSERT(m_document->part());
m_document->ref();
m_startingSelection = m_document->part()->selection();
m_endingSelection = m_startingSelection;
m_document->part()->setSelection(Selection(), false, true);
}
EditCommand::~EditCommand()
{
ASSERT(m_document);
m_document->deref();
if (m_typingStyle)
m_typingStyle->deref();
}
void EditCommand::apply()
{
ASSERT(m_document);
ASSERT(m_document->part());
ASSERT(state() == NotApplied);
KHTMLPart *part = m_document->part();
ASSERT(part->selection().isNone());
doApply();
m_state = Applied;
// FIXME: Improve typing style.
// See this bug: <rdar://problem/3769899> Implementation of typing style needs improvement
if (!preservesTypingStyle())
setTypingStyle(0);
if (!isCompositeStep()) {
document()->updateLayout();
EditCommandPtr cmd(this);
part->appliedEditing(cmd);
}
}
void EditCommand::unapply()
{
ASSERT(m_document);
ASSERT(m_document->part());
ASSERT(state() == Applied);
bool topLevel = !isCompositeStep();
KHTMLPart *part = m_document->part();
if (topLevel) {
part->setSelection(Selection(), false, true);
}
ASSERT(part->selection().isNone());
doUnapply();
m_state = NotApplied;
if (topLevel) {
document()->updateLayout();
EditCommandPtr cmd(this);
part->unappliedEditing(cmd);
}
}
void EditCommand::reapply()
{
ASSERT(m_document);
ASSERT(m_document->part());
ASSERT(state() == NotApplied);
bool topLevel = !isCompositeStep();
KHTMLPart *part = m_document->part();
if (topLevel) {
part->setSelection(Selection(), false, true);
}
ASSERT(part->selection().isNone());
doReapply();
m_state = Applied;
if (topLevel) {
document()->updateLayout();
EditCommandPtr cmd(this);
part->reappliedEditing(cmd);
}
}
void EditCommand::doReapply()
{
doApply();
}
EditAction EditCommand::editingAction() const
{
return EditActionUnspecified;
}
void EditCommand::setStartingSelection(const Selection &s)
{
for (EditCommand *cmd = this; cmd; cmd = cmd->m_parent)
cmd->m_startingSelection = s;
}
void EditCommand::setStartingSelection(const VisiblePosition &p)
{
Selection s = Selection(p);
for (EditCommand *cmd = this; cmd; cmd = cmd->m_parent)
cmd->m_startingSelection = s;
}
void EditCommand::setStartingSelection(const Position &p, EAffinity affinity)
{
Selection s = Selection(p, affinity);
for (EditCommand *cmd = this; cmd; cmd = cmd->m_parent)
cmd->m_startingSelection = s;
}
void EditCommand::setEndingSelection(const Selection &s)
{
for (EditCommand *cmd = this; cmd; cmd = cmd->m_parent)
cmd->m_endingSelection = s;
}
void EditCommand::setEndingSelection(const VisiblePosition &p)
{
Selection s = Selection(p);
for (EditCommand *cmd = this; cmd; cmd = cmd->m_parent)
cmd->m_endingSelection = s;
}
void EditCommand::setEndingSelection(const Position &p, EAffinity affinity)
{
Selection s = Selection(p, affinity);
for (EditCommand *cmd = this; cmd; cmd = cmd->m_parent)
cmd->m_endingSelection = s;
}
void EditCommand::assignTypingStyle(CSSMutableStyleDeclarationImpl *style)
{
if (m_typingStyle == style)
return;
CSSMutableStyleDeclarationImpl *old = m_typingStyle;
m_typingStyle = style;
if (m_typingStyle)
m_typingStyle->ref();
if (old)
old->deref();
}
void EditCommand::setTypingStyle(CSSMutableStyleDeclarationImpl *style)
{
// FIXME: Improve typing style.
// See this bug: <rdar://problem/3769899> Implementation of typing style needs improvement
for (EditCommand *cmd = this; cmd; cmd = cmd->m_parent)
cmd->assignTypingStyle(style);
}
bool EditCommand::preservesTypingStyle() const
{
return false;
}
bool EditCommand::isInsertTextCommand() const
{
return false;
}
bool EditCommand::isTypingCommand() const
{
return false;
}
CSSMutableStyleDeclarationImpl *EditCommand::styleAtPosition(const Position &pos)
{
CSSComputedStyleDeclarationImpl *computedStyle = pos.computedStyle();
computedStyle->ref();
CSSMutableStyleDeclarationImpl *style = computedStyle->copyInheritableProperties();
computedStyle->deref();
// FIXME: Improve typing style.
// See this bug: <rdar://problem/3769899> Implementation of typing style needs improvement
CSSMutableStyleDeclarationImpl *typingStyle = document()->part()->typingStyle();
if (typingStyle)
style->merge(typingStyle);
return style;
}
//------------------------------------------------------------------------------------------
// CompositeEditCommand
CompositeEditCommand::CompositeEditCommand(DocumentImpl *document)
: EditCommand(document)
{
}
void CompositeEditCommand::doUnapply()
{
if (m_cmds.count() == 0) {
return;
}
for (int i = m_cmds.count() - 1; i >= 0; --i)
m_cmds[i]->unapply();
setState(NotApplied);
}
void CompositeEditCommand::doReapply()
{
if (m_cmds.count() == 0) {
return;
}
for (QValueList<EditCommandPtr>::ConstIterator it = m_cmds.begin(); it != m_cmds.end(); ++it)
(*it)->reapply();
setState(Applied);
}
//
// sugary-sweet convenience functions to help create and apply edit commands in composite commands
//
void CompositeEditCommand::applyCommandToComposite(EditCommandPtr &cmd)
{
cmd.setStartingSelection(endingSelection());
cmd.setEndingSelection(endingSelection());
cmd.setParent(this);
cmd.apply();
m_cmds.append(cmd);
}
void CompositeEditCommand::applyStyle(CSSStyleDeclarationImpl *style, EditAction editingAction)
{
EditCommandPtr cmd(new ApplyStyleCommand(document(), style, editingAction));
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -