Reviewed by Maciej
* khtml/css/html4.css:
* khtml/html/html_objectimpl.cpp:
(HTMLObjectElementImpl::HTMLObjectElementImpl):
(HTMLObjectElementImpl::parseHTMLAttribute):
(HTMLObjectElementImpl::rendererIsNeeded):
(HTMLObjectElementImpl::createRenderer):
(HTMLObjectElementImpl::attach):
(HTMLObjectElementImpl::detach):
(HTMLObjectElementImpl::recalcStyle):
(HTMLObjectElementImpl::childrenChanged):
(HTMLObjectElementImpl::isURLAttribute):
(HTMLObjectElementImpl::isImageType):
(HTMLObjectElementImpl::renderFallbackContent):
* khtml/html/html_objectimpl.h:
* khtml/khtml_part.cpp:
(KHTMLPart::requestObject):
(KHTMLPart::selectFrameElementInParentIfFullySelected):
(KHTMLPart::handleFallbackContent):
* khtml/khtml_part.h:
* khtml/khtmlpart_p.h:
(khtml::ChildFrame::ChildFrame):
* khtml/rendering/render_frames.cpp:
(RenderPartObject::RenderPartObject):
(RenderPartObject::updateWidget):
* khtml/rendering/render_frames.h:
(khtml::RenderPart::hasFallbackContent):
* khtml/rendering/render_replaced.cpp:
(RenderReplaced::RenderReplaced):
* kwq/KWQKHTMLPart.mm:
(KWQKHTMLPart::createPart):
* kwq/WebCoreBridge.h:
* kwq/WebCoreBridge.mm:
(-[WebCoreBridge mainResourceError]):
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@9095
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2005-05-03 David Hyatt <hyatt@apple.com>
+
+ Fix for object element to support fallback content. WIth this change Safari passes the Acid2 test.
+
+ Reviewed by Maciej
+
+ * khtml/css/html4.css:
+ * khtml/html/html_objectimpl.cpp:
+ (HTMLObjectElementImpl::HTMLObjectElementImpl):
+ (HTMLObjectElementImpl::parseHTMLAttribute):
+ (HTMLObjectElementImpl::rendererIsNeeded):
+ (HTMLObjectElementImpl::createRenderer):
+ (HTMLObjectElementImpl::attach):
+ (HTMLObjectElementImpl::detach):
+ (HTMLObjectElementImpl::recalcStyle):
+ (HTMLObjectElementImpl::childrenChanged):
+ (HTMLObjectElementImpl::isURLAttribute):
+ (HTMLObjectElementImpl::isImageType):
+ (HTMLObjectElementImpl::renderFallbackContent):
+ * khtml/html/html_objectimpl.h:
+ * khtml/khtml_part.cpp:
+ (KHTMLPart::requestObject):
+ (KHTMLPart::selectFrameElementInParentIfFullySelected):
+ (KHTMLPart::handleFallbackContent):
+ * khtml/khtml_part.h:
+ * khtml/khtmlpart_p.h:
+ (khtml::ChildFrame::ChildFrame):
+ * khtml/rendering/render_frames.cpp:
+ (RenderPartObject::RenderPartObject):
+ (RenderPartObject::updateWidget):
+ * khtml/rendering/render_frames.h:
+ (khtml::RenderPart::hasFallbackContent):
+ * khtml/rendering/render_replaced.cpp:
+ (RenderReplaced::RenderReplaced):
+ * kwq/KWQKHTMLPart.mm:
+ (KWQKHTMLPart::createPart):
+ * kwq/WebCoreBridge.h:
+ * kwq/WebCoreBridge.mm:
+ (-[WebCoreBridge mainResourceError]):
+
2005-05-01 Darin Adler <darin@apple.com>
- move to Xcode native targets and stop checking in generated files
/* FIXME: content: close-quote; */
}
-iframe, embed, object {
- width: 300px;
- height: 150px
-}
-
center {
display: block;
/* special centering to be able to emulate the html4/netscape behaviour */
#endif
{
needWidgetUpdate = false;
+ m_useFallbackContent = false;
}
HTMLObjectElementImpl::~HTMLObjectElementImpl()
serviceType = serviceType.left( pos );
if (m_render)
needWidgetUpdate = true;
- if (!canRenderImageType(serviceType) && m_imageLoader) {
+ if (!isImageType() && m_imageLoader) {
delete m_imageLoader;
m_imageLoader = 0;
}
url = khtml::parseURL( val ).string();
if (m_render)
needWidgetUpdate = true;
- if (m_render && canRenderImageType(serviceType)) {
+ if (m_render && isImageType()) {
if (!m_imageLoader)
m_imageLoader = new HTMLImageLoader(this);
m_imageLoader->updateFromElement();
bool HTMLObjectElementImpl::rendererIsNeeded(RenderStyle *style)
{
- if (canRenderImageType(serviceType)) {
+ if (m_useFallbackContent || isImageType())
return HTMLElementImpl::rendererIsNeeded(style);
- }
KHTMLPart* part = getDocument()->part();
if (!part || !part->pluginsEnabled()) {
RenderObject *HTMLObjectElementImpl::createRenderer(RenderArena *arena, RenderStyle *style)
{
- if (canRenderImageType(serviceType)) {
+ if (m_useFallbackContent)
+ return RenderObject::createObject(this, style);
+ if (isImageType())
return new (arena) RenderImage(this);
- }
return new (arena) RenderPartObject(this);
}
{
HTMLElementImpl::attach();
- if (m_render) {
- if (canRenderImageType(serviceType)) {
+ if (m_render && !m_useFallbackContent) {
+ if (isImageType()) {
if (!m_imageLoader)
m_imageLoader = new HTMLImageLoader(this);
m_imageLoader->updateFromElement();
void HTMLObjectElementImpl::detach()
{
// Only bother with an unload event if we had a render object. - dwh
- if (attached() && m_render)
+ if (attached() && m_render && !m_useFallbackContent)
// ### do this when we are actualy removed from document instead
dispatchHTMLEvent(EventImpl::UNLOAD_EVENT,false,false);
void HTMLObjectElementImpl::recalcStyle(StyleChange ch)
{
- if (needWidgetUpdate && m_render && !canRenderImageType(serviceType)) {
+ if (!m_useFallbackContent && needWidgetUpdate && m_render && !isImageType()) {
// Set needWidgetUpdate to false before calling updateWidget because updateWidget may cause
// this method or attach (which also calls updateWidget) to be called.
needWidgetUpdate = false;
void HTMLObjectElementImpl::childrenChanged()
{
- if (inDocument()) {
+ if (inDocument() && !m_useFallbackContent) {
needWidgetUpdate = true;
setChanged();
}
return (attr->id() == ATTR_DATA || (attr->id() == ATTR_USEMAP && attr->value().domString()[0] != '#'));
}
+bool HTMLObjectElementImpl::isImageType()
+{
+ if (serviceType.isEmpty() && url.startsWith("data:")) {
+ // Extract the MIME type from the data URL.
+ int index = url.find(';');
+ if (index == -1)
+ index = url.find(',');
+ if (index != -1) {
+ int len = index - 5;
+ if (len > 0)
+ serviceType = url.mid(5, len);
+ else
+ serviceType = "text/plain"; // Data URLs with no MIME type are considered text/plain.
+ }
+ }
+
+ return canRenderImageType(serviceType);
+}
+
+void HTMLObjectElementImpl::renderFallbackContent()
+{
+ if (m_useFallbackContent)
+ return;
+
+ // Mark ourselves as using the fallback content.
+ m_useFallbackContent = true;
+
+ // Now do a detach and reattach.
+ // FIXME: Style gets recalculated which is suboptimal.
+ detach();
+ attach();
+}
+
// -------------------------------------------------------------------------
HTMLParamElementImpl::HTMLParamElementImpl(DocumentPtr *doc)
virtual bool isURLAttribute(AttributeImpl *attr) const;
+ bool isImageType();
+
+ void renderFallbackContent();
+
#if APPLE_CHANGES
KJS::Bindings::Instance *getObjectInstance() const;
#endif
QString serviceType;
QString url;
QString classId;
- bool needWidgetUpdate;
+ bool needWidgetUpdate : 1;
+ bool m_useFallbackContent : 1;
HTMLImageLoader* m_imageLoader;
#if APPLE_CHANGES
#include "html/html_baseimpl.h"
#include "html/html_miscimpl.h"
#include "html/html_imageimpl.h"
+#include "html/html_objectimpl.h"
#include "rendering/render_block.h"
#include "rendering/render_text.h"
#include "rendering/render_frames.h"
(*it).m_type = khtml::ChildFrame::Object;
(*it).m_paramNames = paramNames;
(*it).m_paramValues = paramValues;
+ (*it).m_hasFallbackContent = frame->hasFallbackContent();
KURL completedURL;
if (!url.isEmpty())
parent->setSelection(Selection(beforeOwnerElement, afterOwnerElement));
}
+void KHTMLPart::handleFallbackContent()
+{
+ KHTMLPart *parent = parentPart();
+ if (!parent)
+ return;
+ ChildFrame *childFrame = parent->childFrame(this);
+ if (!childFrame || childFrame->m_type != ChildFrame::Object)
+ return;
+ khtml::RenderPart *renderPart = childFrame->m_frame;
+ if (!renderPart)
+ return;
+ HTMLObjectElementImpl* elt = static_cast<HTMLObjectElementImpl *>(renderPart->element());
+ elt->renderFallbackContent();
+}
+
using namespace KParts;
#include "khtml_part.moc"
// Call this after doing user-triggered selections to make it easy to delete the frame you entirely selected.
void selectFrameElementInParentIfFullySelected();
+ void handleFallbackContent();
+
private:
khtml::ChildFrame *childFrame( const QObject *obj );
{
enum Type { Frame, IFrame, Object };
- ChildFrame() { m_bCompleted = false; m_bPreloaded = false; m_type = Frame; m_bNotify = false; }
+ ChildFrame() { m_bCompleted = false; m_bPreloaded = false; m_type = Frame; m_bNotify = false; m_hasFallbackContent = false; }
#if !APPLE_CHANGES
~ChildFrame() { if (m_run) m_run->abort(); }
QStringList m_paramNames;
QStringList m_paramValues;
bool m_bNotify;
+ bool m_hasFallbackContent;
};
}
return false;
}
-int RenderPart::intrinsicWidth() const
-{
- // KDE may need a non-zero width here, although this will mess up pages (e.g., thinker.org).
-#if APPLE_CHANGES
- return 0;
-#else
- return 300;
-#endif
-}
-
-int RenderPart::intrinsicHeight() const
-{
- // KDE may need a non-zero height here, although this will mess up pages (e.g., thinker.org).
-#if APPLE_CHANGES
- return 0;
-#else
- return 200;
-#endif
-}
-
void RenderPart::slotViewCleared()
{
}
{
// init RenderObject attributes
setInline(true);
+ m_hasFallbackContent = false;
}
void RenderPartObject::updateWidget()
params.append( QString::fromLatin1("__KHTML__CODEBASE=\"%1\"").arg( o->getAttribute(ATTR_CODEBASE).string() ) );
#endif
- part->requestObject( this, url, serviceType, paramNames, paramValues );
+ // Find out if we support fallback content.
+ m_hasFallbackContent = false;
+ for (NodeImpl *child = o->firstChild(); child && !m_hasFallbackContent; child = child->nextSibling()) {
+ if ((!child->isTextNode() && child->id() != ID_EMBED && child->id() != ID_PARAM) || // Discount <embed> and <param>
+ (child->isTextNode() && !child->containsOnlyWhitespace()))
+ m_hasFallbackContent = true;
+ }
+ bool success = part->requestObject( this, url, serviceType, paramNames, paramValues );
+ if (!success && m_hasFallbackContent)
+ o->renderFallbackContent();
} else if ( element()->id() == ID_EMBED ) {
HTMLEmbedElementImpl *o = static_cast<HTMLEmbedElementImpl *>(element());
*/
virtual bool partLoadingErrorNotify( khtml::ChildFrame *childFrame, const KURL& url, const QString& serviceType );
- virtual int intrinsicWidth() const;
- virtual int intrinsicHeight() const;
+ bool hasFallbackContent() const { return m_hasFallbackContent; }
public slots:
virtual void slotViewCleared();
+
+protected:
+ bool m_hasFallbackContent;
};
class RenderFrame : public RenderPart
// init RenderObject attributes
setReplaced(true);
- m_intrinsicWidth = 200;
+ m_intrinsicWidth = 300;
m_intrinsicHeight = 150;
m_selectionState = SelectionNone;
}
KWQ_BLOCK_EXCEPTIONS;
ReadOnlyPart *part;
- BOOL needFrame = [_bridge frameRequiredForMIMEType:mimeType.getNSString() URL:url.getNSURL()];
- if (child.m_type == ChildFrame::Object && !needFrame) {
+ ObjectElementType objectType = ObjectElementFrame;
+ if (child.m_type == ChildFrame::Object)
+ objectType = [_bridge determineObjectFromMIMEType:mimeType.getNSString() URL:url.getNSURL()];
+
+ if (objectType == ObjectElementNone) {
+ if (child.m_hasFallbackContent)
+ return NULL;
+ objectType = ObjectElementPlugin; // Since no fallback content exists, we'll make a plugin and show the error dialog.
+ }
+
+ if (objectType == ObjectElementPlugin) {
KWQPluginPart *newPart = new KWQPluginPart;
newPart->setWidget(new QWidget([_bridge viewForPluginWithURL:url.getNSURL()
attributeNames:child.m_paramNames.getNSArray()
// This call needs to return an object with a ref, since the caller will expect to own it.
// childBridge owns the only ref so far.
part = [childBridge part];
- if (part) {
+ if (part)
part->ref();
- }
}
return part;
WebUndoActionTyping,
} WebUndoAction;
+typedef enum
+{
+ ObjectElementNone,
+ ObjectElementImage,
+ ObjectElementFrame,
+ ObjectElementPlugin,
+} ObjectElementType;
+
// WebCoreBridge objects are used by WebCore to abstract away operations that need
// to be implemented by library clients, for example WebKit. The objects are also
// used in the opposite direction, for simple access to WebCore functions without dealing
- (void)end;
- (void)stop;
+- (void)mainResourceError;
+
- (NSURL *)URL;
- (NSURL *)baseURL;
- (NSString *)referrer;
- (int)getObjectCacheSize;
-- (BOOL)frameRequiredForMIMEType:(NSString*)MIMEType URL:(NSURL *)URL;
+- (ObjectElementType)determineObjectFromMIMEType:(NSString*)MIMEType URL:(NSURL*)URL;
- (void)loadEmptyDocumentSynchronously;
_part->stop();
}
+- (void)mainResourceError
+{
+ _part->handleFallbackContent();
+}
+
- (void)createKHTMLViewWithNSView:(NSView *)view marginWidth:(int)mw marginHeight:(int)mh
{
// If we own the view, delete the old one - otherwise the render _part will take care of deleting the view.