📄 kwqkhtmlpart.cpp
字号:
/* * Copyright (C) 2003 Apple Computer, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#include <glib.h>#include <gtk/gtk.h>#include "KWQKHTMLPart.h"#if 0#include "DOMInternal.h"#include "KWQClipboard.h"#endif#include "KWQDOMNode.h"#if 0#include "KWQDummyView.h"#include "KWQExceptions.h"#endif#include "KWQKJobClasses.h"#include "KWQLogging.h"#include "KWQPageState.h"#include "KWQPrinter.h"#include "KWQWindowWidget.h"#if 0#include "WebCoreBridge.h"#include "WebCoreViewFactory.h"#endif#include "csshelper.h"#include "dom2_eventsimpl.h"#include "dom2_rangeimpl.h"#include "dom_position.h"#include "dom_selection.h"#include "dom_textimpl.h"#include "html_documentimpl.h"#include "html_misc.h"#include "htmltokenizer.h"#include "khtml_text_operations.h"#include "khtmlpart_p.h"#include "khtmlview.h"#include "kjs_binding.h"#include "kjs_window.h"#include "misc/htmlattrs.h"#include "qscrollbar.h"#include "render_canvas.h"#include "render_frames.h"#include "render_image.h"#include "render_list.h"#include "render_style.h"#include "render_table.h"#include "render_text.h"#include <JavaScriptCore/identifier.h>#include <JavaScriptCore/property_map.h>#if 0#include <JavaScriptCore/runtime.h>#include <JavaScriptCore/runtime_root.h>#include <JavaScriptCore/WebScriptObjectPrivate.h>#endif#include "WebCoreBridge.h"#include "KWIQMacros.h"#undef _KWQ_TIMINGusing DOM::AtomicString;using DOM::ClipboardEventImpl;using DOM::DocumentImpl;using DOM::DOMString;using DOM::ElementImpl;using DOM::EventImpl;using DOM::HTMLDocumentImpl;using DOM::HTMLElementImpl;using DOM::HTMLFormElementImpl;using DOM::HTMLFrameElementImpl;using DOM::HTMLGenericFormElementImpl;using DOM::HTMLTableCellElementImpl;using DOM::Node;using DOM::NodeImpl;using DOM::Position;using DOM::Range;using DOM::RangeImpl;using DOM::Selection;using DOM::TextImpl;using khtml::Cache;using khtml::ChildFrame;using khtml::Decoder;using khtml::findPlainText;using khtml::InlineTextBox;using khtml::MouseDoubleClickEvent;using khtml::MouseMoveEvent;using khtml::MousePressEvent;using khtml::MouseReleaseEvent;using khtml::parseURL;using khtml::PRE;using khtml::RenderCanvas;using khtml::RenderImage;using khtml::RenderLayer;using khtml::RenderListItem;using khtml::RenderObject;using khtml::RenderPart;using khtml::RenderStyle;using khtml::RenderTableCell;using khtml::RenderText;using khtml::RenderWidget;using khtml::VISIBLE;using KIO::Job;using KJS::Interpreter;using KJS::Location;using KJS::SavedBuiltins;using KJS::SavedProperties;using KJS::ScheduledAction;using KJS::Window;#if 0using KJS::Bindings::Instance;#endifusing KParts::ReadOnlyPart;using KParts::URLArgs;class NSEvent{ int _clickCount;public: NSEvent() : _clickCount(0) {}; int clickCount() { return _clickCount;}};NSEvent *KWQKHTMLPart::_currentEvent = new NSEvent;NSResponder *KWQKHTMLPart::_firstResponderAtMouseDownTime = NULL;void KHTMLPart::completed(){ KWQ(this)->_completed.call();}void KHTMLPart::completed(bool arg){ KWQ(this)->_completed.call(arg);}void KHTMLPart::nodeActivated(const Node &){}bool KHTMLPart::openURL(const KURL &URL){ ASSERT_NOT_REACHED(); return true;}void KHTMLPart::onURL(const QString &){}void KHTMLPart::setStatusBarText(const QString &status){ KWQ(this)->setStatusBarText(status);}void KHTMLPart::started(Job *j){ KWQ(this)->_started.call(j);}static void redirectionTimerMonitor(void *context){ KWQKHTMLPart *kwq = static_cast<KWQKHTMLPart *>(context); kwq->redirectionTimerStartedOrStopped();}KWQKHTMLPart::KWQKHTMLPart() : _bridge(NULL) , _started(this, SIGNAL(started(KIO::Job *))) , _completed(this, SIGNAL(completed())) , _completedWithBool(this, SIGNAL(completed(bool))) , _mouseDownView(NULL) , _mouseDownWasInSubframe(false) , _sendingEventToSubview(false) , _mouseDownMayStartDrag(false) , _mouseDownMayStartSelect(false) , _formValuesAboutToBeSubmitted(0) , _formAboutToBeSubmitted(0) , _windowWidget(NULL) , _usesInactiveTextBackgroundColor(false) , _showsFirstResponder(true) , _drawSelectionOnly(false) , _elementToDraw(0){ QOBJECT_TYPE(KWQKHTMLPart); // Must init the cache before connecting to any signals Cache::init(); // The widget is made outside this class in our case. KHTMLPart::init( 0, DefaultGUI ); mutableInstances().prepend(this); d->m_redirectionTimer.setMonitor(redirectionTimerMonitor, this);}KWQKHTMLPart::~KWQKHTMLPart(){ // ~KHTMLPart::KHTMLPart() calls d->m_redirectionTimer.stop() // would it be better idea to stop the timer here ? --ktkinnun d->m_redirectionTimer.setMonitor(0, 0);#if 0 cleanupPluginRootObjects();#endif mutableInstances().remove(this); if (d->m_view) { d->m_view->deref(); }#if 0 freeClipboard();#endif if (_formValuesAboutToBeSubmitted) { g_hash_table_destroy(_formValuesAboutToBeSubmitted); } _formAboutToBeSubmitted = 0; delete _windowWidget; }#if 0void KWQKHTMLPart::freeClipboard(){ if (_dragClipboard) { _dragClipboard->setAccessPolicy(KWQClipboard::Numb); _dragClipboard->deref(); _dragClipboard = 0; }}#endifvoid KWQKHTMLPart::setSettings (KHTMLSettings *settings){ d->m_settings = settings;}QString KWQKHTMLPart::generateFrameName(){ return QString::fromUtf8(_bridge->generateFrameName());}void KWQKHTMLPart::provisionalLoadStarted(){ // we don't want to wait until we get an actual http response back // to cancel pending redirects, otherwise they might fire before // that happens. cancelRedirection(true);}bool KWQKHTMLPart::openURL(const KURL &url){ bool onLoad = false; if (jScript() && jScript()->interpreter()) { KHTMLPart *rootPart = this; while (rootPart->parentPart() != 0) rootPart = rootPart->parentPart(); KJS::ScriptInterpreter *interpreter = static_cast<KJS::ScriptInterpreter *>(KJSProxy::proxy(rootPart)->interpreter()); DOM::Event *evt = interpreter->getCurrentEvent(); if (evt) { onLoad = (evt->type() == "load"); } } // FIXME: The lack of args here to get the reload flag from // indicates a problem in how we use KHTMLPart::processObjectRequest, // where we are opening the URL before the args are set up. // FIXME: utf8? -- psalmi _bridge->loadURL(url.url().utf8(), _bridge->referrer(), false, // reload: NO onLoad, // onLoadEvent: onLoad "", // target: nil 0, // triggeringEvent: nil 0, // form: nil 0); // formValues return true;}void KWQKHTMLPart::openURLRequest(const KURL &url, const URLArgs &args){ //FIXME: utf8? -- psalmi _bridge->loadURL(url.url().utf8(), _bridge->referrer(), args.reload, // reload: args.reload false, // onLoadEvent: false args.frameName.utf8(), // frame: args.frameName 0, // event: nil 0, // form: nil 0); // formvalues: nil}void KWQKHTMLPart::didNotOpenURL(const KURL &URL){ if (_submittedFormURL == URL) { _submittedFormURL = KURL(); }}// Scans logically forward from "start", including any child framesstatic HTMLFormElementImpl *scanForForm(NodeImpl *start){ NodeImpl *n; for (n = start; n; n = n->traverseNextNode()) { NodeImpl::Id nodeID = idFromNode(n); if (nodeID == ID_FORM) { return static_cast<HTMLFormElementImpl *>(n); } else if (n->isHTMLElement() && static_cast<HTMLElementImpl *>(n)->isGenericFormElement()) { return static_cast<HTMLGenericFormElementImpl *>(n)->form(); } else if (nodeID == ID_FRAME || nodeID == ID_IFRAME) { NodeImpl *childDoc = static_cast<HTMLFrameElementImpl *>(n)->contentDocument(); HTMLFormElementImpl *frameResult = scanForForm(childDoc); if (frameResult) { return frameResult; } } } return 0;}// We look for either the form containing the current focus, or for one immediately after itHTMLFormElementImpl *KWQKHTMLPart::currentForm() const{ // start looking either at the active (first responder) node, or where the selection is NodeImpl *start = activeNode().handle(); if (!start) { start = selectionStart(); } // try walking up the node tree to find a form element NodeImpl *n; for (n = start; n; n = n->parentNode()) { if (idFromNode(n) == ID_FORM) { return static_cast<HTMLFormElementImpl *>(n); } else if (n->isHTMLElement() && static_cast<HTMLElementImpl *>(n)->isGenericFormElement()) { return static_cast<HTMLGenericFormElementImpl *>(n)->form(); } } // try walking forward in the node tree to find a form element if (!start) { start = xmlDocImpl(); } return scanForForm(start);}#if 0 //FIXME: KWIQ: commented block// Either get cached regexp or build one that matches any of the labels.// The regexp we build is of the form: (STR1|STR2|STRN)QRegExp *regExpForLabels(NSArray *labels){ // All the ObjC calls in this method are simple array and string // calls which we can assume do not raise exceptions // Parallel arrays that we use to cache regExps. In practice the number of expressions // that the app will use is equal to the number of locales is used in searching. static const unsigned int regExpCacheSize = 4; static NSMutableArray *regExpLabels = nil; static QPtrList <QRegExp> regExps; static QRegExp wordRegExp = QRegExp("\\w"); QRegExp *result; if (!regExpLabels) { regExpLabels = [[NSMutableArray alloc] initWithCapacity:regExpCacheSize]; } unsigned int cacheHit = [regExpLabels indexOfObject:labels]; if (cacheHit != NSNotFound) { result = regExps.at(cacheHit); } else { QString pattern("("); unsigned int numLabels = [labels count]; unsigned int i; for (i = 0; i < numLabels; i++) { QString label = QString::fromNSString([labels objectAtIndex:i]); bool startsWithWordChar = false; bool endsWithWordChar = false; if (label.length() != 0) { startsWithWordChar = wordRegExp.search(label.at(0)) >= 0; endsWithWordChar = wordRegExp.search(label.at(label.length() - 1)) >= 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -