📄 render_frames.cpp
字号:
}
// Turn the attributes of either the EMBED tag or OBJECT tag into arrays, but don't override PARAM values.
NamedAttrMapImpl* attributes = embedOrObject->attributes();
if (attributes) {
for (unsigned long i = 0; i < attributes->length(); ++i) {
AttributeImpl* it = attributes->attributeItem(i);
QString name = o->getDocument()->attrName(it->id()).string();
if (embed || uniqueParamNames.find(name) == 0) {
paramNames.append(name);
paramValues.append(it->value().string());
}
}
}
// If we still don't have a type, try to map from a specific CLASSID to a type.
if (serviceType.isEmpty() && !o->classId.isEmpty())
mapClassIdToServiceType(o->classId, serviceType);
// If no URL and type, abort.
if (url.isEmpty() && serviceType.isEmpty())
return;
if (!isURLAllowed(document(), url))
return;
// 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());
url = o->url;
serviceType = o->serviceType;
if (url.isEmpty() && serviceType.isEmpty())
return;
if (!isURLAllowed(document(), url))
return;
// add all attributes set on the embed object
NamedAttrMapImpl* a = o->attributes();
if (a) {
for (unsigned long i = 0; i < a->length(); ++i) {
AttributeImpl* it = a->attributeItem(i);
paramNames.append(o->getDocument()->attrName(it->id()).string());
paramValues.append(it->value().string());
}
}
part->requestObject( this, url, serviceType, paramNames, paramValues );
#if NOKIA_CHANGES
} else if ( element()->id() == ID_BGSOUND ) {
HTMLEmbedElementImpl *o = static_cast<HTMLEmbedElementImpl *>(element());
url = o->url;
serviceType = o->serviceType;
if ( url.isEmpty() && serviceType.isEmpty() ) {
#ifdef DEBUG_LAYOUT
kdDebug() << "RenderPartObject::close - empty url and serverType" << endl;
#endif
return;
}
// Avoid infinite recursion. If the plug-in's URL is the same as the part's URL, infinite frames may be created.
if (!url.isEmpty() && part->completeURL(url) == part->baseURL()) {
return;
}
// parse and add the attributes
// Currently specification asked to specify 50 whenever it is out range of 50
// or any other value
// In case the loop tag was not specified, we want to take 50 in default
// as well
NamedAttrMapImpl* a = o->attributes();
if (a) {
bool LoopTag = false;
for (unsigned long i = 0; i < a->length(); ++i) {
AttributeImpl* it = a->attributeItem(i);
paramNames.append(o->getDocument()->attrName(it->id()).string());
if ( it->id() == ATTR_LOOP )
{
if (it->value().toInt() > 0 && it->value().toInt() <= 50 ) {
paramValues.append(it->value().string());
} else {
paramValues.append("50");
}
LoopTag = true;
} else {
paramValues.append(it->value().string());
}
}
if (!LoopTag)
{
paramNames.append("loop");
paramValues.append("50");
}
}
part->requestObject( this, url, serviceType, paramNames, paramValues );
#endif
} else {
assert(element()->id() == ID_IFRAME);
HTMLIFrameElementImpl *o = static_cast<HTMLIFrameElementImpl *>(element());
url = o->url.string();
if (!isURLAllowed(document(), url))
return;
if (url.isEmpty())
url = "about:blank";
KHTMLView *v = static_cast<KHTMLView *>(m_view);
bool requestSucceeded = v->part()->requestFrame( this, url, o->name.string(), QStringList(), QStringList(), true );
if (requestSucceeded && url == "about:blank") {
KHTMLPart *newPart = v->part()->findFrame( o->name.string() );
if (newPart && newPart->xmlDocImpl()) {
newPart->xmlDocImpl()->setBaseURL( v->part()->baseURL().url() );
}
}
}
}
bool RenderPartObject::partLoadingErrorNotify( khtml::ChildFrame *childFrame, const KURL& url, const QString& serviceType )
{
KHTMLPart *part = static_cast<KHTMLView *>(m_view)->part();
//kdDebug() << "RenderPartObject::partLoadingErrorNotify serviceType=" << serviceType << endl;
// Check if we just tried with e.g. nsplugin
// and fallback to the activexhandler if there is a classid
// and a codebase, where we may download the ocx if it's missing
if( serviceType != "application/x-activex-handler" && element()->id()==ID_OBJECT ) {
// check for embed child object
HTMLObjectElementImpl *o = static_cast<HTMLObjectElementImpl *>(element());
HTMLEmbedElementImpl *embed = 0;
NodeImpl *child = o->firstChild();
while ( child ) {
if ( child->id() == ID_EMBED )
embed = static_cast<HTMLEmbedElementImpl *>( child );
child = child->nextSibling();
}
if( embed && !o->classId.isEmpty() &&
!( static_cast<ElementImpl *>(o)->getAttribute(ATTR_CODEBASE).string() ).isEmpty() )
{
KParts::URLArgs args;
args.serviceType = "application/x-activex-handler";
if (part->requestObject( childFrame, url, args ))
return true; // success
}
}
// Dissociate ourselves from the current event loop (to prevent crashes
// due to the message box staying up)
QTimer::singleShot( 0, this, SLOT( slotPartLoadingErrorNotify() ) );
Tokenizer *tokenizer = static_cast<DOM::DocumentImpl *>(part->document().handle())->tokenizer();
if (tokenizer) tokenizer->setOnHold( true );
slotPartLoadingErrorNotify();
if (tokenizer) tokenizer->setOnHold( false );
return false;
}
void RenderPartObject::slotPartLoadingErrorNotify()
{
#if APPLE_CHANGES
// FIXME: What are we going to do for this case?
#else
// First we need to find out the servicetype - again - this code is too duplicated !
HTMLEmbedElementImpl *embed = 0;
QString serviceType;
if( element()->id()==ID_OBJECT ) {
// check for embed child object
HTMLObjectElementImpl *o = static_cast<HTMLObjectElementImpl *>(element());
serviceType = o->serviceType;
NodeImpl *child = o->firstChild();
while ( child ) {
if ( child->id() == ID_EMBED )
embed = static_cast<HTMLEmbedElementImpl *>( child );
child = child->nextSibling();
}
} else if( element()->id()==ID_EMBED ) {
embed = static_cast<HTMLEmbedElementImpl *>(element());
}
if ( embed )
serviceType = embed->serviceType;
KHTMLPart *part = static_cast<KHTMLView *>(m_view)->part();
KParts::BrowserExtension *ext = part->browserExtension();
if( embed && !embed->pluginPage.isEmpty() && ext ) {
// Prepare the mimetype to show in the question (comment if available, name as fallback)
QString mimeName = serviceType;
KMimeType::Ptr mime = KMimeType::mimeType(serviceType);
if ( mime->name() != KMimeType::defaultMimeType() )
mimeName = mime->comment();
// Prepare the URL to show in the question (host only if http, to make it short)
KURL pluginPageURL( embed->pluginPage );
QString shortURL = pluginPageURL.protocol() == "http" ? pluginPageURL.host() : pluginPageURL.prettyURL();
int res = KMessageBox::questionYesNo( m_view,
i18n("No plugin found for '%1'.\nDo you want to download one from %2?").arg(mimeName).arg(shortURL),
i18n("Missing plugin"), QString::null, QString::null, QString("plugin-")+serviceType);
if ( res == KMessageBox::Yes )
{
// Display vendor download page
ext->createNewWindow( pluginPageURL );
}
}
#endif // APPLE_CHANGES
}
void RenderPartObject::layout( )
{
KHTMLAssert( needsLayout() );
KHTMLAssert( minMaxKnown() );
#if !APPLE_CHANGES
int m_oldwidth = m_width;
int m_oldheight = m_height;
#endif
calcWidth();
calcHeight();
RenderPart::layout();
setNeedsLayout(false);
}
void RenderPartObject::slotViewCleared()
{
if(element() && m_widget && m_widget->inherits("QScrollView") ) {
#ifdef DEBUG_LAYOUT
kdDebug(6031) << "iframe is a scrollview!" << endl;
#endif
QScrollView *view = static_cast<QScrollView *>(m_widget);
int frameStyle = QFrame::NoFrame;
QScrollView::ScrollBarMode scroll = QScrollView::Auto;
int marginw = -1;
int marginh = -1;
if ( element()->id() == ID_IFRAME) {
HTMLIFrameElementImpl *frame = static_cast<HTMLIFrameElementImpl *>(element());
if(frame->frameBorder)
frameStyle = QFrame::Box;
scroll = frame->scrolling;
marginw = frame->marginWidth;
marginh = frame->marginHeight;
}
view->setFrameStyle(frameStyle);
#if !APPLE_CHANGES
view->setVScrollBarMode(scroll);
view->setHScrollBarMode(scroll);
#endif
if(view->inherits("KHTMLView")) {
#ifdef DEBUG_LAYOUT
kdDebug(6031) << "frame is a KHTMLview!" << endl;
#endif
KHTMLView *htmlView = static_cast<KHTMLView *>(view);
htmlView->setIgnoreWheelEvents( element()->id() == ID_IFRAME );
if(marginw != -1) htmlView->setMarginWidth(marginw);
if(marginh != -1) htmlView->setMarginHeight(marginh);
}
}
}
#if NOKIA_CHANGES
// Calculate the replaced width
int RenderPartObject::calcReplacedWidth() const
{
if (m_widget && m_widget->hasResized())
{
QRect newRect = m_widget->frameGeometry();
int newWidth = newRect.width();
if (newWidth > 0) {
return newWidth;
}
}
return RenderReplaced::calcReplacedWidth();
}
// Calculate the replaced height
int RenderPartObject::calcReplacedHeight() const
{
if (m_widget && m_widget->hasResized())
{
QRect newRect = m_widget->frameGeometry();
int newHeight = newRect.height();
if (newHeight > 0) {
return newHeight;
}
}
return RenderReplaced::calcReplacedHeight();
}
#ifdef RD_32_BROWSER
bool RenderPartObject::focusable() const
{
if( m_widget ) {
return m_widget->focusable();
}
else
return false;
}
#endif
#endif // NOKIA_CHANGES
#if APPLE_CHANGES
// FIXME: This should not be necessary. Remove this once WebKit knows to properly schedule
// layouts using WebCore when objects resize.
void RenderPart::updateWidgetPositions()
{
if (!m_widget)
return;
int x, y, width, height;
absolutePosition(x,y);
x += borderLeft() + paddingLeft();
y += borderTop() + paddingTop();
width = m_width - borderLeft() - borderRight() - paddingLeft() - paddingRight();
height = m_height - borderTop() - borderBottom() - paddingTop() - paddingBottom();
QRect newBounds(x,y,width,height);
if (newBounds != m_widget->frameGeometry()) {
// The widget changed positions. Update the frame geometry.
RenderArena *arena = ref();
element()->ref();
m_widget->setFrameGeometry(newBounds);
element()->deref();
deref(arena);
QScrollView *view = static_cast<QScrollView *>(m_widget);
#if !NOKIA_CHANGES
if (view && view->inherits("KHTMLView"))
static_cast<KHTMLView*>(view)->layout();
#endif
}
}
#endif
#include "render_frames.moc"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -