diff options
author | Leon Clarke <leonclarke@google.com> | 2010-06-03 14:33:32 +0100 |
---|---|---|
committer | Leon Clarke <leonclarke@google.com> | 2010-06-08 12:24:51 +0100 |
commit | 5af96e2c7b73ebc627c6894727826a7576d31758 (patch) | |
tree | f9d5e6f6175ccd7e3d14de9b290f08937a0d17ba /WebCore/rendering | |
parent | 8cc4fcf4f6adcbc0e0aebfc24fbad9a4cddf2cfb (diff) | |
download | external_webkit-5af96e2c7b73ebc627c6894727826a7576d31758.zip external_webkit-5af96e2c7b73ebc627c6894727826a7576d31758.tar.gz external_webkit-5af96e2c7b73ebc627c6894727826a7576d31758.tar.bz2 |
Merge webkit.org at r60469 : Initial merge by git.
Change-Id: I66a0047aa2af802f66bb0c7f2a8b02247a596234
Diffstat (limited to 'WebCore/rendering')
27 files changed, 864 insertions, 358 deletions
diff --git a/WebCore/rendering/AutoTableLayout.cpp b/WebCore/rendering/AutoTableLayout.cpp index 2a4958a..1633d88 100644 --- a/WebCore/rendering/AutoTableLayout.cpp +++ b/WebCore/rendering/AutoTableLayout.cpp @@ -64,7 +64,6 @@ void AutoTableLayout::recalcColumn(int effCol) else if (child->isTableSection()) { RenderTableSection* section = toRenderTableSection(child); int numRows = section->numRows(); - RenderTableCell* last = 0; for (int i = 0; i < numRows; i++) { RenderTableSection::CellStruct current = section->cellAt(i, effCol); RenderTableCell* cell = current.cell; @@ -133,7 +132,6 @@ void AutoTableLayout::recalcColumn(int effCol) l.maxWidth = max(l.maxWidth, 1); insertSpanCell(cell); } - last = cell; } } } @@ -513,7 +511,6 @@ void AutoTableLayout::layout() calcEffectiveWidth(); bool havePercent = false; - bool haveRelative = false; int totalRelative = 0; int numAuto = 0; int numFixed = 0; @@ -535,7 +532,6 @@ void AutoTableLayout::layout() totalPercent += width.rawValue(); break; case Relative: - haveRelative = true; totalRelative += width.value(); break; case Fixed: diff --git a/WebCore/rendering/MediaControlElements.cpp b/WebCore/rendering/MediaControlElements.cpp index 16827f5..3413b02 100644 --- a/WebCore/rendering/MediaControlElements.cpp +++ b/WebCore/rendering/MediaControlElements.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2008, 2009, 2010 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -62,19 +62,29 @@ static const float cSeekRepeatDelay = 0.1f; static const float cStepTime = 0.07f; static const float cSeekTime = 0.2f; -MediaControlShadowRootElement::MediaControlShadowRootElement(Document* document, HTMLMediaElement* mediaElement) - : HTMLDivElement(divTag, document) +inline MediaControlShadowRootElement::MediaControlShadowRootElement(HTMLMediaElement* mediaElement) + : HTMLDivElement(divTag, mediaElement->document()) , m_mediaElement(mediaElement) { +} + +PassRefPtr<MediaControlShadowRootElement> MediaControlShadowRootElement::create(HTMLMediaElement* mediaElement) +{ + RefPtr<MediaControlShadowRootElement> element = new MediaControlShadowRootElement(mediaElement); + RefPtr<RenderStyle> rootStyle = RenderStyle::create(); rootStyle->inheritFrom(mediaElement->renderer()->style()); rootStyle->setDisplay(BLOCK); rootStyle->setPosition(RelativePosition); - RenderMediaControlShadowRoot* renderer = new (mediaElement->renderer()->renderArena()) RenderMediaControlShadowRoot(this); + + RenderMediaControlShadowRoot* renderer = new (mediaElement->renderer()->renderArena()) RenderMediaControlShadowRoot(element.get()); renderer->setStyle(rootStyle.release()); - setRenderer(renderer); - setAttached(); - setInDocument(); + + element->setRenderer(renderer); + element->setAttached(); + element->setInDocument(); + + return element.release(); } void MediaControlShadowRootElement::updateStyle() @@ -87,8 +97,8 @@ void MediaControlShadowRootElement::updateStyle() // ---------------------------- -MediaControlElement::MediaControlElement(Document* document, PseudoId pseudo, HTMLMediaElement* mediaElement) - : HTMLDivElement(divTag, document) +MediaControlElement::MediaControlElement(HTMLMediaElement* mediaElement, PseudoId pseudo) + : HTMLDivElement(divTag, mediaElement->document()) , m_mediaElement(mediaElement) , m_pseudoStyleId(pseudo) { @@ -118,6 +128,11 @@ MediaControlElement::MediaControlElement(Document* document, PseudoId pseudo, HT } } +PassRefPtr<MediaControlElement> MediaControlElement::create(HTMLMediaElement* mediaElement, PseudoId pseudoStyleId) +{ + return new MediaControlElement(mediaElement, pseudoStyleId); +} + void MediaControlElement::attachToParent(Element* parent) { parent->addChild(this); @@ -200,9 +215,14 @@ void MediaControlElement::updateStyle() // ---------------------------- -MediaControlTimelineContainerElement::MediaControlTimelineContainerElement(Document* document, HTMLMediaElement* element) - : MediaControlElement(document, MEDIA_CONTROLS_TIMELINE_CONTAINER, element) +inline MediaControlTimelineContainerElement::MediaControlTimelineContainerElement(HTMLMediaElement* mediaElement) + : MediaControlElement(mediaElement, MEDIA_CONTROLS_TIMELINE_CONTAINER) +{ +} + +PassRefPtr<MediaControlTimelineContainerElement> MediaControlTimelineContainerElement::create(HTMLMediaElement* mediaElement) { + return new MediaControlTimelineContainerElement(mediaElement); } bool MediaControlTimelineContainerElement::rendererIsNeeded(RenderStyle* style) @@ -213,23 +233,28 @@ bool MediaControlTimelineContainerElement::rendererIsNeeded(RenderStyle* style) // This is for MediaControllerThemeClassic: // If there is no style for MediaControlStatusDisplayElement style, don't hide // the timeline. - if (!m_mediaElement->renderer()->getCachedPseudoStyle(MEDIA_CONTROLS_STATUS_DISPLAY)) + if (!mediaElement()->renderer()->getCachedPseudoStyle(MEDIA_CONTROLS_STATUS_DISPLAY)) return true; - float duration = m_mediaElement->duration(); + float duration = mediaElement()->duration(); return !isnan(duration) && !isinf(duration); } // ---------------------------- -MediaControlVolumeSliderContainerElement::MediaControlVolumeSliderContainerElement(Document* doc, HTMLMediaElement* element) - : MediaControlElement(doc, MEDIA_CONTROLS_VOLUME_SLIDER_CONTAINER, element) +inline MediaControlVolumeSliderContainerElement::MediaControlVolumeSliderContainerElement(HTMLMediaElement* mediaElement) + : MediaControlElement(mediaElement, MEDIA_CONTROLS_VOLUME_SLIDER_CONTAINER) , m_isVisible(false) , m_x(0) , m_y(0) { } +PassRefPtr<MediaControlVolumeSliderContainerElement> MediaControlVolumeSliderContainerElement::create(HTMLMediaElement* mediaElement) +{ + return new MediaControlVolumeSliderContainerElement(mediaElement); +} + PassRefPtr<RenderStyle> MediaControlVolumeSliderContainerElement::styleForElement() { RefPtr<RenderStyle> style = MediaControlElement::styleForElement(); @@ -265,12 +290,17 @@ bool MediaControlVolumeSliderContainerElement::hitTest(const IntPoint& absPoint) // ---------------------------- -MediaControlStatusDisplayElement::MediaControlStatusDisplayElement(Document* document, HTMLMediaElement* element) - : MediaControlElement(document, MEDIA_CONTROLS_STATUS_DISPLAY, element) +inline MediaControlStatusDisplayElement::MediaControlStatusDisplayElement(HTMLMediaElement* mediaElement) + : MediaControlElement(mediaElement, MEDIA_CONTROLS_STATUS_DISPLAY) , m_stateBeingDisplayed(Nothing) { } +PassRefPtr<MediaControlStatusDisplayElement> MediaControlStatusDisplayElement::create(HTMLMediaElement* mediaElement) +{ + return new MediaControlStatusDisplayElement(mediaElement); +} + void MediaControlStatusDisplayElement::update() { MediaControlElement::update(); @@ -278,9 +308,9 @@ void MediaControlStatusDisplayElement::update() // Get the new state that we'll have to display. StateBeingDisplayed newStateToDisplay = Nothing; - if (m_mediaElement->readyState() != HTMLMediaElement::HAVE_ENOUGH_DATA && !m_mediaElement->currentSrc().isEmpty()) + if (mediaElement()->readyState() != HTMLMediaElement::HAVE_ENOUGH_DATA && !mediaElement()->currentSrc().isEmpty()) newStateToDisplay = Loading; - else if (m_mediaElement->movieLoadType() == MediaPlayer::LiveStream) + else if (mediaElement()->movieLoadType() == MediaPlayer::LiveStream) newStateToDisplay = LiveBroadcast; // Propagate only if needed. @@ -306,14 +336,14 @@ bool MediaControlStatusDisplayElement::rendererIsNeeded(RenderStyle* style) { if (!MediaControlElement::rendererIsNeeded(style)) return false; - float duration = m_mediaElement->duration(); + float duration = mediaElement()->duration(); return (isnan(duration) || isinf(duration)); } // ---------------------------- -MediaControlInputElement::MediaControlInputElement(Document* document, PseudoId pseudo, const String& type, HTMLMediaElement* mediaElement) - : HTMLInputElement(inputTag, document) +MediaControlInputElement::MediaControlInputElement(HTMLMediaElement* mediaElement, PseudoId pseudo, const String& type) + : HTMLInputElement(inputTag, mediaElement->document()) , m_mediaElement(mediaElement) , m_pseudoStyleId(pseudo) { @@ -372,7 +402,7 @@ void MediaControlInputElement::update() PassRefPtr<RenderStyle> MediaControlInputElement::styleForElement() { - return m_mediaElement->renderer()->getCachedPseudoStyle(m_pseudoStyleId); + return mediaElement()->renderer()->getCachedPseudoStyle(m_pseudoStyleId); } bool MediaControlInputElement::rendererIsNeeded(RenderStyle* style) @@ -380,7 +410,7 @@ bool MediaControlInputElement::rendererIsNeeded(RenderStyle* style) ASSERT(document()->page()); return HTMLInputElement::rendererIsNeeded(style) && parent() && parent()->renderer() - && (!style->hasAppearance() || document()->page()->theme()->shouldRenderMediaControlPart(style->appearance(), m_mediaElement)); + && (!style->hasAppearance() || document()->page()->theme()->shouldRenderMediaControlPart(style->appearance(), mediaElement())); } void MediaControlInputElement::attach() @@ -392,7 +422,7 @@ void MediaControlInputElement::attach() bool needsRenderer = rendererIsNeeded(style.get()); if (!needsRenderer) return; - RenderObject* renderer = createRenderer(m_mediaElement->renderer()->renderArena(), style.get()); + RenderObject* renderer = createRenderer(mediaElement()->renderer()->renderArena(), style.get()); if (!renderer) return; renderer->setStyle(style.get()); @@ -409,7 +439,7 @@ void MediaControlInputElement::attach() void MediaControlInputElement::updateStyle() { - if (!m_mediaElement || !m_mediaElement->renderer()) + if (!mediaElement() || !mediaElement()->renderer()) return; RefPtr<RenderStyle> style = styleForElement(); @@ -445,15 +475,20 @@ void MediaControlInputElement::setDisplayType(MediaControlElementType displayTyp // ---------------------------- -MediaControlMuteButtonElement::MediaControlMuteButtonElement(Document* document, HTMLMediaElement* element) - : MediaControlInputElement(document, MEDIA_CONTROLS_MUTE_BUTTON, "button", element) +inline MediaControlMuteButtonElement::MediaControlMuteButtonElement(HTMLMediaElement* mediaElement) + : MediaControlInputElement(mediaElement, MEDIA_CONTROLS_MUTE_BUTTON, "button") +{ +} + +PassRefPtr<MediaControlMuteButtonElement> MediaControlMuteButtonElement::create(HTMLMediaElement* mediaElement) { + return new MediaControlMuteButtonElement(mediaElement); } void MediaControlMuteButtonElement::defaultEventHandler(Event* event) { if (event->type() == eventNames().clickEvent) { - m_mediaElement->setMuted(!m_mediaElement->muted()); + mediaElement()->setMuted(!mediaElement()->muted()); event->setDefaultHandled(); } HTMLInputElement::defaultEventHandler(event); @@ -461,20 +496,25 @@ void MediaControlMuteButtonElement::defaultEventHandler(Event* event) void MediaControlMuteButtonElement::updateDisplayType() { - setDisplayType(m_mediaElement->muted() ? MediaUnMuteButton : MediaMuteButton); + setDisplayType(mediaElement()->muted() ? MediaUnMuteButton : MediaMuteButton); } // ---------------------------- -MediaControlPlayButtonElement::MediaControlPlayButtonElement(Document* document, HTMLMediaElement* element) - : MediaControlInputElement(document, MEDIA_CONTROLS_PLAY_BUTTON, "button", element) +inline MediaControlPlayButtonElement::MediaControlPlayButtonElement(HTMLMediaElement* mediaElement) + : MediaControlInputElement(mediaElement, MEDIA_CONTROLS_PLAY_BUTTON, "button") +{ +} + +PassRefPtr<MediaControlPlayButtonElement> MediaControlPlayButtonElement::create(HTMLMediaElement* mediaElement) { + return new MediaControlPlayButtonElement(mediaElement); } void MediaControlPlayButtonElement::defaultEventHandler(Event* event) { if (event->type() == eventNames().clickEvent) { - m_mediaElement->togglePlayState(); + mediaElement()->togglePlayState(); event->setDefaultHandled(); } HTMLInputElement::defaultEventHandler(event); @@ -482,21 +522,29 @@ void MediaControlPlayButtonElement::defaultEventHandler(Event* event) void MediaControlPlayButtonElement::updateDisplayType() { - setDisplayType(m_mediaElement->canPlay() ? MediaPlayButton : MediaPauseButton); + setDisplayType(mediaElement()->canPlay() ? MediaPlayButton : MediaPauseButton); } // ---------------------------- -MediaControlSeekButtonElement::MediaControlSeekButtonElement(Document* document, HTMLMediaElement* element, bool forward) - : MediaControlInputElement(document, forward ? MEDIA_CONTROLS_SEEK_FORWARD_BUTTON : MEDIA_CONTROLS_SEEK_BACK_BUTTON, - "button", element) - , m_forward(forward) +inline MediaControlSeekButtonElement::MediaControlSeekButtonElement(HTMLMediaElement* mediaElement, PseudoId pseudoId) + : MediaControlInputElement(mediaElement, pseudoId, "button") , m_seeking(false) , m_capturing(false) , m_seekTimer(this, &MediaControlSeekButtonElement::seekTimerFired) { } +PassRefPtr<MediaControlSeekButtonElement> MediaControlSeekButtonElement::create(HTMLMediaElement* mediaElement, PseudoId pseudoStyleId) +{ + return new MediaControlSeekButtonElement(mediaElement, pseudoStyleId); +} + +inline bool MediaControlSeekButtonElement::isForwardButton() const +{ + return pseudoStyleId() == MEDIA_CONTROLS_SEEK_FORWARD_BUTTON; +} + void MediaControlSeekButtonElement::defaultEventHandler(Event* event) { if (event->type() == eventNames().mousedownEvent) { @@ -504,7 +552,7 @@ void MediaControlSeekButtonElement::defaultEventHandler(Event* event) m_capturing = true; frame->eventHandler()->setCapturingMouseEventsNode(this); } - m_mediaElement->pause(event->fromUserGesture()); + mediaElement()->pause(event->fromUserGesture()); m_seekTimer.startRepeating(cSeekRepeatDelay); event->setDefaultHandled(); } else if (event->type() == eventNames().mouseupEvent) { @@ -516,8 +564,8 @@ void MediaControlSeekButtonElement::defaultEventHandler(Event* event) ExceptionCode ec; if (m_seeking || m_seekTimer.isActive()) { if (!m_seeking) { - float stepTime = m_forward ? cStepTime : -cStepTime; - m_mediaElement->setCurrentTime(m_mediaElement->currentTime() + stepTime, ec); + float stepTime = isForwardButton() ? cStepTime : -cStepTime; + mediaElement()->setCurrentTime(mediaElement()->currentTime() + stepTime, ec); } m_seekTimer.stop(); m_seeking = false; @@ -531,8 +579,8 @@ void MediaControlSeekButtonElement::seekTimerFired(Timer<MediaControlSeekButtonE { ExceptionCode ec; m_seeking = true; - float seekTime = m_forward ? cSeekTime : -cSeekTime; - m_mediaElement->setCurrentTime(m_mediaElement->currentTime() + seekTime, ec); + float seekTime = isForwardButton() ? cSeekTime : -cSeekTime; + mediaElement()->setCurrentTime(mediaElement()->currentTime() + seekTime, ec); } void MediaControlSeekButtonElement::detach() @@ -544,18 +592,22 @@ void MediaControlSeekButtonElement::detach() MediaControlInputElement::detach(); } - // ---------------------------- -MediaControlRewindButtonElement::MediaControlRewindButtonElement(Document* document, HTMLMediaElement* element) - : MediaControlInputElement(document, MEDIA_CONTROLS_REWIND_BUTTON, "button", element) +inline MediaControlRewindButtonElement::MediaControlRewindButtonElement(HTMLMediaElement* element) + : MediaControlInputElement(element, MEDIA_CONTROLS_REWIND_BUTTON, "button") { } +PassRefPtr<MediaControlRewindButtonElement> MediaControlRewindButtonElement::create(HTMLMediaElement* mediaElement) +{ + return new MediaControlRewindButtonElement(mediaElement); +} + void MediaControlRewindButtonElement::defaultEventHandler(Event* event) { if (event->type() == eventNames().clickEvent) { - m_mediaElement->rewind(30); + mediaElement()->rewind(30); event->setDefaultHandled(); } HTMLInputElement::defaultEventHandler(event); @@ -564,15 +616,20 @@ void MediaControlRewindButtonElement::defaultEventHandler(Event* event) // ---------------------------- -MediaControlReturnToRealtimeButtonElement::MediaControlReturnToRealtimeButtonElement(Document* document, HTMLMediaElement* element) - : MediaControlInputElement(document, MEDIA_CONTROLS_RETURN_TO_REALTIME_BUTTON, "button", element) +inline MediaControlReturnToRealtimeButtonElement::MediaControlReturnToRealtimeButtonElement(HTMLMediaElement* mediaElement) + : MediaControlInputElement(mediaElement, MEDIA_CONTROLS_RETURN_TO_REALTIME_BUTTON, "button") { } +PassRefPtr<MediaControlReturnToRealtimeButtonElement> MediaControlReturnToRealtimeButtonElement::create(HTMLMediaElement* mediaElement) +{ + return new MediaControlReturnToRealtimeButtonElement(mediaElement); +} + void MediaControlReturnToRealtimeButtonElement::defaultEventHandler(Event* event) { if (event->type() == eventNames().clickEvent) { - m_mediaElement->returnToRealtime(); + mediaElement()->returnToRealtime(); event->setDefaultHandled(); } HTMLInputElement::defaultEventHandler(event); @@ -581,16 +638,21 @@ void MediaControlReturnToRealtimeButtonElement::defaultEventHandler(Event* event // ---------------------------- -MediaControlToggleClosedCaptionsButtonElement::MediaControlToggleClosedCaptionsButtonElement(Document* doc, HTMLMediaElement* element) - : MediaControlInputElement(doc, MEDIA_CONTROLS_TOGGLE_CLOSED_CAPTIONS_BUTTON, "button", element) +inline MediaControlToggleClosedCaptionsButtonElement::MediaControlToggleClosedCaptionsButtonElement(HTMLMediaElement* mediaElement) + : MediaControlInputElement(mediaElement, MEDIA_CONTROLS_TOGGLE_CLOSED_CAPTIONS_BUTTON, "button") { } +PassRefPtr<MediaControlToggleClosedCaptionsButtonElement> MediaControlToggleClosedCaptionsButtonElement::create(HTMLMediaElement* mediaElement) +{ + return new MediaControlToggleClosedCaptionsButtonElement(mediaElement); +} + void MediaControlToggleClosedCaptionsButtonElement::defaultEventHandler(Event* event) { if (event->type() == eventNames().clickEvent) { - m_mediaElement->setClosedCaptionsVisible(!m_mediaElement->closedCaptionsVisible()); - setChecked(m_mediaElement->closedCaptionsVisible()); + mediaElement()->setClosedCaptionsVisible(!mediaElement()->closedCaptionsVisible()); + setChecked(mediaElement()->closedCaptionsVisible()); event->setDefaultHandled(); } HTMLInputElement::defaultEventHandler(event); @@ -598,17 +660,21 @@ void MediaControlToggleClosedCaptionsButtonElement::defaultEventHandler(Event* e void MediaControlToggleClosedCaptionsButtonElement::updateDisplayType() { - setDisplayType(m_mediaElement->closedCaptionsVisible() ? MediaHideClosedCaptionsButton : MediaShowClosedCaptionsButton); + setDisplayType(mediaElement()->closedCaptionsVisible() ? MediaHideClosedCaptionsButton : MediaShowClosedCaptionsButton); } - // ---------------------------- -MediaControlTimelineElement::MediaControlTimelineElement(Document* document, HTMLMediaElement* element) - : MediaControlInputElement(document, MEDIA_CONTROLS_TIMELINE, "range", element) +MediaControlTimelineElement::MediaControlTimelineElement(HTMLMediaElement* mediaElement) + : MediaControlInputElement(mediaElement, MEDIA_CONTROLS_TIMELINE, "range") { } +PassRefPtr<MediaControlTimelineElement> MediaControlTimelineElement::create(HTMLMediaElement* mediaElement) +{ + return new MediaControlTimelineElement(mediaElement); +} + void MediaControlTimelineElement::defaultEventHandler(Event* event) { // Left button is 0. Rejects mouse events not from left button. @@ -619,7 +685,7 @@ void MediaControlTimelineElement::defaultEventHandler(Event* event) return; if (event->type() == eventNames().mousedownEvent) - m_mediaElement->beginScrubbing(); + mediaElement()->beginScrubbing(); MediaControlInputElement::defaultEventHandler(event); @@ -627,34 +693,39 @@ void MediaControlTimelineElement::defaultEventHandler(Event* event) return; float time = narrowPrecisionToFloat(value().toDouble()); - if (time != m_mediaElement->currentTime()) { + if (time != mediaElement()->currentTime()) { ExceptionCode ec; - m_mediaElement->setCurrentTime(time, ec); + mediaElement()->setCurrentTime(time, ec); } RenderSlider* slider = toRenderSlider(renderer()); if (slider && slider->inDragMode()) - toRenderMedia(m_mediaElement->renderer())->updateTimeDisplay(); + toRenderMedia(mediaElement()->renderer())->updateTimeDisplay(); if (event->type() == eventNames().mouseupEvent) - m_mediaElement->endScrubbing(); + mediaElement()->endScrubbing(); } void MediaControlTimelineElement::update(bool updateDuration) { if (updateDuration) { - float dur = m_mediaElement->duration(); - setAttribute(maxAttr, String::number(isfinite(dur) ? dur : 0)); + float duration = mediaElement()->duration(); + setAttribute(maxAttr, String::number(isfinite(duration) ? duration : 0)); } - setValue(String::number(m_mediaElement->currentTime())); + setValue(String::number(mediaElement()->currentTime())); MediaControlInputElement::update(); } // ---------------------------- -MediaControlVolumeSliderElement::MediaControlVolumeSliderElement(Document* document, HTMLMediaElement* element) - : MediaControlInputElement(document, MEDIA_CONTROLS_VOLUME_SLIDER, "range", element) +inline MediaControlVolumeSliderElement::MediaControlVolumeSliderElement(HTMLMediaElement* mediaElement) + : MediaControlInputElement(mediaElement, MEDIA_CONTROLS_VOLUME_SLIDER, "range") +{ +} + +PassRefPtr<MediaControlVolumeSliderElement> MediaControlVolumeSliderElement::create(HTMLMediaElement* mediaElement) { + return new MediaControlVolumeSliderElement(mediaElement); } void MediaControlVolumeSliderElement::defaultEventHandler(Event* event) @@ -672,16 +743,16 @@ void MediaControlVolumeSliderElement::defaultEventHandler(Event* event) return; float volume = narrowPrecisionToFloat(value().toDouble()); - if (volume != m_mediaElement->volume()) { + if (volume != mediaElement()->volume()) { ExceptionCode ec = 0; - m_mediaElement->setVolume(volume, ec); + mediaElement()->setVolume(volume, ec); ASSERT(!ec); } } void MediaControlVolumeSliderElement::update() { - float volume = m_mediaElement->volume(); + float volume = mediaElement()->volume(); if (value().toFloat() != volume) setValue(String::number(volume)); MediaControlInputElement::update(); @@ -689,15 +760,20 @@ void MediaControlVolumeSliderElement::update() // ---------------------------- -MediaControlFullscreenButtonElement::MediaControlFullscreenButtonElement(Document* document, HTMLMediaElement* element) - : MediaControlInputElement(document, MEDIA_CONTROLS_FULLSCREEN_BUTTON, "button", element) +inline MediaControlFullscreenButtonElement::MediaControlFullscreenButtonElement(HTMLMediaElement* mediaElement) + : MediaControlInputElement(mediaElement, MEDIA_CONTROLS_FULLSCREEN_BUTTON, "button") +{ +} + +PassRefPtr<MediaControlFullscreenButtonElement> MediaControlFullscreenButtonElement::create(HTMLMediaElement* mediaElement) { + return new MediaControlFullscreenButtonElement(mediaElement); } void MediaControlFullscreenButtonElement::defaultEventHandler(Event* event) { if (event->type() == eventNames().clickEvent) { - m_mediaElement->enterFullscreen(); + mediaElement()->enterFullscreen(); event->setDefaultHandled(); } HTMLInputElement::defaultEventHandler(event); @@ -705,13 +781,18 @@ void MediaControlFullscreenButtonElement::defaultEventHandler(Event* event) // ---------------------------- -MediaControlTimeDisplayElement::MediaControlTimeDisplayElement(Document* document, PseudoId pseudo, HTMLMediaElement* element) - : MediaControlElement(document, pseudo, element) +inline MediaControlTimeDisplayElement::MediaControlTimeDisplayElement(HTMLMediaElement* mediaElement, PseudoId pseudo) + : MediaControlElement(mediaElement, pseudo) , m_currentValue(0) , m_isVisible(true) { } +PassRefPtr<MediaControlTimeDisplayElement> MediaControlTimeDisplayElement::create(HTMLMediaElement* mediaElement, PseudoId pseudoStyleId) +{ + return new MediaControlTimeDisplayElement(mediaElement, pseudoStyleId); +} + PassRefPtr<RenderStyle> MediaControlTimeDisplayElement::styleForElement() { RefPtr<RenderStyle> style = MediaControlElement::styleForElement(); @@ -742,6 +823,6 @@ void MediaControlTimeDisplayElement::setCurrentValue(float time) m_currentValue = time; } +} // namespace WebCore -} //namespace WebCore -#endif // enable(video) +#endif // ENABLE(VIDEO) diff --git a/WebCore/rendering/MediaControlElements.h b/WebCore/rendering/MediaControlElements.h index 21831ce..68c06a3 100644 --- a/WebCore/rendering/MediaControlElements.h +++ b/WebCore/rendering/MediaControlElements.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2008, 2009, 2010 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -72,14 +72,16 @@ HTMLMediaElement* toParentMediaElement(RenderObject*); class MediaControlShadowRootElement : public HTMLDivElement { public: - MediaControlShadowRootElement(Document*, HTMLMediaElement*); - - virtual bool isShadowNode() const { return true; } - virtual Node* shadowParentNode() { return m_mediaElement; } + static PassRefPtr<MediaControlShadowRootElement> create(HTMLMediaElement*); void updateStyle(); private: + MediaControlShadowRootElement(HTMLMediaElement*); + + virtual bool isShadowNode() const { return true; } + virtual Node* shadowParentNode() { return m_mediaElement; } + HTMLMediaElement* m_mediaElement; }; @@ -87,21 +89,27 @@ private: class MediaControlElement : public HTMLDivElement { public: - MediaControlElement(Document*, PseudoId, HTMLMediaElement*); - virtual void attach(); - virtual bool rendererIsNeeded(RenderStyle*); + static PassRefPtr<MediaControlElement> create(HTMLMediaElement*, PseudoId); - virtual PassRefPtr<RenderStyle> styleForElement(); + virtual void attach(); void attachToParent(Element*); void update(); - virtual void updateStyle(); + void updateStyle(); MediaControlElementType displayType() const { return m_displayType; } HTMLMediaElement* mediaElement() const { return m_mediaElement; } - virtual bool isMediaControlElement() const { return true; } protected: + MediaControlElement(HTMLMediaElement*, PseudoId); + + virtual bool rendererIsNeeded(RenderStyle*); + + virtual PassRefPtr<RenderStyle> styleForElement(); + +private: + virtual bool isMediaControlElement() const { return true; } + HTMLMediaElement* m_mediaElement; PseudoId m_pseudoStyleId; MediaControlElementType m_displayType; // some elements can show multiple types (e.g. play/pause) @@ -111,7 +119,10 @@ protected: class MediaControlTimelineContainerElement : public MediaControlElement { public: - MediaControlTimelineContainerElement(Document*, HTMLMediaElement*); + static PassRefPtr<MediaControlTimelineContainerElement> create(HTMLMediaElement*); + +private: + MediaControlTimelineContainerElement(HTMLMediaElement*); virtual bool rendererIsNeeded(RenderStyle*); }; @@ -119,7 +130,8 @@ public: class MediaControlVolumeSliderContainerElement : public MediaControlElement { public: - MediaControlVolumeSliderContainerElement(Document*, HTMLMediaElement*); + static PassRefPtr<MediaControlVolumeSliderContainerElement> create(HTMLMediaElement*); + virtual PassRefPtr<RenderStyle> styleForElement(); void setVisible(bool); bool isVisible() { return m_isVisible; } @@ -127,6 +139,8 @@ public: bool hitTest(const IntPoint& absPoint); private: + MediaControlVolumeSliderContainerElement(HTMLMediaElement*); + bool m_isVisible; int m_x, m_y; }; @@ -135,10 +149,15 @@ private: class MediaControlStatusDisplayElement : public MediaControlElement { public: - MediaControlStatusDisplayElement(Document*, HTMLMediaElement*); - virtual void update(); - virtual bool rendererIsNeeded(RenderStyle*); + static PassRefPtr<MediaControlStatusDisplayElement> create(HTMLMediaElement*); + + void update(); + private: + MediaControlStatusDisplayElement(HTMLMediaElement*); + + virtual bool rendererIsNeeded(RenderStyle*); + enum StateBeingDisplayed { Nothing, Loading, LiveBroadcast }; StateBeingDisplayed m_stateBeingDisplayed; }; @@ -147,25 +166,33 @@ private: class MediaControlInputElement : public HTMLInputElement { public: - MediaControlInputElement(Document*, PseudoId, const String& type, HTMLMediaElement*); - virtual void attach(); - virtual bool rendererIsNeeded(RenderStyle*); - - virtual PassRefPtr<RenderStyle> styleForElement(); void attachToParent(Element*); void update(); void updateStyle(); bool hitTest(const IntPoint& absPoint); + MediaControlElementType displayType() const { return m_displayType; } HTMLMediaElement* mediaElement() const { return m_mediaElement; } - virtual bool isMediaControlElement() const { return true; } protected: - virtual void updateDisplayType() { } + MediaControlInputElement(HTMLMediaElement*, PseudoId, const String& type); + void setDisplayType(MediaControlElementType); + PseudoId pseudoStyleId() const { return m_pseudoStyleId; } + +private: + virtual void attach(); + virtual bool rendererIsNeeded(RenderStyle*); + + virtual PassRefPtr<RenderStyle> styleForElement(); + + virtual bool isMediaControlElement() const { return true; } + + virtual void updateDisplayType() { } + HTMLMediaElement* m_mediaElement; PseudoId m_pseudoStyleId; MediaControlElementType m_displayType; @@ -175,8 +202,13 @@ protected: class MediaControlMuteButtonElement : public MediaControlInputElement { public: - MediaControlMuteButtonElement(Document*, HTMLMediaElement*); + static PassRefPtr<MediaControlMuteButtonElement> create(HTMLMediaElement*); + virtual void defaultEventHandler(Event*); + +private: + MediaControlMuteButtonElement(HTMLMediaElement*); + virtual void updateDisplayType(); }; @@ -184,8 +216,13 @@ public: class MediaControlPlayButtonElement : public MediaControlInputElement { public: - MediaControlPlayButtonElement(Document*, HTMLMediaElement*); + static PassRefPtr<MediaControlPlayButtonElement> create(HTMLMediaElement*); + virtual void defaultEventHandler(Event*); + +private: + MediaControlPlayButtonElement(HTMLMediaElement*); + virtual void updateDisplayType(); }; @@ -193,13 +230,18 @@ public: class MediaControlSeekButtonElement : public MediaControlInputElement { public: - MediaControlSeekButtonElement(Document*, HTMLMediaElement*, bool forward); + static PassRefPtr<MediaControlSeekButtonElement> create(HTMLMediaElement*, PseudoId); + virtual void defaultEventHandler(Event*); + +private: + MediaControlSeekButtonElement(HTMLMediaElement*, PseudoId); + + bool isForwardButton() const; + virtual void detach(); void seekTimerFired(Timer<MediaControlSeekButtonElement>*); -private: - bool m_forward; bool m_seeking; bool m_capturing; Timer<MediaControlSeekButtonElement> m_seekTimer; @@ -209,24 +251,37 @@ private: class MediaControlRewindButtonElement : public MediaControlInputElement { public: - MediaControlRewindButtonElement(Document*, HTMLMediaElement*); + static PassRefPtr<MediaControlRewindButtonElement> create(HTMLMediaElement*); + virtual void defaultEventHandler(Event*); + +private: + MediaControlRewindButtonElement(HTMLMediaElement*); }; // ---------------------------- class MediaControlReturnToRealtimeButtonElement : public MediaControlInputElement { public: - MediaControlReturnToRealtimeButtonElement(Document*, HTMLMediaElement*); + static PassRefPtr<MediaControlReturnToRealtimeButtonElement> create(HTMLMediaElement*); + virtual void defaultEventHandler(Event*); + +private: + MediaControlReturnToRealtimeButtonElement(HTMLMediaElement*); }; // ---------------------------- class MediaControlToggleClosedCaptionsButtonElement : public MediaControlInputElement { public: - MediaControlToggleClosedCaptionsButtonElement(Document*, HTMLMediaElement*); + static PassRefPtr<MediaControlToggleClosedCaptionsButtonElement> create(HTMLMediaElement*); + virtual void defaultEventHandler(Event*); + +private: + MediaControlToggleClosedCaptionsButtonElement(HTMLMediaElement*); + virtual void updateDisplayType(); }; @@ -234,40 +289,55 @@ public: class MediaControlTimelineElement : public MediaControlInputElement { public: - MediaControlTimelineElement(Document*, HTMLMediaElement*); + static PassRefPtr<MediaControlTimelineElement> create(HTMLMediaElement*); + virtual void defaultEventHandler(Event*); void update(bool updateDuration = true); + +private: + MediaControlTimelineElement(HTMLMediaElement*); }; // ---------------------------- class MediaControlVolumeSliderElement : public MediaControlInputElement { public: - MediaControlVolumeSliderElement(Document*, HTMLMediaElement*); + static PassRefPtr<MediaControlVolumeSliderElement> create(HTMLMediaElement*); + virtual void defaultEventHandler(Event*); - virtual void update(); + void update(); + +private: + MediaControlVolumeSliderElement(HTMLMediaElement*); }; // ---------------------------- class MediaControlFullscreenButtonElement : public MediaControlInputElement { public: - MediaControlFullscreenButtonElement(Document*, HTMLMediaElement*); + static PassRefPtr<MediaControlFullscreenButtonElement> create(HTMLMediaElement*); + virtual void defaultEventHandler(Event*); + +private: + MediaControlFullscreenButtonElement(HTMLMediaElement*); }; // ---------------------------- class MediaControlTimeDisplayElement : public MediaControlElement { public: - MediaControlTimeDisplayElement(Document*, PseudoId, HTMLMediaElement*); + static PassRefPtr<MediaControlTimeDisplayElement> create(HTMLMediaElement*, PseudoId); + void setVisible(bool); - virtual PassRefPtr<RenderStyle> styleForElement(); void setCurrentValue(float); float currentValue() const { return m_currentValue; } private: + MediaControlTimeDisplayElement(HTMLMediaElement*, PseudoId); + + virtual PassRefPtr<RenderStyle> styleForElement(); float m_currentValue; bool m_isVisible; }; @@ -282,7 +352,8 @@ public: // ---------------------------- - } //namespace WebCore -#endif // enable(video) + +#endif // ENABLE(VIDEO) + #endif // MediaControlElements_h diff --git a/WebCore/rendering/RenderBlock.cpp b/WebCore/rendering/RenderBlock.cpp index 9ea5209..5ac57f0 100644 --- a/WebCore/rendering/RenderBlock.cpp +++ b/WebCore/rendering/RenderBlock.cpp @@ -239,6 +239,12 @@ void RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldSty if (child->isAnonymousBlock()) { RefPtr<RenderStyle> newStyle = RenderStyle::create(); newStyle->inheritFrom(style()); + if (style()->specifiesColumns()) { + if (child->style()->specifiesColumns()) + newStyle->inheritColumnPropertiesFrom(style()); + if (child->style()->columnSpan()) + newStyle->setColumnSpan(true); + } newStyle->setDisplay(BLOCK); child->setStyle(newStyle.release()); } @@ -261,19 +267,181 @@ void RenderBlock::updateBeforeAfterContent(PseudoId pseudoId) return; return children()->updateBeforeAfterContent(this, pseudoId); } + +void RenderBlock::addChildToAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild) +{ + ASSERT(!continuation()); // We don't yet support column spans that aren't immediate children of the multi-column block. + + // The goal is to locate a suitable box in which to place our child. + RenderBlock* beforeChildParent = toRenderBlock(beforeChild ? beforeChild->parent() : lastChild()); -void RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild) + // If the new child is floating or positioned it can just go in that block. + if (newChild->isFloatingOrPositioned()) + return beforeChildParent->addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild); + + // See if the child can be placed in the box. + bool newChildHasColumnSpan = newChild->style()->columnSpan() && !newChild->isInline(); + bool beforeChildParentHoldsColumnSpans = beforeChildParent->isAnonymousColumnSpanBlock(); + + if (newChildHasColumnSpan == beforeChildParentHoldsColumnSpans) + return beforeChildParent->addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild); + + if (!beforeChild) { + // Create a new block of the correct type. + RenderBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanBlock() : createAnonymousColumnsBlock(); + children()->appendChildNode(this, newBox); + newBox->addChildIgnoringAnonymousColumnBlocks(newChild, 0); + return; + } + + RenderObject* immediateChild = beforeChild; + bool isPreviousBlockViable = true; + while (immediateChild->parent() != this) { + if (isPreviousBlockViable) + isPreviousBlockViable = !immediateChild->previousSibling(); + immediateChild = immediateChild->parent(); + } + if (isPreviousBlockViable && immediateChild->previousSibling()) + return toRenderBlock(immediateChild->previousSibling())->addChildIgnoringAnonymousColumnBlocks(newChild, 0); // Treat like an append. + + // Split our anonymous blocks. + RenderObject* newBeforeChild = splitAnonymousBlocksAroundChild(beforeChild); + + // Create a new anonymous box of the appropriate type. + RenderBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanBlock() : createAnonymousColumnsBlock(); + children()->insertChildNode(this, newBox, newBeforeChild); + newBox->addChildIgnoringAnonymousColumnBlocks(newChild, 0); + return; +} + +RenderObject* RenderBlock::splitAnonymousBlocksAroundChild(RenderObject* beforeChild) +{ + while (beforeChild->parent() != this) { + RenderBlock* blockToSplit = toRenderBlock(beforeChild->parent()); + ASSERT(blockToSplit->isAnonymousBlock() && !blockToSplit->continuation()); + + if (blockToSplit->firstChild() != beforeChild) { + // We have to split the parentBlock into two blocks. + RenderBlock* post = createAnonymousBlockWithSameTypeAs(blockToSplit); + post->setChildrenInline(blockToSplit->childrenInline()); + RenderBlock* parentBlock = toRenderBlock(blockToSplit->parent()); + parentBlock->children()->insertChildNode(parentBlock, post, blockToSplit->nextSibling()); + blockToSplit->moveChildrenTo(post, beforeChild, 0, blockToSplit->hasLayer()); + post->setNeedsLayoutAndPrefWidthsRecalc(); + blockToSplit->setNeedsLayoutAndPrefWidthsRecalc(); + beforeChild = post; + } else + beforeChild = blockToSplit; + } + + return beforeChild; +} + +void RenderBlock::makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, RenderBlock* newBlockBox, RenderObject* newChild) +{ + RenderBlock* pre = 0; + RenderBlock* post = 0; + RenderBlock* block = this; // Eventually block will not just be |this|, but will also be a block nested inside |this|. Assign to a variable + // so that we don't have to patch all of the rest of the code later on. + + // Delete the block's line boxes before we do the split. + block->deleteLineBoxTree(); + + if (beforeChild && beforeChild->parent() != this) + beforeChild = splitAnonymousBlocksAroundChild(beforeChild); + + if (beforeChild != firstChild()) { + pre = block->createAnonymousColumnsBlock(); + pre->setChildrenInline(block->childrenInline()); + } + + if (beforeChild) { + post = block->createAnonymousColumnsBlock(); + post->setChildrenInline(block->childrenInline()); + } + + RenderObject* boxFirst = block->firstChild(); + if (pre) + block->children()->insertChildNode(block, pre, boxFirst); + block->children()->insertChildNode(block, newBlockBox, boxFirst); + if (post) + block->children()->insertChildNode(block, post, boxFirst); + block->setChildrenInline(false); + + // The pre/post blocks always have layers, so we know to always do a full insert/remove (so we pass true as the last argument). + block->moveChildrenTo(pre, boxFirst, beforeChild, true); + block->moveChildrenTo(post, beforeChild, 0, true); + + // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting + // time in makeChildrenNonInline by just setting this explicitly up front. + newBlockBox->setChildrenInline(false); + + // We delayed adding the newChild until now so that the |newBlockBox| would be fully + // connected, thus allowing newChild access to a renderArena should it need + // to wrap itself in additional boxes (e.g., table construction). + newBlockBox->addChild(newChild); + + // Always just do a full layout in order to ensure that line boxes (especially wrappers for images) + // get deleted properly. Because objects moved from the pre block into the post block, we want to + // make new line boxes instead of leaving the old line boxes around. + if (pre) + pre->setNeedsLayoutAndPrefWidthsRecalc(); + block->setNeedsLayoutAndPrefWidthsRecalc(); + if (post) + post->setNeedsLayoutAndPrefWidthsRecalc(); +} + +static RenderBlock* columnsBlockForSpanningElement(RenderBlock* block, RenderObject* newChild) +{ + // FIXME: The style of this function may seem weird. + // This function is the gateway for the addition of column-span support. Support will be added in three stages: + // (1) Immediate children of a multi-column block can span. + // (2) Nested block-level children with only block-level ancestors between them and the multi-column block can span. + // (3) Nested children with block or inline ancestors between them and the multi-column block can span (this is when we + // cross the streams and have to cope with both types of continuations mixed together). + // This function currently only supports (1). + if (!newChild->isText() && newChild->style()->columnSpan() && !newChild->isFloatingOrPositioned() + && !newChild->isInline() && !block->isAnonymousColumnSpanBlock() && block->style()->specifiesColumns()) + return block; + return 0; +} + +void RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild) { // Make sure we don't append things after :after-generated content if we have it. if (!beforeChild) { RenderObject* lastRenderer = lastChild(); - if (isAfterContent(lastRenderer)) beforeChild = lastRenderer; else if (lastRenderer && lastRenderer->isAnonymousBlock() && isAfterContent(lastRenderer->lastChild())) beforeChild = lastRenderer->lastChild(); } + // Check for a spanning element in columns. + RenderBlock* columnsBlockAncestor = columnsBlockForSpanningElement(this, newChild); + if (columnsBlockAncestor) { + ASSERT(columnsBlockAncestor == this); + + // We are placing a column-span element inside a block. We have to perform a split of this + // block's children. This involves creating an anonymous block box to hold + // the column-spanning |newChild|. We take all of the children from before |newChild| and put them into + // one anonymous columns block, and all of the children after |newChild| go into another anonymous block. + RenderBlock* newBox = createAnonymousColumnSpanBlock(); + + // Someone may have put the spanning element inside an element with generated content, causing a split. When this happens, + // the :after content has to move into the last anonymous block. Call updateBeforeAfterContent to ensure that our :after + // content gets properly destroyed. + bool isLastChild = (beforeChild == lastChild()); + if (document()->usesBeforeAfterRules()) + children()->updateBeforeAfterContent(this, AFTER); + if (isLastChild && beforeChild != lastChild()) + beforeChild = 0; // We destroyed the last child, so now we need to update our insertion + // point to be 0. It's just a straight append now. + + makeChildrenAnonymousColumnBlocks(beforeChild, newBox, newChild); + return; + } + bool madeBoxesNonInline = false; // If the requested beforeChild is not one of our children, then this is because @@ -351,6 +519,13 @@ void RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild) // this object may be dead here } +void RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild) +{ + if (!isAnonymous() && firstChild() && (firstChild()->isAnonymousColumnsBlock() || firstChild()->isAnonymousColumnSpanBlock())) + return addChildToAnonymousColumnBlocks(newChild, beforeChild); + return addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild); +} + static void getInlineRun(RenderObject* start, RenderObject* boundary, RenderObject*& inlineRunStart, RenderObject*& inlineRunEnd) @@ -407,42 +582,24 @@ RootInlineBox* RenderBlock::createAndAppendRootInlineBox() m_lineBoxes.appendLineBox(rootBox); return rootBox; } - -void RenderBlock::moveChildTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* child) -{ - ASSERT(this == child->parent()); - toChildList->appendChildNode(to, children()->removeChildNode(this, child, false), false); -} -void RenderBlock::moveChildTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* beforeChild, RenderObject* child) +void RenderBlock::moveChildTo(RenderBlock* to, RenderObject* child, RenderObject* beforeChild, bool fullRemoveInsert) { ASSERT(this == child->parent()); ASSERT(!beforeChild || to == beforeChild->parent()); - toChildList->insertChildNode(to, children()->removeChildNode(this, child, false), beforeChild, false); -} - -void RenderBlock::moveAllChildrenTo(RenderObject* to, RenderObjectChildList* toChildList) -{ - RenderObject* nextChild = children()->firstChild(); - while (nextChild) { - RenderObject* child = nextChild; - nextChild = child->nextSibling(); - toChildList->appendChildNode(to, children()->removeChildNode(this, child, false), false); - } + to->children()->insertChildNode(to, children()->removeChildNode(this, child, fullRemoveInsert), beforeChild, fullRemoveInsert); } -void RenderBlock::moveAllChildrenTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* beforeChild) +void RenderBlock::moveChildrenTo(RenderBlock* to, RenderObject* startChild, RenderObject* endChild, RenderObject* beforeChild, bool fullRemoveInsert) { ASSERT(!beforeChild || to == beforeChild->parent()); - if (!beforeChild) { - moveAllChildrenTo(to, toChildList); - return; - } - RenderObject* nextChild = children()->firstChild(); - while (nextChild) { + RenderObject* nextChild = startChild; + while (nextChild && nextChild != endChild) { RenderObject* child = nextChild; nextChild = child->nextSibling(); - toChildList->insertChildNode(to, children()->removeChildNode(this, child, false), beforeChild, false); + to->children()->insertChildNode(to, children()->removeChildNode(this, child, fullRemoveInsert), beforeChild, fullRemoveInsert); + if (child == endChild) + return; } } @@ -477,14 +634,7 @@ void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint) RenderBlock* block = createAnonymousBlock(); children()->insertChildNode(this, block, inlineRunStart); - RenderObject* o = inlineRunStart; - while (o != inlineRunEnd) { - RenderObject* no = o; - o = no->nextSibling(); - - moveChildTo(block, block->children(), no); - } - moveChildTo(block, block->children(), inlineRunEnd); + moveChildrenTo(block, inlineRunStart, child); } #ifndef NDEBUG @@ -500,7 +650,7 @@ void RenderBlock::removeLeftoverAnonymousBlock(RenderBlock* child) ASSERT(child->isAnonymousBlock()); ASSERT(!child->childrenInline()); - if (child->continuation()) + if (child->continuation() || (child->firstChild() && (child->isAnonymousColumnSpanBlock() || child->isAnonymousColumnsBlock()))) return; RenderObject* firstAnChild = child->m_children.firstChild(); @@ -517,16 +667,22 @@ void RenderBlock::removeLeftoverAnonymousBlock(RenderBlock* child) child->previousSibling()->setNextSibling(firstAnChild); if (child->nextSibling()) child->nextSibling()->setPreviousSibling(lastAnChild); + + if (child == m_children.firstChild()) + m_children.setFirstChild(firstAnChild); + if (child == m_children.lastChild()) + m_children.setLastChild(lastAnChild); } else { + if (child == m_children.firstChild()) + m_children.setFirstChild(child->nextSibling()); + if (child == m_children.lastChild()) + m_children.setLastChild(child->previousSibling()); + if (child->previousSibling()) child->previousSibling()->setNextSibling(child->nextSibling()); if (child->nextSibling()) child->nextSibling()->setPreviousSibling(child->previousSibling()); } - if (child == m_children.firstChild()) - m_children.setFirstChild(firstAnChild); - if (child == m_children.lastChild()) - m_children.setLastChild(lastAnChild); child->setParent(0); child->setPreviousSibling(0); child->setNextSibling(0); @@ -537,6 +693,29 @@ void RenderBlock::removeLeftoverAnonymousBlock(RenderBlock* child) child->destroy(); } +static bool canMergeContiguousAnonymousBlocks(RenderObject* oldChild, RenderObject* prev, RenderObject* next) +{ + if (oldChild->documentBeingDestroyed() || oldChild->isInline() || oldChild->virtualContinuation()) + return false; + + if ((prev && (!prev->isAnonymousBlock() || toRenderBlock(prev)->continuation())) + || (next && (!next->isAnonymousBlock() || toRenderBlock(next)->continuation()))) + return false; + +#if ENABLE(RUBY) + if ((prev && (prev->isRubyRun() || prev->isRubyBase())) + || (next && (next->isRubyRun() || next->isRubyBase()))) + return false; +#endif + + if (!prev || !next) + return true; + + // Make sure the types of the anonymous blocks match up. + return prev->isAnonymousColumnsBlock() == next->isAnonymousColumnsBlock() + && prev->isAnonymousColumnSpanBlock() == prev->isAnonymousColumnSpanBlock(); +} + void RenderBlock::removeChild(RenderObject* oldChild) { // If this child is a block, and if our previous and next siblings are @@ -544,41 +723,65 @@ void RenderBlock::removeChild(RenderObject* oldChild) // fold the inline content back together. RenderObject* prev = oldChild->previousSibling(); RenderObject* next = oldChild->nextSibling(); - bool canDeleteAnonymousBlocks = !documentBeingDestroyed() && !isInline() && !oldChild->isInline() - && (!oldChild->isRenderBlock() || !toRenderBlock(oldChild)->continuation()) - && (!prev || (prev->isAnonymousBlock() && prev->childrenInline())) - && (!next || (next->isAnonymousBlock() && next->childrenInline())); - if (canDeleteAnonymousBlocks && prev && next) { - // Take all the children out of the |next| block and put them in - // the |prev| block. + bool canMergeAnonymousBlocks = canMergeContiguousAnonymousBlocks(oldChild, prev, next); + if (canMergeAnonymousBlocks && prev && next) { prev->setNeedsLayoutAndPrefWidthsRecalc(); RenderBlock* nextBlock = toRenderBlock(next); RenderBlock* prevBlock = toRenderBlock(prev); - nextBlock->moveAllChildrenTo(prevBlock, prevBlock->children()); - // Delete the now-empty block's lines and nuke it. - nextBlock->deleteLineBoxTree(); - nextBlock->destroy(); + + if (prev->childrenInline() != next->childrenInline()) { + RenderBlock* inlineChildrenBlock = prev->childrenInline() ? prevBlock : nextBlock; + RenderBlock* blockChildrenBlock = prev->childrenInline() ? nextBlock : prevBlock; + + // Place the inline children block inside of the block children block instead of deleting it. + // In order to reuse it, we have to reset it to just be a generic anonymous block. Make sure + // to clear out inherited column properties by just making a new style, and to also clear the + // column span flag if it is set. + ASSERT(!inlineChildrenBlock->continuation()); + RefPtr<RenderStyle> newStyle = RenderStyle::create(); + newStyle->inheritFrom(style()); + children()->removeChildNode(this, inlineChildrenBlock, inlineChildrenBlock->hasLayer()); + inlineChildrenBlock->setStyle(newStyle); + + // Now just put the inlineChildrenBlock inside the blockChildrenBlock. + blockChildrenBlock->children()->insertChildNode(blockChildrenBlock, inlineChildrenBlock, prev == inlineChildrenBlock ? blockChildrenBlock->firstChild() : 0, + inlineChildrenBlock->hasLayer() || blockChildrenBlock->hasLayer()); + next->setNeedsLayoutAndPrefWidthsRecalc(); + } else { + // Take all the children out of the |next| block and put them in + // the |prev| block. + nextBlock->moveAllChildrenTo(prevBlock, nextBlock->hasLayer() || prevBlock->hasLayer()); + + // Delete the now-empty block's lines and nuke it. + nextBlock->deleteLineBoxTree(); + nextBlock->destroy(); + } } RenderBox::removeChild(oldChild); RenderObject* child = prev ? prev : next; - if (canDeleteAnonymousBlocks && child && !child->previousSibling() && !child->nextSibling() && !isFlexibleBox()) { + if (canMergeAnonymousBlocks && child && !child->previousSibling() && !child->nextSibling() && !isFlexibleBox()) { // The removal has knocked us down to containing only a single anonymous // box. We can go ahead and pull the content right back up into our // box. setNeedsLayoutAndPrefWidthsRecalc(); - RenderBlock* anonBlock = toRenderBlock(children()->removeChildNode(this, child, false)); - setChildrenInline(true); - anonBlock->moveAllChildrenTo(this, children()); + setChildrenInline(child->childrenInline()); + RenderBlock* anonBlock = toRenderBlock(children()->removeChildNode(this, child, child->hasLayer())); + anonBlock->moveAllChildrenTo(this, child->hasLayer()); // Delete the now-empty block's lines and nuke it. anonBlock->deleteLineBoxTree(); anonBlock->destroy(); } - // If this was our last child be sure to clear out our line boxes. - if (childrenInline() && !firstChild()) - lineBoxes()->deleteLineBoxes(renderArena()); + if (!firstChild() && !documentBeingDestroyed()) { + // If this was our last child be sure to clear out our line boxes. + if (childrenInline()) + lineBoxes()->deleteLineBoxes(renderArena()); + // If we're now an empty anonymous block then go ahead and delete ourselves. + else if (isAnonymousBlock() && parent() && parent()->isRenderBlock() && !continuation()) + destroy(); + } } bool RenderBlock::isSelfCollapsingBlock() const @@ -1933,25 +2136,6 @@ void RenderBlock::paintContinuationOutlines(PaintInfo& info, int tx, int ty) table->remove(this); } -void RenderBlock::setSelectionState(SelectionState s) -{ - if (selectionState() == s) - return; - - if (s == SelectionInside && selectionState() != SelectionNone) - return; - - if ((s == SelectionStart && selectionState() == SelectionEnd) || - (s == SelectionEnd && selectionState() == SelectionStart)) - RenderBox::setSelectionState(SelectionBoth); - else - RenderBox::setSelectionState(s); - - RenderBlock* cb = containingBlock(); - if (cb && !cb->isRenderView()) - cb->setSelectionState(s); -} - bool RenderBlock::shouldPaintSelectionGaps() const { return selectionState() != SelectionNone && style()->visibility() == VISIBLE && isSelectionRoot(); @@ -2068,7 +2252,7 @@ GapRects RenderBlock::fillSelectionGaps(RenderBlock* rootBlock, int blockX, int if (!isBlockFlow()) // FIXME: Make multi-column selection gap filling work someday. return result; - if (hasColumns() || hasTransform()) { + if (hasColumns() || hasTransform() || style()->columnSpan()) { // FIXME: We should learn how to gap fill multiple columns and transforms eventually. lastTop = (ty - blockY) + height(); lastLeft = leftSelectionOffset(rootBlock, height()); @@ -3745,7 +3929,11 @@ void RenderBlock::calcColumnWidth() void RenderBlock::setDesiredColumnCountAndWidth(int count, int width) { - if (count == 1 && style()->hasAutoColumnWidth()) { + bool destroyColumns = !firstChild() + || (count == 1 && style()->hasAutoColumnWidth()) + || firstChild()->isAnonymousColumnsBlock() + || firstChild()->isAnonymousColumnSpanBlock(); + if (destroyColumns) { if (hasColumns()) { delete gColumnInfoMap->take(this); setHasColumns(false); @@ -4197,7 +4385,6 @@ void RenderBlock::calcInlinePrefWidths() InlineMinMaxIterator childIterator(this); bool addedTextIndent = false; // Only gets added in once. RenderObject* prevFloat = 0; - RenderObject* previousLeaf = 0; while (RenderObject* child = childIterator.next()) { autoWrap = child->isReplaced() ? child->parent()->style()->autoWrap() : child->style()->autoWrap(); @@ -4425,8 +4612,6 @@ void RenderBlock::calcInlinePrefWidths() } oldAutoWrap = autoWrap; - if (!child->isRenderInline()) - previousLeaf = child; } if (style()->collapseWhiteSpace()) @@ -5232,6 +5417,39 @@ RenderBlock* RenderBlock::createAnonymousBlock(bool isFlexibleBox) const return newBox; } +RenderBlock* RenderBlock::createAnonymousBlockWithSameTypeAs(RenderBlock* otherAnonymousBlock) const +{ + if (otherAnonymousBlock->isAnonymousColumnsBlock()) + return createAnonymousColumnsBlock(); + if (otherAnonymousBlock->isAnonymousColumnSpanBlock()) + return createAnonymousColumnSpanBlock(); + return createAnonymousBlock(otherAnonymousBlock->style()->display() == BOX); +} + +RenderBlock* RenderBlock::createAnonymousColumnsBlock() const +{ + RefPtr<RenderStyle> newStyle = RenderStyle::create(); + newStyle->inheritFrom(style()); + newStyle->inheritColumnPropertiesFrom(style()); + newStyle->setDisplay(BLOCK); + + RenderBlock* newBox = new (renderArena()) RenderBlock(document() /* anonymous box */); + newBox->setStyle(newStyle.release()); + return newBox; +} + +RenderBlock* RenderBlock::createAnonymousColumnSpanBlock() const +{ + RefPtr<RenderStyle> newStyle = RenderStyle::create(); + newStyle->inheritFrom(style()); + newStyle->setColumnSpan(true); + newStyle->setDisplay(BLOCK); + + RenderBlock* newBox = new (renderArena()) RenderBlock(document() /* anonymous box */); + newBox->setStyle(newStyle.release()); + return newBox; +} + const char* RenderBlock::renderName() const { if (isBody()) @@ -5241,6 +5459,10 @@ const char* RenderBlock::renderName() const return "RenderBlock (floating)"; if (isPositioned()) return "RenderBlock (positioned)"; + if (isAnonymousColumnsBlock()) + return "RenderBlock (anonymous multi-column)"; + if (isAnonymousColumnSpanBlock()) + return "RenderBlock (anonymous multi-column span)"; if (isAnonymousBlock()) return "RenderBlock (anonymous)"; else if (isAnonymous()) diff --git a/WebCore/rendering/RenderBlock.h b/WebCore/rendering/RenderBlock.h index 450912a..7d9e2fc 100644 --- a/WebCore/rendering/RenderBlock.h +++ b/WebCore/rendering/RenderBlock.h @@ -111,8 +111,6 @@ public: bool containsNonZeroBidiLevel() const; - virtual void setSelectionState(SelectionState s); - GapRects selectionGapRectsForRepaint(RenderBoxModelObject* repaintContainer); IntRect fillLeftSelectionGap(RenderObject* selObj, int xPos, int yPos, int height, RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty, const PaintInfo*); @@ -143,19 +141,41 @@ public: // This function is a convenience helper for creating an anonymous block that inherits its // style from this RenderBlock. RenderBlock* createAnonymousBlock(bool isFlexibleBox = false) const; - + RenderBlock* createAnonymousColumnsBlock() const; + RenderBlock* createAnonymousColumnSpanBlock() const; + RenderBlock* createAnonymousBlockWithSameTypeAs(RenderBlock* otherAnonymousBlock) const; + static void appendRunsForObject(int start, int end, RenderObject*, InlineBidiResolver&); static bool requiresLineBox(const InlineIterator&, bool isLineEmpty = true, bool previousLineBrokeCleanly = true); Vector<IntRect>* columnRects() const; int columnGap() const; - -protected: - void moveChildTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* child); - void moveChildTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* beforeChild, RenderObject* child); - void moveAllChildrenTo(RenderObject* to, RenderObjectChildList* toChildList); - void moveAllChildrenTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* beforeChild); +protected: + // These functions are only used internally to manipulate the render tree structure via remove/insert/appendChildNode. + // Since they are typically called only to move objects around within anonymous blocks (which only have layers in + // the case of column spans), the default for fullRemoveInsert is false rather than true. + void moveChildTo(RenderBlock* to, RenderObject* child, bool fullRemoveInsert = false) + { + return moveChildTo(to, child, 0, fullRemoveInsert); + } + void moveChildTo(RenderBlock* to, RenderObject* child, RenderObject* beforeChild, bool fullRemoveInsert = false); + void moveAllChildrenTo(RenderBlock* to, bool fullRemoveInsert = false) + { + return moveAllChildrenTo(to, 0, fullRemoveInsert); + } + void moveAllChildrenTo(RenderBlock* to, RenderObject* beforeChild, bool fullRemoveInsert = false) + { + return moveChildrenTo(to, firstChild(), 0, beforeChild, fullRemoveInsert); + } + // Move all of the kids from |startChild| up to but excluding |endChild|. 0 can be passed as the endChild to denote + // that all the kids from |startChild| onwards should be added. + void moveChildrenTo(RenderBlock* to, RenderObject* startChild, RenderObject* endChild, bool fullRemoveInsert = false) + { + return moveChildrenTo(to, startChild, endChild, 0, fullRemoveInsert); + } + void moveChildrenTo(RenderBlock* to, RenderObject* startChild, RenderObject* endChild, RenderObject* beforeChild, bool fullRemoveInsert = false); + int maxTopPosMargin() const { return m_maxMargin ? m_maxMargin->m_topPos : MaxMargin::topPosDefault(this); } int maxTopNegMargin() const { return m_maxMargin ? m_maxMargin->m_topNeg : MaxMargin::topNegDefault(this); } int maxBottomPosMargin() const { return m_maxMargin ? m_maxMargin->m_bottomPos : MaxMargin::bottomPosDefault(this); } @@ -223,6 +243,9 @@ private: virtual void dirtyLinesFromChangedChild(RenderObject* child) { m_lineBoxes.dirtyLinesFromChangedChild(this, child); } + void addChildToAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild); + virtual void addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild = 0); + virtual bool isSelfCollapsingBlock() const; virtual int maxTopMargin(bool positive) const { return positive ? maxTopPosMargin() : maxTopNegMargin(); } @@ -380,11 +403,14 @@ private: void calcColumnWidth(); int layoutColumns(int endOfContent = -1, int requestedColumnHeight = -1); int visibleTopOfHighestFloatExtendingBelow(int bottom, int maxHeight) const; + void makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, RenderBlock* newBlockBox, RenderObject* newChild); bool expandsToEncloseOverhangingFloats() const; void updateScrollInfoAfterLayout(); + RenderObject* splitAnonymousBlocksAroundChild(RenderObject* beforeChild); + struct FloatingObject : Noncopyable { enum Type { FloatLeft, @@ -528,7 +554,7 @@ private: RenderLineBoxList m_lineBoxes; // All of the root line boxes created for this block flow. For example, <div>Hello<br>world.</div> will have two total lines for the <div>. mutable int m_lineHeight; - + // RenderRubyBase objects need to be able to split and merge, moving their children around // (calling moveChildTo, moveAllChildrenTo, and makeChildrenNonInline). friend class RenderRubyBase; diff --git a/WebCore/rendering/RenderBoxModelObject.cpp b/WebCore/rendering/RenderBoxModelObject.cpp index 1a72957..196e8c5 100644 --- a/WebCore/rendering/RenderBoxModelObject.cpp +++ b/WebCore/rendering/RenderBoxModelObject.cpp @@ -181,6 +181,29 @@ void RenderBoxModelObject::highQualityRepaintTimerFired(Timer<RenderBoxModelObje RenderBoxModelScaleObserver::highQualityRepaintTimerFired(this); } +void RenderBoxModelObject::setSelectionState(SelectionState s) +{ + if (selectionState() == s) + return; + + if (s == SelectionInside && selectionState() != SelectionNone) + return; + + if ((s == SelectionStart && selectionState() == SelectionEnd) + || (s == SelectionEnd && selectionState() == SelectionStart)) + RenderObject::setSelectionState(SelectionBoth); + else + RenderObject::setSelectionState(s); + + // FIXME: + // We should consider whether it is OK propagating to ancestor RenderInlines. + // This is a workaround for http://webkit.org/b/32123 + RenderBlock* cb = containingBlock(); + if (cb && !cb->isRenderView()) + cb->setSelectionState(s); +} + + RenderBoxModelObject::RenderBoxModelObject(Node* node) : RenderObject(node) , m_layer(0) diff --git a/WebCore/rendering/RenderBoxModelObject.h b/WebCore/rendering/RenderBoxModelObject.h index 62f1009..dc2cf18 100644 --- a/WebCore/rendering/RenderBoxModelObject.h +++ b/WebCore/rendering/RenderBoxModelObject.h @@ -103,6 +103,7 @@ public: void highQualityRepaintTimerFired(Timer<RenderBoxModelObject>*); + virtual void setSelectionState(SelectionState s); protected: void calculateBackgroundImageGeometry(const FillLayer*, int tx, int ty, int w, int h, IntRect& destRect, IntPoint& phase, IntSize& tileSize); diff --git a/WebCore/rendering/RenderEmbeddedObject.cpp b/WebCore/rendering/RenderEmbeddedObject.cpp index 8619fc0..3d3278a 100644 --- a/WebCore/rendering/RenderEmbeddedObject.cpp +++ b/WebCore/rendering/RenderEmbeddedObject.cpp @@ -94,7 +94,7 @@ bool RenderEmbeddedObject::allowsAcceleratedCompositing() const static bool isURLAllowed(Document* doc, const String& url) { - if (doc->frame()->page()->frameCount() >= 200) + if (doc->frame()->page()->frameCount() >= Page::maxNumberOfFrames) return false; // We allow one level of self-reference because some sites depend on that. diff --git a/WebCore/rendering/RenderFileUploadControl.cpp b/WebCore/rendering/RenderFileUploadControl.cpp index 1ae149b..d4d73bc 100644 --- a/WebCore/rendering/RenderFileUploadControl.cpp +++ b/WebCore/rendering/RenderFileUploadControl.cpp @@ -50,17 +50,30 @@ const int iconFilenameSpacing = 2; const int defaultWidthNumChars = 34; const int buttonShadowHeight = 2; -class HTMLFileUploadInnerButtonElement : public HTMLInputElement { +class ShadowInputElement : public HTMLInputElement { public: - HTMLFileUploadInnerButtonElement(Document*, Node* shadowParent); + static PassRefPtr<ShadowInputElement> create(Node* shadowParent); + +private: + ShadowInputElement(Node* shadowParent); virtual bool isShadowNode() const { return true; } virtual Node* shadowParentNode() { return m_shadowParent; } -private: Node* m_shadowParent; }; +inline ShadowInputElement::ShadowInputElement(Node* shadowParent) + : HTMLInputElement(inputTag, shadowParent->document()) + , m_shadowParent(shadowParent) +{ +} + +inline PassRefPtr<ShadowInputElement> ShadowInputElement::create(Node* shadowParent) +{ + return new ShadowInputElement(shadowParent); +} + RenderFileUploadControl::RenderFileUploadControl(HTMLInputElement* input) : RenderBlock(input) , m_button(0) @@ -143,7 +156,7 @@ void RenderFileUploadControl::updateFromElement() ASSERT(inputElement->inputType() == HTMLInputElement::FILE); if (!m_button) { - m_button = new HTMLFileUploadInnerButtonElement(document(), inputElement); + m_button = ShadowInputElement::create(inputElement); m_button->setInputType("button"); m_button->setValue(fileButtonChooseFileLabel()); RefPtr<RenderStyle> buttonStyle = createButtonStyle(style()); @@ -313,10 +326,4 @@ String RenderFileUploadControl::fileTextValue() const return m_fileChooser->basenameForWidth(style()->font(), maxFilenameWidth()); } -HTMLFileUploadInnerButtonElement::HTMLFileUploadInnerButtonElement(Document* doc, Node* shadowParent) - : HTMLInputElement(inputTag, doc) - , m_shadowParent(shadowParent) -{ -} - } // namespace WebCore diff --git a/WebCore/rendering/RenderLayer.cpp b/WebCore/rendering/RenderLayer.cpp index 7477d77..3eab1f8 100644 --- a/WebCore/rendering/RenderLayer.cpp +++ b/WebCore/rendering/RenderLayer.cpp @@ -977,12 +977,14 @@ void RenderLayer::addChild(RenderLayer* child, RenderLayer* beforeChild) if (prevSibling) { child->setPreviousSibling(prevSibling); prevSibling->setNextSibling(child); + ASSERT(prevSibling != child); } else setFirstChild(child); if (beforeChild) { beforeChild->setPreviousSibling(child); child->setNextSibling(beforeChild); + ASSERT(beforeChild != child); } else setLastChild(child); diff --git a/WebCore/rendering/RenderMedia.cpp b/WebCore/rendering/RenderMedia.cpp index 7100435..ba60ed0 100644 --- a/WebCore/rendering/RenderMedia.cpp +++ b/WebCore/rendering/RenderMedia.cpp @@ -170,84 +170,84 @@ void RenderMedia::layout() void RenderMedia::createControlsShadowRoot() { ASSERT(!m_controlsShadowRoot); - m_controlsShadowRoot = new MediaControlShadowRootElement(document(), mediaElement()); + m_controlsShadowRoot = MediaControlShadowRootElement::create(mediaElement()); addChild(m_controlsShadowRoot->renderer()); } void RenderMedia::createPanel() { ASSERT(!m_panel); - m_panel = new MediaControlElement(document(), MEDIA_CONTROLS_PANEL, mediaElement()); + m_panel = MediaControlElement::create(mediaElement(), MEDIA_CONTROLS_PANEL); m_panel->attachToParent(m_controlsShadowRoot.get()); } void RenderMedia::createMuteButton() { ASSERT(!m_muteButton); - m_muteButton = new MediaControlMuteButtonElement(document(), mediaElement()); + m_muteButton = MediaControlMuteButtonElement::create(mediaElement()); m_muteButton->attachToParent(m_panel.get()); } void RenderMedia::createPlayButton() { ASSERT(!m_playButton); - m_playButton = new MediaControlPlayButtonElement(document(), mediaElement()); + m_playButton = MediaControlPlayButtonElement::create(mediaElement()); m_playButton->attachToParent(m_panel.get()); } void RenderMedia::createSeekBackButton() { ASSERT(!m_seekBackButton); - m_seekBackButton = new MediaControlSeekButtonElement(document(), mediaElement(), false); + m_seekBackButton = MediaControlSeekButtonElement::create(mediaElement(), MEDIA_CONTROLS_SEEK_BACK_BUTTON); m_seekBackButton->attachToParent(m_panel.get()); } void RenderMedia::createSeekForwardButton() { ASSERT(!m_seekForwardButton); - m_seekForwardButton = new MediaControlSeekButtonElement(document(), mediaElement(), true); + m_seekForwardButton = MediaControlSeekButtonElement::create(mediaElement(), MEDIA_CONTROLS_SEEK_FORWARD_BUTTON); m_seekForwardButton->attachToParent(m_panel.get()); } void RenderMedia::createRewindButton() { ASSERT(!m_rewindButton); - m_rewindButton = new MediaControlRewindButtonElement(document(), mediaElement()); + m_rewindButton = MediaControlRewindButtonElement::create(mediaElement()); m_rewindButton->attachToParent(m_panel.get()); } void RenderMedia::createReturnToRealtimeButton() { ASSERT(!m_returnToRealtimeButton); - m_returnToRealtimeButton = new MediaControlReturnToRealtimeButtonElement(document(), mediaElement()); + m_returnToRealtimeButton = MediaControlReturnToRealtimeButtonElement::create(mediaElement()); m_returnToRealtimeButton->attachToParent(m_panel.get()); } void RenderMedia::createToggleClosedCaptionsButton() { ASSERT(!m_toggleClosedCaptionsButton); - m_toggleClosedCaptionsButton = new MediaControlToggleClosedCaptionsButtonElement(document(), mediaElement()); + m_toggleClosedCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(mediaElement()); m_toggleClosedCaptionsButton->attachToParent(m_panel.get()); } void RenderMedia::createStatusDisplay() { ASSERT(!m_statusDisplay); - m_statusDisplay = new MediaControlStatusDisplayElement(document(), mediaElement()); + m_statusDisplay = MediaControlStatusDisplayElement::create(mediaElement()); m_statusDisplay->attachToParent(m_panel.get()); } void RenderMedia::createTimelineContainer() { ASSERT(!m_timelineContainer); - m_timelineContainer = new MediaControlTimelineContainerElement(document(), mediaElement()); + m_timelineContainer = MediaControlTimelineContainerElement::create(mediaElement()); m_timelineContainer->attachToParent(m_panel.get()); } void RenderMedia::createTimeline() { ASSERT(!m_timeline); - m_timeline = new MediaControlTimelineElement(document(), mediaElement()); + m_timeline = MediaControlTimelineElement::create(mediaElement()); m_timeline->setAttribute(precisionAttr, "float"); m_timeline->attachToParent(m_timelineContainer.get()); } @@ -255,14 +255,14 @@ void RenderMedia::createTimeline() void RenderMedia::createVolumeSliderContainer() { ASSERT(!m_volumeSliderContainer); - m_volumeSliderContainer = new MediaControlVolumeSliderContainerElement(document(), mediaElement()); + m_volumeSliderContainer = MediaControlVolumeSliderContainerElement::create(mediaElement()); m_volumeSliderContainer->attachToParent(m_panel.get()); } void RenderMedia::createVolumeSlider() { ASSERT(!m_volumeSlider); - m_volumeSlider = new MediaControlVolumeSliderElement(document(), mediaElement()); + m_volumeSlider = MediaControlVolumeSliderElement::create(mediaElement()); m_volumeSlider->setAttribute(precisionAttr, "float"); m_volumeSlider->setAttribute(maxAttr, "1"); m_volumeSlider->setAttribute(valueAttr, String::number(mediaElement()->volume())); @@ -272,21 +272,21 @@ void RenderMedia::createVolumeSlider() void RenderMedia::createCurrentTimeDisplay() { ASSERT(!m_currentTimeDisplay); - m_currentTimeDisplay = new MediaControlTimeDisplayElement(document(), MEDIA_CONTROLS_CURRENT_TIME_DISPLAY, mediaElement()); + m_currentTimeDisplay = MediaControlTimeDisplayElement::create(mediaElement(), MEDIA_CONTROLS_CURRENT_TIME_DISPLAY); m_currentTimeDisplay->attachToParent(m_timelineContainer.get()); } void RenderMedia::createTimeRemainingDisplay() { ASSERT(!m_timeRemainingDisplay); - m_timeRemainingDisplay = new MediaControlTimeDisplayElement(document(), MEDIA_CONTROLS_TIME_REMAINING_DISPLAY, mediaElement()); + m_timeRemainingDisplay = MediaControlTimeDisplayElement::create(mediaElement(), MEDIA_CONTROLS_TIME_REMAINING_DISPLAY); m_timeRemainingDisplay->attachToParent(m_timelineContainer.get()); } void RenderMedia::createFullscreenButton() { ASSERT(!m_fullscreenButton); - m_fullscreenButton = new MediaControlFullscreenButtonElement(document(), mediaElement()); + m_fullscreenButton = MediaControlFullscreenButtonElement::create(mediaElement()); m_fullscreenButton->attachToParent(m_panel.get()); } diff --git a/WebCore/rendering/RenderObject.h b/WebCore/rendering/RenderObject.h index 0c3e66d..3ff38ab 100644 --- a/WebCore/rendering/RenderObject.h +++ b/WebCore/rendering/RenderObject.h @@ -386,6 +386,8 @@ public: { return m_isAnonymous && style()->display() == BLOCK && style()->styleType() == NOPSEUDO && !isListMarker(); } + bool isAnonymousColumnsBlock() const { return style()->specifiesColumns() && isAnonymousBlock(); } + bool isAnonymousColumnSpanBlock() const { return style()->columnSpan() && isAnonymousBlock(); } bool isElementContinuation() const { return node() && node()->renderer() != this; } bool isInlineElementContinuation() const { return isElementContinuation() && isInline(); } bool isBlockElementContinuation() const { return isElementContinuation() && !isInline(); } diff --git a/WebCore/rendering/RenderObjectChildList.cpp b/WebCore/rendering/RenderObjectChildList.cpp index aa8f50f..6775537 100644 --- a/WebCore/rendering/RenderObjectChildList.cpp +++ b/WebCore/rendering/RenderObjectChildList.cpp @@ -171,7 +171,7 @@ void RenderObjectChildList::appendChildNode(RenderObject* owner, RenderObject* n void RenderObjectChildList::insertChildNode(RenderObject* owner, RenderObject* child, RenderObject* beforeChild, bool fullInsert) { if (!beforeChild) { - appendChildNode(owner, child); + appendChildNode(owner, child, fullInsert); return; } diff --git a/WebCore/rendering/RenderProgress.cpp b/WebCore/rendering/RenderProgress.cpp index cf98f18..ac3fb15 100644 --- a/WebCore/rendering/RenderProgress.cpp +++ b/WebCore/rendering/RenderProgress.cpp @@ -19,6 +19,7 @@ */ #include "config.h" + #if ENABLE(PROGRESS_TAG) #include "RenderProgress.h" @@ -38,19 +39,26 @@ using namespace HTMLNames; class ProgressValueElement : public HTMLDivElement { public: - ProgressValueElement(Document*, Node* shadowParent); + static PassRefPtr<ProgressValueElement> create(Node* shadowParent); private: + ProgressValueElement(Node* shadowParent); + virtual bool isShadowNode() const { return true; } virtual Node* shadowParentNode() { return m_shadowParent; } Node* m_shadowParent; }; -ProgressValueElement::ProgressValueElement(Document* document, Node* shadowParent) -: HTMLDivElement(divTag, document) -, m_shadowParent(shadowParent) +inline ProgressValueElement::ProgressValueElement(Node* shadowParent) + : HTMLDivElement(divTag, shadowParent->document()) + , m_shadowParent(shadowParent) +{ +} + +inline PassRefPtr<ProgressValueElement> ProgressValueElement::create(Node* shadowParent) { + return new ProgressValueElement(shadowParent); } RenderProgress::RenderProgress(HTMLProgressElement* element) @@ -136,7 +144,7 @@ void RenderProgress::updateValuePartState() { bool needLayout = !style()->hasAppearance() || m_valuePart; if (!style()->hasAppearance() && !m_valuePart) { - m_valuePart = new ProgressValueElement(document(), node()); + m_valuePart = ProgressValueElement::create(node()); RefPtr<RenderStyle> styleForValuePart = createStyleForValuePart(style()); m_valuePart->setRenderer(m_valuePart->createRenderer(renderArena(), styleForValuePart.get())); m_valuePart->renderer()->setStyle(styleForValuePart.release()); @@ -215,4 +223,5 @@ HTMLProgressElement* RenderProgress::progressElement() const } } // namespace WebCore + #endif diff --git a/WebCore/rendering/RenderRubyBase.cpp b/WebCore/rendering/RenderRubyBase.cpp index b088937..967a054 100644 --- a/WebCore/rendering/RenderRubyBase.cpp +++ b/WebCore/rendering/RenderRubyBase.cpp @@ -103,8 +103,7 @@ void RenderRubyBase::moveInlineChildren(RenderRubyBase* toBase, RenderObject* fr } } // Move our inline children into the target block we determined above. - for (RenderObject* child = firstChild(); child != fromBeforeChild; child = firstChild()) - moveChildTo(toBlock, toBlock->children(), child); + moveChildrenTo(toBlock, firstChild(), fromBeforeChild); } void RenderRubyBase::moveBlockChildren(RenderRubyBase* toBase, RenderObject* fromBeforeChild) @@ -124,7 +123,7 @@ void RenderRubyBase::moveBlockChildren(RenderRubyBase* toBase, RenderObject* fro anonBlock->destroy(); } else { ASSERT(child->isFloatingOrPositioned()); - moveChildTo(toBase, toBase->children(), child); + moveChildTo(toBase, child); } } } else { @@ -147,7 +146,7 @@ void RenderRubyBase::moveBlockChildren(RenderRubyBase* toBase, RenderObject* fro ASSERT(anonBlock->childrenInline()); ASSERT(!anonBlock->inlineElementContinuation()); // Move inline children out of anonymous block. - anonBlock->moveAllChildrenTo(this, children(), anonBlock); + anonBlock->moveAllChildrenTo(this, anonBlock); anonBlock->deleteLineBoxTree(); anonBlock->destroy(); } @@ -181,8 +180,7 @@ void RenderRubyBase::mergeBlockChildren(RenderRubyBase* toBase, RenderObject* fr anonBlockHere->destroy(); } // Move all remaining children normally. - for (RenderObject* child = firstChild(); child != fromBeforeChild; child = firstChild()) - moveChildTo(toBase, toBase->children(), child); + moveChildrenTo(toBase, firstChild(), fromBeforeChild); } } // namespace WebCore diff --git a/WebCore/rendering/RenderRubyRun.cpp b/WebCore/rendering/RenderRubyRun.cpp index d91c625..d6b724b 100644 --- a/WebCore/rendering/RenderRubyRun.cpp +++ b/WebCore/rendering/RenderRubyRun.cpp @@ -175,8 +175,8 @@ void RenderRubyRun::removeChild(RenderObject* child) RenderRubyBase* rightBase = rightRun->rubyBaseSafe(); // Collect all children in a single base, then swap the bases. rightBase->moveChildren(base); - moveChildTo(rightRun, rightRun->children(), base); - rightRun->moveChildTo(this, children(), rightBase); + moveChildTo(rightRun, base); + rightRun->moveChildTo(this, rightBase); // The now empty ruby base will be removed below. } } diff --git a/WebCore/rendering/RenderSVGResourceClipper.cpp b/WebCore/rendering/RenderSVGResourceClipper.cpp index 0f82903..7957df4 100644 --- a/WebCore/rendering/RenderSVGResourceClipper.cpp +++ b/WebCore/rendering/RenderSVGResourceClipper.cpp @@ -184,9 +184,7 @@ bool RenderSVGResourceClipper::createClipData(ClipperData* clipperData, const Fl maskContext->translate(-repaintRect.x(), -repaintRect.y()); // clipPath can also be clipped by another clipPath. - bool clipperGetsClipped = false; if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(this->document(), style()->svgStyle()->clipperResource())) { - clipperGetsClipped = true; if (!clipper->applyClippingToContext(this, objectBoundingBox, repaintRect, maskContext)) { maskContext->restore(); return false; diff --git a/WebCore/rendering/RenderSVGResourceFilter.cpp b/WebCore/rendering/RenderSVGResourceFilter.cpp index ea30d77..e197d5b 100644 --- a/WebCore/rendering/RenderSVGResourceFilter.cpp +++ b/WebCore/rendering/RenderSVGResourceFilter.cpp @@ -55,8 +55,6 @@ RenderSVGResourceType RenderSVGResourceFilter::s_resourceType = FilterResourceTy RenderSVGResourceFilter::RenderSVGResourceFilter(SVGFilterElement* node) : RenderSVGResourceContainer(node) - , m_savedContext(0) - , m_sourceGraphicBuffer(0) { } @@ -221,8 +219,8 @@ bool RenderSVGResourceFilter::applyResource(RenderObject* object, RenderStyle*, sourceGraphicContext->translate(-clippedSourceRect.x(), -clippedSourceRect.y()); sourceGraphicContext->scale(scale); sourceGraphicContext->clearRect(FloatRect(FloatPoint(), paintRect.size())); - m_sourceGraphicBuffer.set(sourceGraphic.release()); - m_savedContext = context; + filterData->sourceGraphicBuffer.set(sourceGraphic.release()); + filterData->savedContext = context; context = sourceGraphicContext; m_filter.set(object, filterData.release()); @@ -245,15 +243,15 @@ void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsCo FilterData* filterData = m_filter.get(object); if (!filterData->builded) { - if (!m_savedContext) { + if (!filterData->savedContext) { invalidateClient(object); return; } - context = m_savedContext; - m_savedContext = 0; + context = filterData->savedContext; + filterData->savedContext = 0; #if !PLATFORM(CG) - m_sourceGraphicBuffer->transformColorSpace(DeviceRGB, LinearRGB); + filterData->sourceGraphicBuffer->transformColorSpace(DeviceRGB, LinearRGB); #endif } @@ -264,7 +262,7 @@ void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsCo // initial filtering process. We just take the stored filter result on a // second drawing. if (!filterData->builded) { - filterData->filter->setSourceImage(m_sourceGraphicBuffer.release()); + filterData->filter->setSourceImage(filterData->sourceGraphicBuffer.release()); lastEffect->apply(filterData->filter.get()); filterData->builded = true; } @@ -278,7 +276,7 @@ void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsCo } } - m_sourceGraphicBuffer.clear(); + filterData->sourceGraphicBuffer.clear(); } FloatRect RenderSVGResourceFilter::resourceBoundingBox(const FloatRect& objectBoundingBox) diff --git a/WebCore/rendering/RenderSVGResourceFilter.h b/WebCore/rendering/RenderSVGResourceFilter.h index 6e98492..4d875c0 100644 --- a/WebCore/rendering/RenderSVGResourceFilter.h +++ b/WebCore/rendering/RenderSVGResourceFilter.h @@ -48,6 +48,8 @@ struct FilterData { RefPtr<SVGFilter> filter; OwnPtr<SVGFilterBuilder> builder; + OwnPtr<ImageBuffer> sourceGraphicBuffer; + GraphicsContext* savedContext; FloatRect boundaries; FloatSize scale; bool builded; @@ -81,10 +83,6 @@ public: private: bool fitsInMaximumImageSize(const FloatSize&, FloatSize&); - // Intermediate storage during - GraphicsContext* m_savedContext; - OwnPtr<ImageBuffer> m_sourceGraphicBuffer; - HashMap<RenderObject*, FilterData*> m_filter; }; diff --git a/WebCore/rendering/RenderSlider.cpp b/WebCore/rendering/RenderSlider.cpp index ed5fe76..aed8a8c 100644 --- a/WebCore/rendering/RenderSlider.cpp +++ b/WebCore/rendering/RenderSlider.cpp @@ -58,16 +58,19 @@ static double sliderPosition(HTMLInputElement* element) return range.proportionFromValue(range.valueFromElement(element)); } +// FIXME: Could share code with the SliderDivElement class in RenderProgress. class SliderThumbElement : public HTMLDivElement { public: - SliderThumbElement(Document*, Node* shadowParent); - + static PassRefPtr<SliderThumbElement> create(Node* shadowParent); + bool inDragMode() const { return m_inDragMode; } virtual void defaultEventHandler(Event*); virtual void detach(); private: + SliderThumbElement(Node* shadowParent); + virtual bool isShadowNode() const { return true; } virtual Node* shadowParentNode() { return m_shadowParent; } @@ -76,13 +79,18 @@ private: bool m_inDragMode; }; -SliderThumbElement::SliderThumbElement(Document* document, Node* shadowParent) - : HTMLDivElement(divTag, document) +inline SliderThumbElement::SliderThumbElement(Node* shadowParent) + : HTMLDivElement(divTag, shadowParent->document()) , m_shadowParent(shadowParent) , m_inDragMode(false) { } +inline PassRefPtr<SliderThumbElement> SliderThumbElement::create(Node* shadowParent) +{ + return new SliderThumbElement(shadowParent); +} + void SliderThumbElement::defaultEventHandler(Event* event) { if (!event->isMouseEvent()) { @@ -309,7 +317,7 @@ void RenderSlider::updateFromElement() { // Layout will take care of the thumb's size and position. if (!m_thumb) { - m_thumb = new SliderThumbElement(document(), node()); + m_thumb = SliderThumbElement::create(node()); RefPtr<RenderStyle> thumbStyle = createThumbStyle(style()); m_thumb->setRenderer(m_thumb->createRenderer(renderArena(), thumbStyle.get())); m_thumb->renderer()->setStyle(thumbStyle.release()); diff --git a/WebCore/rendering/RenderTextControl.cpp b/WebCore/rendering/RenderTextControl.cpp index deb7168..7724619 100644 --- a/WebCore/rendering/RenderTextControl.cpp +++ b/WebCore/rendering/RenderTextControl.cpp @@ -144,7 +144,7 @@ void RenderTextControl::createSubtreeIfNeeded(TextControlInnerElement* innerBloc // For non-search fields, there is no intermediate innerBlock as the shadow node. // m_innerText will be the shadow node in that case. RenderStyle* parentStyle = innerBlock ? innerBlock->renderer()->style() : style(); - m_innerText = new TextControlInnerTextElement(document(), innerBlock ? 0 : node()); + m_innerText = TextControlInnerTextElement::create(document(), innerBlock ? 0 : node()); m_innerText->attachInnerElement(innerBlock ? innerBlock : node(), createInnerTextStyle(parentStyle), renderArena()); } } @@ -182,7 +182,7 @@ void RenderTextControl::setInnerTextValue(const String& innerTextValue) ASSERT(!ec); if (value.endsWith("\n") || value.endsWith("\r")) { - m_innerText->appendChild(new HTMLBRElement(brTag, document()), ec); + m_innerText->appendChild(HTMLBRElement::create(document()), ec); ASSERT(!ec); } diff --git a/WebCore/rendering/RenderTextControlSingleLine.cpp b/WebCore/rendering/RenderTextControlSingleLine.cpp index 8c8bf7f..20f33c3 100644 --- a/WebCore/rendering/RenderTextControlSingleLine.cpp +++ b/WebCore/rendering/RenderTextControlSingleLine.cpp @@ -532,7 +532,7 @@ void RenderTextControlSingleLine::createSubtreeIfNeeded() if (!inputElement()->isSearchField()) { RenderTextControl::createSubtreeIfNeeded(m_innerBlock.get()); if (inputElement()->hasSpinButton() && !m_outerSpinButton) { - m_outerSpinButton = new SpinButtonElement(document(), node()); + m_outerSpinButton = SpinButtonElement::create(node()); m_outerSpinButton->attachInnerElement(node(), createOuterSpinButtonStyle(), renderArena()); } return; @@ -540,13 +540,13 @@ void RenderTextControlSingleLine::createSubtreeIfNeeded() if (!m_innerBlock) { // Create the inner block element - m_innerBlock = new TextControlInnerElement(document(), node()); + m_innerBlock = TextControlInnerElement::create(node()); m_innerBlock->attachInnerElement(node(), createInnerBlockStyle(style()), renderArena()); } if (!m_resultsButton) { // Create the search results button element - m_resultsButton = new SearchFieldResultsButtonElement(document()); + m_resultsButton = SearchFieldResultsButtonElement::create(document()); m_resultsButton->attachInnerElement(m_innerBlock.get(), createResultsButtonStyle(m_innerBlock->renderer()->style()), renderArena()); } @@ -555,7 +555,7 @@ void RenderTextControlSingleLine::createSubtreeIfNeeded() if (!m_cancelButton) { // Create the cancel button element - m_cancelButton = new SearchFieldCancelButtonElement(document()); + m_cancelButton = SearchFieldCancelButtonElement::create(document()); m_cancelButton->attachInnerElement(m_innerBlock.get(), createCancelButtonStyle(m_innerBlock->renderer()->style()), renderArena()); } } diff --git a/WebCore/rendering/RenderTheme.cpp b/WebCore/rendering/RenderTheme.cpp index 7a1afda..c37de8d 100644 --- a/WebCore/rendering/RenderTheme.cpp +++ b/WebCore/rendering/RenderTheme.cpp @@ -224,7 +224,7 @@ void RenderTheme::adjustStyle(CSSStyleSelector* selector, RenderStyle* style, El case ProgressBarPart: return adjustProgressBarStyle(selector, style, e); #endif -#if ENABLE(Meter_TAG) +#if ENABLE(METER_TAG) case MeterPart: return adjustMeterStyle(selector, style, e); #endif @@ -937,7 +937,7 @@ bool RenderTheme::paintMeter(RenderObject* renderObject, const RenderObject::Pai // left to right horizontal gauge double scale = innerRect.width() / (max - min); valueRect.setLocation(innerRect.location()); - valueRect.setSize(FloatSize(narrowPrecisionToFloat((value - min)) * scale, innerRect.height())); + valueRect.setSize(FloatSize(narrowPrecisionToFloat((value - min) * scale), innerRect.height())); } if (!valueRect.isEmpty()) paintInfo.context->fillRect(valueRect, Color::black, style->colorSpace()); diff --git a/WebCore/rendering/RenderView.cpp b/WebCore/rendering/RenderView.cpp index 1eef860..8079760 100644 --- a/WebCore/rendering/RenderView.cpp +++ b/WebCore/rendering/RenderView.cpp @@ -683,10 +683,9 @@ int RenderView::viewWidth() const float RenderView::zoomFactor() const { - if (m_frameView->frame() && m_frameView->frame()->shouldApplyPageZoom()) - return m_frameView->frame()->zoomFactor(); - - return 1.0f; + if (!m_frameView->shouldApplyPageZoom()) + return 1; + return m_frameView->zoomFactor(); } // The idea here is to take into account what object is moving the pagination point, and diff --git a/WebCore/rendering/TextControlInnerElements.cpp b/WebCore/rendering/TextControlInnerElements.cpp index 84f7c0f..ed12611 100644 --- a/WebCore/rendering/TextControlInnerElements.cpp +++ b/WebCore/rendering/TextControlInnerElements.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2006, 2008, 2010 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -40,14 +40,17 @@ namespace WebCore { +using namespace HTMLNames; + class RenderTextControlInnerBlock : public RenderBlock { public: RenderTextControlInnerBlock(Node* node, bool isMultiLine) : RenderBlock(node), m_multiLine(isMultiLine) { } +private: virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction); virtual VisiblePosition positionForPoint(const IntPoint&); - private: - bool m_multiLine; + + bool m_multiLine; }; bool RenderTextControlInnerBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction) @@ -76,12 +79,19 @@ VisiblePosition RenderTextControlInnerBlock::positionForPoint(const IntPoint& po return RenderBlock::positionForPoint(contentsPoint); } -TextControlInnerElement::TextControlInnerElement(Document* doc, Node* shadowParent) - : HTMLDivElement(HTMLNames::divTag, doc) +// ---------------------------- + +TextControlInnerElement::TextControlInnerElement(Document* document, Node* shadowParent) + : HTMLDivElement(divTag, document) , m_shadowParent(shadowParent) { } +PassRefPtr<TextControlInnerElement> TextControlInnerElement::create(Node* shadowParent) +{ + return new TextControlInnerElement(shadowParent->document(), shadowParent); +} + void TextControlInnerElement::attachInnerElement(Node* parent, PassRefPtr<RenderStyle> style, RenderArena* arena) { // When adding these elements, create the renderer & style first before adding to the DOM. @@ -107,21 +117,29 @@ void TextControlInnerElement::attachInnerElement(Node* parent, PassRefPtr<Render parent->renderer()->addChild(renderer); } -TextControlInnerTextElement::TextControlInnerTextElement(Document* doc, Node* shadowParent) - : TextControlInnerElement(doc, shadowParent) +// ---------------------------- + +inline TextControlInnerTextElement::TextControlInnerTextElement(Document* document, Node* shadowParent) + : TextControlInnerElement(document, shadowParent) { } -void TextControlInnerTextElement::defaultEventHandler(Event* evt) +PassRefPtr<TextControlInnerTextElement> TextControlInnerTextElement::create(Document* document, Node* shadowParent) { - // FIXME: In the future, we should add a way to have default event listeners. Then we would add one to the text field's inner div, and we wouldn't need this subclass. - Node* shadowAncestor = shadowAncestorNode(); - if (shadowAncestor) { - if (evt->isBeforeTextInsertedEvent() || evt->type() == eventNames().webkitEditableContentChangedEvent) - shadowAncestor->defaultEventHandler(evt); + return new TextControlInnerTextElement(document, shadowParent); +} + +void TextControlInnerTextElement::defaultEventHandler(Event* event) +{ + // FIXME: In the future, we should add a way to have default event listeners. + // Then we would add one to the text field's inner div, and we wouldn't need this subclass. + // Or possibly we could just use a normal event listener. + if (event->isBeforeTextInsertedEvent() || event->type() == eventNames().webkitEditableContentChangedEvent) { + if (Node* shadowAncestor = shadowAncestorNode()) + shadowAncestor->defaultEventHandler(event); } - if (!evt->defaultHandled()) - HTMLDivElement::defaultEventHandler(evt); + if (event->defaultHandled()) + HTMLDivElement::defaultEventHandler(event); } RenderObject* TextControlInnerTextElement::createRenderer(RenderArena* arena, RenderStyle*) @@ -135,16 +153,23 @@ RenderObject* TextControlInnerTextElement::createRenderer(RenderArena* arena, Re return new (arena) RenderTextControlInnerBlock(this, multiLine); } -SearchFieldResultsButtonElement::SearchFieldResultsButtonElement(Document* doc) - : TextControlInnerElement(doc) +// ---------------------------- + +inline SearchFieldResultsButtonElement::SearchFieldResultsButtonElement(Document* document) + : TextControlInnerElement(document) { } -void SearchFieldResultsButtonElement::defaultEventHandler(Event* evt) +PassRefPtr<SearchFieldResultsButtonElement> SearchFieldResultsButtonElement::create(Document* document) +{ + return new SearchFieldResultsButtonElement(document); +} + +void SearchFieldResultsButtonElement::defaultEventHandler(Event* event) { // On mousedown, bring up a menu, if needed HTMLInputElement* input = static_cast<HTMLInputElement*>(shadowAncestorNode()); - if (evt->type() == eventNames().mousedownEvent && evt->isMouseEvent() && static_cast<MouseEvent*>(evt)->button() == LeftButton) { + if (event->type() == eventNames().mousedownEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton) { input->focus(); input->select(); RenderTextControlSingleLine* renderer = toRenderTextControlSingleLine(input->renderer()); @@ -152,18 +177,26 @@ void SearchFieldResultsButtonElement::defaultEventHandler(Event* evt) renderer->hidePopup(); else if (input->maxResults() > 0) renderer->showPopup(); - evt->setDefaultHandled(); + event->setDefaultHandled(); } - if (!evt->defaultHandled()) - HTMLDivElement::defaultEventHandler(evt); + + if (!event->defaultHandled()) + HTMLDivElement::defaultEventHandler(event); } -SearchFieldCancelButtonElement::SearchFieldCancelButtonElement(Document* doc) - : TextControlInnerElement(doc) +// ---------------------------- + +inline SearchFieldCancelButtonElement::SearchFieldCancelButtonElement(Document* document) + : TextControlInnerElement(document) , m_capturing(false) { } +PassRefPtr<SearchFieldCancelButtonElement> SearchFieldCancelButtonElement::create(Document* document) +{ + return new SearchFieldCancelButtonElement(document); +} + void SearchFieldCancelButtonElement::detach() { if (m_capturing) { @@ -174,60 +207,71 @@ void SearchFieldCancelButtonElement::detach() } -void SearchFieldCancelButtonElement::defaultEventHandler(Event* evt) +void SearchFieldCancelButtonElement::defaultEventHandler(Event* event) { // If the element is visible, on mouseup, clear the value, and set selection HTMLInputElement* input = static_cast<HTMLInputElement*>(shadowAncestorNode()); - if (evt->type() == eventNames().mousedownEvent && evt->isMouseEvent() && static_cast<MouseEvent*>(evt)->button() == LeftButton) { - input->focus(); - input->select(); - evt->setDefaultHandled(); - if (renderer() && renderer()->visibleToHitTesting()) + if (event->type() == eventNames().mousedownEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton) { + if (renderer() && renderer()->visibleToHitTesting()) { if (Frame* frame = document()->frame()) { frame->eventHandler()->setCapturingMouseEventsNode(this); m_capturing = true; } - } else if (evt->type() == eventNames().mouseupEvent && evt->isMouseEvent() && static_cast<MouseEvent*>(evt)->button() == LeftButton) { + } + input->focus(); + input->select(); + event->setDefaultHandled(); + } + if (event->type() == eventNames().mouseupEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton) { if (m_capturing && renderer() && renderer()->visibleToHitTesting()) { - if (hovered()) { - input->setValue(""); - input->onSearch(); - evt->setDefaultHandled(); - } if (Frame* frame = document()->frame()) { frame->eventHandler()->setCapturingMouseEventsNode(0); m_capturing = false; } + if (hovered()) { + input->setValue(""); + input->onSearch(); + event->setDefaultHandled(); + } } } - if (!evt->defaultHandled()) - HTMLDivElement::defaultEventHandler(evt); + + if (!event->defaultHandled()) + HTMLDivElement::defaultEventHandler(event); } -SpinButtonElement::SpinButtonElement(Document* doc, Node* shadowParent) - : TextControlInnerElement(doc, shadowParent) +// ---------------------------- + +inline SpinButtonElement::SpinButtonElement(Node* shadowParent) + : TextControlInnerElement(shadowParent->document(), shadowParent) , m_capturing(false) , m_onUpButton(false) { } -void SpinButtonElement::defaultEventHandler(Event* evt) +PassRefPtr<SpinButtonElement> SpinButtonElement::create(Node* shadowParent) { - if (!evt->isMouseEvent()) { - if (!evt->defaultHandled()) - HTMLDivElement::defaultEventHandler(evt); + return new SpinButtonElement(shadowParent); +} + +void SpinButtonElement::defaultEventHandler(Event* event) +{ + if (!event->isMouseEvent()) { + if (!event->defaultHandled()) + HTMLDivElement::defaultEventHandler(event); return; } - const MouseEvent* mevt = static_cast<MouseEvent*>(evt); - if (mevt->button() != LeftButton) { - if (!evt->defaultHandled()) - HTMLDivElement::defaultEventHandler(evt); + + MouseEvent* mouseEvent = static_cast<MouseEvent*>(event); + if (mouseEvent->button() != LeftButton) { + if (!event->defaultHandled()) + HTMLDivElement::defaultEventHandler(event); return; } HTMLInputElement* input = static_cast<HTMLInputElement*>(shadowAncestorNode()); - IntPoint local = roundedIntPoint(renderBox()->absoluteToLocal(mevt->absoluteLocation(), false, true)); - if (evt->type() == eventNames().clickEvent) { + IntPoint local = roundedIntPoint(renderBox()->absoluteToLocal(mouseEvent->absoluteLocation(), false, true)); + if (event->type() == eventNames().clickEvent) { if (renderBox()->borderBoxRect().contains(local)) { input->focus(); input->select(); @@ -235,9 +279,9 @@ void SpinButtonElement::defaultEventHandler(Event* evt) input->stepUpFromRenderer(1); else input->stepUpFromRenderer(-1); - evt->setDefaultHandled(); + event->setDefaultHandled(); } - } else if (evt->type() == eventNames().mousemoveEvent) { + } else if (event->type() == eventNames().mousemoveEvent) { if (renderBox()->borderBoxRect().contains(local)) { if (!m_capturing) { if (Frame* frame = document()->frame()) { @@ -258,8 +302,9 @@ void SpinButtonElement::defaultEventHandler(Event* evt) } } } - if (!evt->defaultHandled()) - HTMLDivElement::defaultEventHandler(evt); + + if (!event->defaultHandled()) + HTMLDivElement::defaultEventHandler(event); } } diff --git a/WebCore/rendering/TextControlInnerElements.h b/WebCore/rendering/TextControlInnerElements.h index f59ac96..ed1887e 100644 --- a/WebCore/rendering/TextControlInnerElements.h +++ b/WebCore/rendering/TextControlInnerElements.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2006, 2008, 2010 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -34,55 +34,76 @@ class String; class TextControlInnerElement : public HTMLDivElement { public: + static PassRefPtr<TextControlInnerElement> create(Node* shadowParent); + + void attachInnerElement(Node*, PassRefPtr<RenderStyle>, RenderArena*); + +protected: TextControlInnerElement(Document*, Node* shadowParent = 0); - + +private: virtual bool isMouseFocusable() const { return false; } virtual bool isShadowNode() const { return m_shadowParent; } virtual Node* shadowParentNode() { return m_shadowParent; } void setShadowParentNode(Node* node) { m_shadowParent = node; } - void attachInnerElement(Node*, PassRefPtr<RenderStyle>, RenderArena*); - -private: + Node* m_shadowParent; }; class TextControlInnerTextElement : public TextControlInnerElement { public: + static PassRefPtr<TextControlInnerTextElement> create(Document*, Node* shadowParent); + + virtual void defaultEventHandler(Event*); + +private: TextControlInnerTextElement(Document*, Node* shadowParent); virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); - virtual void defaultEventHandler(Event*); }; class SearchFieldResultsButtonElement : public TextControlInnerElement { public: - SearchFieldResultsButtonElement(Document*); + static PassRefPtr<SearchFieldResultsButtonElement> create(Document*); + virtual void defaultEventHandler(Event*); + +private: + SearchFieldResultsButtonElement(Document*); }; class SearchFieldCancelButtonElement : public TextControlInnerElement { public: - SearchFieldCancelButtonElement(Document*); + static PassRefPtr<SearchFieldCancelButtonElement> create(Document*); + virtual void defaultEventHandler(Event*); - virtual void detach(); + private: + SearchFieldCancelButtonElement(Document*); + + virtual void detach(); + bool m_capturing; }; class SpinButtonElement : public TextControlInnerElement { public: - SpinButtonElement(Document*, Node*); - virtual bool isSpinButtonElement() const { return true; } - virtual bool isEnabledFormControl() { return static_cast<Element*>(shadowAncestorNode())->isEnabledFormControl(); } - virtual void defaultEventHandler(Event*); + static PassRefPtr<SpinButtonElement> create(Node*); + // FIXME: "Spin button on up button" is not a phrase with a single clear meaning. + // Need a name for this that makes it clearer. bool onUpButton() const { return m_onUpButton; } - static const AtomicString& spinButtonNodeName(); private: + SpinButtonElement(Node*); + + virtual bool isSpinButtonElement() const { return true; } + virtual bool isEnabledFormControl() { return static_cast<Element*>(shadowAncestorNode())->isEnabledFormControl(); } + virtual void defaultEventHandler(Event*); + bool m_capturing; bool m_onUpButton; }; -} //namespace +} // namespace #endif diff --git a/WebCore/rendering/style/RenderStyle.h b/WebCore/rendering/style/RenderStyle.h index 0d0066b..16dcae8 100644 --- a/WebCore/rendering/style/RenderStyle.h +++ b/WebCore/rendering/style/RenderStyle.h @@ -998,6 +998,7 @@ public: void setColumnBreakBefore(EPageBreak p) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_breakBefore, p); } void setColumnBreakInside(EPageBreak p) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_breakInside, p); } void setColumnBreakAfter(EPageBreak p) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_breakAfter, p); } + void inheritColumnPropertiesFrom(RenderStyle* parent) { rareNonInheritedData.access()->m_multiCol = parent->rareNonInheritedData->m_multiCol; } void setTransform(const TransformOperations& ops) { SET_VAR(rareNonInheritedData.access()->m_transform, m_operations, ops); } void setTransformOriginX(Length l) { SET_VAR(rareNonInheritedData.access()->m_transform, m_x, l); } void setTransformOriginY(Length l) { SET_VAR(rareNonInheritedData.access()->m_transform, m_y, l); } |