📄 kwqkhtmlpart.cpp
字号:
}
void KWQKHTMLPart::updatePolicyBaseURL()
{
// FIXME: docImpl() returns null for everything other than HTML documents; is this causing problems? -dwh
if (parentPart() && parentPart()->xmlDocImpl()) {
setPolicyBaseURL(parentPart()->xmlDocImpl()->policyBaseURL());
} else {
setPolicyBaseURL(m_url.url());
}
}
void KWQKHTMLPart::setPolicyBaseURL(const DOMString &s)
{
// FIXME: XML documents will cause this to return null. docImpl() is
// an HTMLdocument only. -dwh
if (xmlDocImpl())
xmlDocImpl()->setPolicyBaseURL(s);
ConstFrameIt end = d->m_frames.end();
for (ConstFrameIt it = d->m_frames.begin(); it != end; ++it) {
ReadOnlyPart *subpart = (*it).m_part;
static_cast<KWQKHTMLPart *>(subpart)->setPolicyBaseURL(s);
}
}
QString KWQKHTMLPart::requestedURLString() const
{
return QString::FromDes(_bridge->Client().RequestedURLString());
}
QString KWQKHTMLPart::incomingReferrer() const
{
return QString::FromDes(_bridge->Client().IncomingReferrer());
}
void KWQKHTMLPart::forceLayout()
{
KHTMLView *v = d->m_view;
if (v) {
v->layout();
// We cannot unschedule a pending relayout, since the force can be called with
// a tiny rectangle from a drawRect update. By unscheduling we in effect
// "validate" and stop the necessary full repaint from occurring. Basically any basic
// append/remove DHTML is broken by this call. For now, I have removed the optimization
// until we have a better invalidation stategy. -dwh
//v->unscheduleRelayout();
}
}
void KWQKHTMLPart::forceLayoutWithPageWidthRange(int minPageWidth, int maxPageWidth)
{
// Dumping externalRepresentation(_part->renderer()).ascii() is a good trick to see
// the state of things before and after the layout
RenderCanvas *root = static_cast<RenderCanvas *>(xmlDocImpl()->renderer());
if (root) {
// This magic is basically copied from khtmlview::print
int pageW = minPageWidth;
root->setWidth(pageW);
root->setNeedsLayoutAndMinMaxRecalc();
forceLayout();
// If we don't fit in the minimum page width, we'll lay out again. If we don't fit in the
// maximum page width, we will lay out to the maximum page width and clip extra content.
// FIXME: We are assuming a shrink-to-fit printing implementation. A cropping
// implementation should not do this!
int rightmostPos = root->rightmostPosition();
if (rightmostPos > minPageWidth) {
pageW = kMin(rightmostPos, maxPageWidth);
root->setWidth(pageW);
root->setNeedsLayoutAndMinMaxRecalc();
forceLayout();
}
}
}
void KWQKHTMLPart::sendResizeEvent()
{
KHTMLView *v = d->m_view;
if (v) {
// Sending an event can result in the destruction of the view and part.
// We ref so that happens after we return from the KHTMLView function.
v->ref();
QResizeEvent e;
v->resizeEvent(&e);
v->deref();
}
}
void KWQKHTMLPart::sendScrollEvent()
{
KHTMLView *v = d->m_view;
if (v) {
DocumentImpl *doc = xmlDocImpl();
if (!doc)
return;
doc->dispatchHTMLEvent(EventImpl::SCROLL_EVENT, true, false);
}
}
void KWQKHTMLPart::runJavaScriptAlert(const QString &message)
{
QString text = message;
text.replace(QChar('\\'), backslashAsCurrencySymbol());
_bridge->Client().RunJavaScriptAlertPanelWithMessage(text.Des());
}
bool KWQKHTMLPart::runJavaScriptConfirm(const QString &message, const QString &yes, const QString &no)
{
QString text = message;
text.replace(QChar('\\'), backslashAsCurrencySymbol());
return _bridge->Client().RunJavaScriptConfirmPanelWithMessage(text.Des(), yes.Des(), no.Des());
}
bool KWQKHTMLPart::runJavaScriptPrompt(const QString &prompt, const QString &defaultValue, QString &result)
{
QString promptText = prompt;
promptText.replace(QChar('\\'), backslashAsCurrencySymbol());
QString defaultValueText = defaultValue;
defaultValueText.replace(QChar('\\'), backslashAsCurrencySymbol());
HBufC *returnedText = 0;
bool ok = _bridge->Client().RunJavaScriptTextInputPanelWithPrompt(prompt.Des(),
defaultValue.Des(), &returnedText);
if (ok ) {
result = QString::FromDes(*returnedText);
result.replace(backslashAsCurrencySymbol(), QChar('\\'));
delete returnedText;
}
return ok;
}
bool KWQKHTMLPart::locationbarVisible()
{
//return [_bridge areToolbarsVisible];
return false;
}
bool KWQKHTMLPart::menubarVisible()
{
return false;
}
bool KWQKHTMLPart::personalbarVisible()
{
//return [_bridge areToolbarsVisible];
return false;
}
bool KWQKHTMLPart::scrollbarsVisible()
{
if (!view())
return false;
if (view()->hScrollBarMode() == QScrollView::AlwaysOff || view()->vScrollBarMode() == QScrollView::AlwaysOff)
return false;
return true;
}
bool KWQKHTMLPart::statusbarVisible()
{
//return [_bridge isStatusBarVisible];
return false;
}
bool KWQKHTMLPart::toolbarVisible()
{
//return [_bridge areToolbarsVisible];
return false;
}
void KWQKHTMLPart::addMessageToConsole(const QString &message, unsigned lineNumber, const QString &sourceURL)
{
// ### NOT IMPLEMENTED javascript console
/*
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
message.getNSString(), @"message",
[NSNumber numberWithInt: lineNumber], @"lineNumber",
sourceURL.getNSString(), @"sourceURL",
NULL];
[_bridge addMessageToConsole:dictionary];
*/
}
void KWQKHTMLPart::createEmptyDocument()
{
// could not figure out the need for this function
#if 0
// Although it's not completely clear from the name of this function,
// it does nothing if we already have a document, and just creates an
// empty one if we have no document at all.
if (!d->m_doc) {
_bridge->Client().LoadEmptyDocumentSynchronously();
if (parentPart() && (parentPart()->childFrame(this)->m_type == ChildFrame::IFrame ||
parentPart()->childFrame(this)->m_type == ChildFrame::Object)) {
d->m_doc->setBaseURL(parentPart()->d->m_doc->baseURL());
}
}
#endif
}
void KWQKHTMLPart::addMetaData(const QString &key, const QString &value)
{
d->m_job->addMetaData(key, value);
}
bool KWQKHTMLPart::KeyEvent(const TKeyEvent& event, bool keyup)
{
// Check for cases where we are too early for events -- possible unmatched key up
// from pressing return in the location bar.
DocumentImpl *doc = xmlDocImpl();
if (!doc) {
return false;
}
NodeImpl *node = doc->focusNode();
if (!node) {
node = doc->body();
if (!node)
return false;
}
// On key down, clear the "don't submit form twice" data member.
if (!keyup) {
prepareForUserAction();
}
//NSEvent *oldCurrentEvent = _currentEvent;
//_currentEvent = KWQRetain(event);
bool result;
QEvent::Type evtype = keyup?QEvent::KeyRelease:QEvent::KeyPress;
QKeyEvent qEvent(evtype, event);
result = !node->dispatchKeyEvent(&qEvent);
// We want to send both a down and a press for the initial key event.
// To get KHTML to do this, we send a second KeyPress QKeyEvent with "is repeat" set to true,
// which causes it to send a press to the DOM.
// That's not a great hack; it would be good to do this in a better way.
if (!keyup && !event.iRepeats) {
QKeyEvent repeatEvent(QEvent::KeyPress, event, true);
if (!node->dispatchKeyEvent(&repeatEvent)) {
result = true;
}
}
//ASSERT(_currentEvent == event);
//KWQRelease(event);
//_currentEvent = oldCurrentEvent;
return result;
}
bool KWQKHTMLPart::activateEvent()
{
// from pressing return in the location bar.
DocumentImpl *doc = xmlDocImpl();
if (!doc) {
return false;
}
NodeImpl *focusNode = doc->focusNode();
if (!focusNode) {
focusNode = doc->body();
if (!focusNode)
return false;
}
focusNode->ref();
// TODO for select element - EElementSelectBox
// should be element node
if (focusNode->isElementNode()) {
NodeImpl::Id id = idFromNode(focusNode);
if(id == ID_TEXTAREA) {
if(!static_cast<RenderWidget*>(focusNode->renderer())->widget()->isActive()) {
static_cast<RenderWidget*>(focusNode->renderer())->widget()->activate();
}
}
else if (id == ID_INPUT) {
HTMLInputElementImpl* inputElement = static_cast<HTMLInputElementImpl *>(focusNode);
if(inputElement->inputType() == HTMLInputElementImpl::TEXT ||
inputElement->inputType() == HTMLInputElementImpl::PASSWORD ||
inputElement->inputType() == HTMLInputElementImpl::RADIO ||
inputElement->inputType() == HTMLInputElementImpl::CHECKBOX ||
inputElement->inputType() == HTMLInputElementImpl::FILE){
if(!static_cast<RenderWidget*>(focusNode->renderer())->widget()->isActive()) {
static_cast<RenderWidget*>(focusNode->renderer())->widget()->activate();
}
}
}
else if (id == ID_SELECT) {
if(!static_cast<RenderWidget*>(focusNode->renderer())->widget()->isActive()) {
static_cast<RenderWidget*>(focusNode->renderer())->widget()->activate();
}
}
else if ((id == ID_OBJECT) || (id == ID_EMBED)) {
if(focusNode->renderer()->isWidget()) {
if(!static_cast<RenderWidget*>(focusNode->renderer())->widget()->isActive()) {
static_cast<RenderWidget*>(focusNode->renderer())->widget()->activate();
}
}
}
}
if(focusNode->renderer() && focusNode->renderer()->isWidget()) {
static_cast<RenderWidget*>(focusNode->renderer())->widget()->clicked();
} else if (focusNode->isHTMLElement() ) {
static_cast<HTMLElementImpl*>(focusNode)->click(false);
}
focusNode->deref();
return true;
}
void KWQKHTMLPart::activateNodeAtPoint(const QPoint &point)
{
// On ActivateEvent, clear the "don't submit form twice" data member.
prepareForUserAction();
RenderObject::NodeInfo renderInfo(true, false);
renderer()->layer()->hitTest(renderInfo, point.x(), point.y());
NodeImpl *navNode = renderInfo.innerNode();
bool activate = false;
for (; navNode; navNode = navNode->parentNode()) {
if (navNode->isElementNode() && navNode->isFocusable()) {
bool canBeFocused = true;
switch (navNode->id()) {
case ID_INPUT:
{
HTMLInputElementImpl* inputElement = static_cast<HTMLInputElementImpl *>(navNode);
activate = inputElement &&
(inputElement->inputType() == HTMLInputElementImpl::TEXT ||
inputElement->inputType() == HTMLInputElementImpl::PASSWORD ||
inputElement->inputType() == HTMLInputElementImpl::RADIO ||
inputElement->inputType() == HTMLInputElementImpl::CHECKBOX ||
inputElement->inputType() == HTMLInputElementImpl::FILE);
break;
}
case ID_SELECT:
case ID_TEXTAREA:
activate = true;
break;
case ID_OBJECT:
case ID_EMBED:
activate = navNode->renderer()->isWidget();
break;
default:
canBeFocused = false;
break;
}//End switch statement
if(canBeFocused) {
break;
}
}
if (navNode->isElementNode() && navNode->renderer() &&
navNode->renderer()->layer()) {
QScrollBar* hbar = navNode->renderer()->layer()->horizontalScrollbar();
QScrollBar* vbar = navNode->renderer()->layer()->verticalScrollbar();
if (hbar)
hbar->clickAtPoint(point);
if (vbar)
vbar->clickAtPoint(point);
}
}
if(navNode) {
navNode->ref();
if(navNode->renderer() && navNode->renderer()->isWidget()) {
QWidget* w = static_cast<RenderWidget*>(navNode->renderer())->widget();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -