📄 pluginview.cpp
字号:
else if (!m_requests.isEmpty()) m_requestTimer.startOneShot(0);}PassRefPtr<JSC::Bindings::Instance> PluginView::bindingInstance(){#if ENABLE(NETSCAPE_PLUGIN_API) NPObject* object = 0; if (!m_plugin || !m_plugin->pluginFuncs()->getvalue) return 0; NPError npErr; { PluginView::setCurrentPluginView(this); JSC::JSLock::DropAllLocks dropAllLocks(false); setCallingPlugin(true); npErr = m_plugin->pluginFuncs()->getvalue(m_instance, NPPVpluginScriptableNPObject, &object); setCallingPlugin(false); PluginView::setCurrentPluginView(0); } if (npErr != NPERR_NO_ERROR || !object) return 0; RefPtr<JSC::Bindings::RootObject> root = m_parentFrame->script()->createRootObject(this); RefPtr<JSC::Bindings::Instance> instance = JSC::Bindings::CInstance::create(object, root.release()); _NPN_ReleaseObject(object); return instance.release();#else return 0;#endif}void PluginView::disconnectStream(PluginStream* stream){ ASSERT(m_streams.contains(stream)); m_streams.remove(stream);}void PluginView::setParameters(const Vector<String>& paramNames, const Vector<String>& paramValues){ ASSERT(paramNames.size() == paramValues.size()); unsigned size = paramNames.size(); unsigned paramCount = 0; m_paramNames = reinterpret_cast<char**>(fastMalloc(sizeof(char*) * size)); m_paramValues = reinterpret_cast<char**>(fastMalloc(sizeof(char*) * size)); for (unsigned i = 0; i < size; i++) { if (m_plugin->quirks().contains(PluginQuirkRemoveWindowlessVideoParam) && equalIgnoringCase(paramNames[i], "windowlessvideo")) continue; m_paramNames[paramCount] = createUTF8String(paramNames[i]); m_paramValues[paramCount] = createUTF8String(paramValues[i]); paramCount++; } m_paramCount = paramCount;}PluginView::PluginView(Frame* parentFrame, const IntSize& size, PluginPackage* plugin, Element* element, const KURL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually) : m_parentFrame(parentFrame) , m_plugin(plugin) , m_element(element) , m_isStarted(false) , m_url(url) , m_baseURL(m_parentFrame->loader()->completeURL(m_parentFrame->document()->baseURL().string())) , m_status(PluginStatusLoadedSuccessfully) , m_requestTimer(this, &PluginView::requestTimerFired) , m_invalidateTimer(this, &PluginView::invalidateTimerFired) , m_popPopupsStateTimer(this, &PluginView::popPopupsStateTimerFired) , m_paramNames(0) , m_paramValues(0)#if defined(XP_MACOSX) , m_isWindowed(false)#else , m_isWindowed(true)#endif , m_isTransparent(false) , m_haveInitialized(false)#if PLATFORM(GTK) || defined(Q_WS_X11) , m_needsXEmbed(false)#endif#if PLATFORM(QT) , m_isNPAPIPlugin(false)#endif#if PLATFORM(WIN_OS) && !PLATFORM(WX) && ENABLE(NETSCAPE_PLUGIN_API) , m_pluginWndProc(0) , m_lastMessage(0) , m_isCallingPluginWndProc(false) , m_wmPrintHDC(0)#endif#if (PLATFORM(QT) && PLATFORM(WIN_OS)) || defined(XP_MACOSX) , m_window(0)#endif , m_loadManually(loadManually) , m_manualStream(0) , m_isJavaScriptPaused(false){ if (!m_plugin) { m_status = PluginStatusCanNotFindPlugin; return; } m_instance = &m_instanceStruct; m_instance->ndata = this; m_instance->pdata = 0; m_mimeType = mimeType.utf8(); setParameters(paramNames, paramValues);#ifdef XP_UNIX m_npWindow.ws_info = 0;#endif m_mode = m_loadManually ? NP_FULL : NP_EMBED; resize(size);}void PluginView::didReceiveResponse(const ResourceResponse& response){ if (m_status != PluginStatusLoadedSuccessfully) return; ASSERT(m_loadManually); ASSERT(!m_manualStream); m_manualStream = PluginStream::create(this, m_parentFrame, m_parentFrame->loader()->activeDocumentLoader()->request(), false, 0, plugin()->pluginFuncs(), instance(), m_plugin->quirks()); m_manualStream->setLoadManually(true); m_manualStream->didReceiveResponse(0, response);}void PluginView::didReceiveData(const char* data, int length){ if (m_status != PluginStatusLoadedSuccessfully) return; ASSERT(m_loadManually); ASSERT(m_manualStream); m_manualStream->didReceiveData(0, data, length);}void PluginView::didFinishLoading(){ if (m_status != PluginStatusLoadedSuccessfully) return; ASSERT(m_loadManually); ASSERT(m_manualStream); m_manualStream->didFinishLoading(0);}void PluginView::didFail(const ResourceError& error){ if (m_status != PluginStatusLoadedSuccessfully) return; ASSERT(m_loadManually); ASSERT(m_manualStream); m_manualStream->didFail(0, error);}void PluginView::setCallingPlugin(bool b) const{ if (!m_plugin->quirks().contains(PluginQuirkHasModalMessageLoop)) return; if (b) ++s_callingPlugin; else --s_callingPlugin; ASSERT(s_callingPlugin >= 0);}bool PluginView::isCallingPlugin(){ return s_callingPlugin > 0;}PluginView* PluginView::create(Frame* parentFrame, const IntSize& size, Element* element, const KURL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually){ // if we fail to find a plugin for this MIME type, findPlugin will search for // a plugin by the file extension and update the MIME type, so pass a mutable String String mimeTypeCopy = mimeType; PluginPackage* plugin = PluginDatabase::installedPlugins()->findPlugin(url, mimeTypeCopy); // No plugin was found, try refreshing the database and searching again if (!plugin && PluginDatabase::installedPlugins()->refresh()) { mimeTypeCopy = mimeType; plugin = PluginDatabase::installedPlugins()->findPlugin(url, mimeTypeCopy); } return new PluginView(parentFrame, size, plugin, element, url, paramNames, paramValues, mimeTypeCopy, loadManually);}void PluginView::freeStringArray(char** stringArray, int length){ if (!stringArray) return; for (int i = 0; i < length; i++) fastFree(stringArray[i]); fastFree(stringArray);}static inline bool startsWithBlankLine(const Vector<char>& buffer){ return buffer.size() > 0 && buffer[0] == '\n';}static inline int locationAfterFirstBlankLine(const Vector<char>& buffer){ const char* bytes = buffer.data(); unsigned length = buffer.size(); for (unsigned i = 0; i < length - 4; i++) { // Support for Acrobat. It sends "\n\n". if (bytes[i] == '\n' && bytes[i + 1] == '\n') return i + 2; // Returns the position after 2 CRLF's or 1 CRLF if it is the first line. if (bytes[i] == '\r' && bytes[i + 1] == '\n') { i += 2; if (i == 2) return i; else if (bytes[i] == '\n') // Support for Director. It sends "\r\n\n" (3880387). return i + 1; else if (bytes[i] == '\r' && bytes[i + 1] == '\n') // Support for Flash. It sends "\r\n\r\n" (3758113). return i + 2; } } return -1;}static inline const char* findEOL(const char* bytes, unsigned length){ // According to the HTTP specification EOL is defined as // a CRLF pair. Unfortunately, some servers will use LF // instead. Worse yet, some servers will use a combination // of both (e.g. <header>CRLFLF<body>), so findEOL needs // to be more forgiving. It will now accept CRLF, LF or // CR. // // It returns NULL if EOLF is not found or it will return // a pointer to the first terminating character. for (unsigned i = 0; i < length; i++) { if (bytes[i] == '\n') return bytes + i; if (bytes[i] == '\r') { // Check to see if spanning buffer bounds // (CRLF is across reads). If so, wait for // next read. if (i + 1 == length) break; return bytes + i; } } return 0;}static inline String capitalizeRFC822HeaderFieldName(const String& name){ bool capitalizeCharacter = true; String result; for (unsigned i = 0; i < name.length(); i++) { UChar c; if (capitalizeCharacter && name[i] >= 'a' && name[i] <= 'z') c = toASCIIUpper(name[i]); else if (!capitalizeCharacter && name[i] >= 'A' && name[i] <= 'Z') c = toASCIILower(name[i]); else c = name[i]; if (name[i] == '-') capitalizeCharacter = true; else capitalizeCharacter = false; result.append(c); } return result;}static inline HTTPHeaderMap parseRFC822HeaderFields(const Vector<char>& buffer, unsigned length){ const char* bytes = buffer.data(); const char* eol; String lastKey; HTTPHeaderMap headerFields; // Loop ove rlines until we're past the header, or we can't find any more end-of-lines while ((eol = findEOL(bytes, length))) { const char* line = bytes; int lineLength = eol - bytes; // Move bytes to the character after the terminator as returned by findEOL. bytes = eol + 1; if ((*eol == '\r') && (*bytes == '\n')) bytes++; // Safe since findEOL won't return a spanning CRLF. length -= (bytes - line); if (lineLength == 0) // Blank line; we're at the end of the header break; else if (*line == ' ' || *line == '\t') { // Continuation of the previous header if (lastKey.isNull()) { // malformed header; ignore it and continue continue; } else { // Merge the continuation of the previous header String currentValue = headerFields.get(lastKey); String newValue(line, lineLength); headerFields.set(lastKey, currentValue + newValue); } } else { // Brand new header const char* colon; for (colon = line; *colon != ':' && colon != eol; colon++) { // empty loop } if (colon == eol) // malformed header; ignore it and continue continue; else { lastKey = capitalizeRFC822HeaderFieldName(String(line, colon - line)); String value; for (colon++; colon != eol; colon++) { if (*colon != ' ' && *colon != '\t') break; } if (colon == eol) value = ""; else value = String(colon, eol - colon); String oldValue = headerFields.get(lastKey); if (!oldValue.isNull()) { String tmp = oldValue; tmp += ", "; tmp += value; value = tmp; } headerFields.set(lastKey, value); } } } return headerFields;}NPError PluginView::handlePost(const char* url, const char* target, uint32 len, const char* buf, bool file, void* notifyData, bool sendNotification, bool allowHeaders){ if (!url || !len || !buf) return NPERR_INVALID_PARAM; FrameLoadRequest frameLoadRequest; HTTPHeaderMap headerFields; Vector<char> buffer; if (file) { NPError readResult = handlePostReadFile(buffer, len, buf); if(readResult != NPERR_NO_ERROR) return readResult; } else { buffer.resize(len); memcpy(buffer.data(), buf, len); } const char* postData = buffer.data(); int postDataLength = buffer.size(); if (allowHeaders) { if (startsWithBlankLine(buffer)) { postData++; postDataLength--; } else { int location = locationAfterFirstBlankLine(buffer); if (location != -1) { // If the blank line is somewhere in the middle of the buffer, everything before is the header headerFields = parseRFC822HeaderFields(buffer, location); unsigned dataLength = buffer.size() - location; // Sometimes plugins like to set Content-Length themselves when they post, // but WebFoundation does not like that. So we will remove the header // and instead truncate the data to the requested length. String contentLength = headerFields.get("Content-Length"); if (!contentLength.isNull()) dataLength = min(contentLength.toInt(), (int)dataLength); headerFields.remove("Content-Length"); postData += location; postDataLength = dataLength; } } } frameLoadRequest.resourceRequest().setHTTPMethod("POST"); frameLoadRequest.resourceRequest().setURL(makeURL(m_baseURL, url)); frameLoadRequest.resourceRequest().addHTTPHeaderFields(headerFields); frameLoadRequest.resourceRequest().setHTTPBody(FormData::create(postData, postDataLength)); frameLoadRequest.setFrameName(target); return load(frameLoadRequest, sendNotification, notifyData);}void PluginView::invalidateWindowlessPluginRect(const IntRect& rect){ if (!isVisible()) return; if (!m_element->renderer()) return; RenderBox* renderer = toRenderBox(m_element->renderer()); IntRect dirtyRect = rect; dirtyRect.move(renderer->borderLeft() + renderer->paddingLeft(), renderer->borderTop() + renderer->paddingTop()); renderer->repaintRectangle(dirtyRect);}void PluginView::paintMissingPluginIcon(GraphicsContext* context, const IntRect& rect){ static RefPtr<Image> nullPluginImage; if (!nullPluginImage) nullPluginImage = Image::loadPlatformResource("nullPlugin"); IntRect imageRect(frameRect().x(), frameRect().y(), nullPluginImage->width(), nullPluginImage->height()); int xOffset = (frameRect().width() - imageRect.width()) / 2; int yOffset = (frameRect().height() - imageRect.height()) / 2; imageRect.move(xOffset, yOffset); if (!rect.intersects(imageRect)) return; context->save(); context->clip(windowClipRect()); context->drawImage(nullPluginImage.get(), imageRect.location()); context->restore();}} // namespace WebCore
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -