File indexing completed on 2023-09-24 04:06:13
0001 /* 0002 * This file is part of the KDE libraries 0003 * Copyright (C) 2000 Harri Porten (porten@kde.org) 0004 * Copyright (c) 2000 Daniel Molkentin (molkentin@kde.org) 0005 * Copyright (c) 2000 Stefan Schimanski (schimmi@kde.org) 0006 * Copyright (C) 2003 Apple Computer, Inc. 0007 * 0008 * This library is free software; you can redistribute it and/or 0009 * modify it under the terms of the GNU Library General Public 0010 * License as published by the Free Software Foundation; either 0011 * version 2 of the License, or (at your option) any later version. 0012 * 0013 * This library is distributed in the hope that it will be useful, 0014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0016 * Library General Public License for more details. 0017 * 0018 * You should have received a copy of the GNU Library General Public 0019 * License along with this library; if not, write to the Free Software 0020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 0021 */ 0022 0023 #include "kjs_navigator.h" 0024 #include "kjs_navigator.lut.h" 0025 0026 #include <QLocale> 0027 0028 #include <kconfig.h> 0029 #include <kconfiggroup.h> 0030 #include <ksharedconfig.h> 0031 #include "khtml_debug.h" 0032 0033 #include <kprotocolmanager.h> 0034 #include <kservice.h> 0035 #include <kservicetypetrader.h> 0036 #include <kjs/lookup.h> 0037 #include <kjs_binding.h> 0038 #include <khtml_part.h> 0039 #include <qsysinfo.h> 0040 #include <qstandardpaths.h> 0041 0042 using namespace KJS; 0043 0044 namespace KJS 0045 { 0046 0047 // All objects that need plugin info must inherit from PluginBase 0048 // Its ctor and dtor take care of the refcounting on the static lists. 0049 class PluginBase : public JSObject 0050 { 0051 public: 0052 PluginBase(ExecState *exec, bool loadPluginInfo); 0053 virtual ~PluginBase(); 0054 0055 struct MimeClassInfo; 0056 struct PluginInfo; 0057 0058 struct MimeClassInfo { 0059 QString type; 0060 QString desc; 0061 QString suffixes; 0062 PluginInfo *plugin; 0063 }; 0064 0065 struct PluginInfo { 0066 QString name; 0067 QString file; 0068 QString desc; 0069 QList<const MimeClassInfo *> mimes; 0070 }; 0071 0072 static QList<const PluginInfo *> *plugins; 0073 static QList<const MimeClassInfo *> *mimes; 0074 0075 private: 0076 static int m_refCount; 0077 }; 0078 0079 class Plugins : public PluginBase 0080 { 0081 public: 0082 Plugins(ExecState *exec, bool pluginsEnabled) 0083 : PluginBase(exec, pluginsEnabled), 0084 m_pluginsEnabled(pluginsEnabled) {} 0085 0086 using KJS::JSObject::getOwnPropertySlot; 0087 bool getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) override; 0088 JSValue *getValueProperty(ExecState *exec, int token) const; 0089 const ClassInfo *classInfo() const override 0090 { 0091 return &info; 0092 } 0093 static const ClassInfo info; 0094 static JSValue *pluginByName(ExecState *exec, const QString &name); 0095 bool pluginsEnabled() const 0096 { 0097 return m_pluginsEnabled; 0098 } 0099 private: 0100 static JSValue *indexGetter(ExecState *, JSObject *, const Identifier &, const PropertySlot &); 0101 static JSValue *nameGetter(ExecState *, JSObject *, const Identifier &, const PropertySlot &); 0102 bool m_pluginsEnabled; 0103 }; 0104 0105 class MimeTypes : public PluginBase 0106 { 0107 public: 0108 MimeTypes(ExecState *exec, bool pluginsEnabled) 0109 : PluginBase(exec, pluginsEnabled), 0110 m_pluginsEnabled(pluginsEnabled) {} 0111 using KJS::JSObject::getOwnPropertySlot; 0112 bool getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) override; 0113 const ClassInfo *classInfo() const override 0114 { 0115 return &info; 0116 } 0117 static const ClassInfo info; 0118 JSValue *getValueProperty(ExecState *exec, int token) const; 0119 static JSValue *mimeTypeByName(ExecState *exec, const QString &name); 0120 bool pluginsEnabled() const 0121 { 0122 return m_pluginsEnabled; 0123 } 0124 private: 0125 static JSValue *indexGetter(ExecState *, JSObject *, const Identifier &, const PropertySlot &); 0126 static JSValue *nameGetter(ExecState *, JSObject *, const Identifier &, const PropertySlot &); 0127 bool m_pluginsEnabled; 0128 }; 0129 0130 class Plugin : public PluginBase 0131 { 0132 public: 0133 Plugin(ExecState *exec, const PluginBase::PluginInfo *info) 0134 : PluginBase(exec, true) 0135 { 0136 m_info = info; 0137 } 0138 using KJS::JSObject::getOwnPropertySlot; 0139 bool getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) override; 0140 const ClassInfo *classInfo() const override 0141 { 0142 return &info; 0143 } 0144 static const ClassInfo info; 0145 JSValue *mimeByName(ExecState *exec, const QString &name) const; 0146 JSValue *getValueProperty(ExecState *exec, int token) const; 0147 const PluginBase::PluginInfo *pluginInfo() const 0148 { 0149 return m_info; 0150 } 0151 private: 0152 const PluginBase::PluginInfo *m_info; 0153 static JSValue *indexGetter(ExecState *, JSObject *, const Identifier &, const PropertySlot &); 0154 static JSValue *nameGetter(ExecState *, JSObject *, const Identifier &, const PropertySlot &); 0155 }; 0156 0157 class MimeType : public PluginBase 0158 { 0159 public: 0160 MimeType(ExecState *exec, const PluginBase::MimeClassInfo *info) 0161 : PluginBase(exec, true) 0162 { 0163 m_info = info; 0164 } 0165 using KJS::JSObject::getOwnPropertySlot; 0166 bool getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) override; 0167 const ClassInfo *classInfo() const override 0168 { 0169 return &info; 0170 } 0171 static const ClassInfo info; 0172 JSValue *getValueProperty(ExecState *exec, int token) const; 0173 private: 0174 const PluginBase::MimeClassInfo *m_info; 0175 }; 0176 0177 } 0178 0179 QList<const PluginBase::PluginInfo *> *KJS::PluginBase::plugins; 0180 QList<const PluginBase::MimeClassInfo *> *KJS::PluginBase::mimes; 0181 int KJS::PluginBase::m_refCount; 0182 0183 const ClassInfo Navigator::info = { "Navigator", nullptr, &NavigatorTable, nullptr }; 0184 /* 0185 @begin NavigatorTable 12 0186 appCodeName Navigator::AppCodeName DontDelete|ReadOnly 0187 appName Navigator::AppName DontDelete|ReadOnly 0188 appVersion Navigator::AppVersion DontDelete|ReadOnly 0189 language Navigator::Language DontDelete|ReadOnly 0190 userAgent Navigator::UserAgent DontDelete|ReadOnly 0191 userLanguage Navigator::UserLanguage DontDelete|ReadOnly 0192 browserLanguage Navigator::BrowserLanguage DontDelete|ReadOnly 0193 platform Navigator::Platform DontDelete|ReadOnly 0194 cpuClass Navigator::CpuClass DontDelete|ReadOnly 0195 plugins Navigator::_Plugins DontDelete|ReadOnly 0196 mimeTypes Navigator::_MimeTypes DontDelete|ReadOnly 0197 product Navigator::Product DontDelete|ReadOnly 0198 vendor Navigator::Vendor DontDelete|ReadOnly 0199 vendorSub Navigator::VendorSub DontDelete|ReadOnly 0200 productSub Navigator::ProductSub DontDelete|ReadOnly 0201 cookieEnabled Navigator::CookieEnabled DontDelete|ReadOnly 0202 javaEnabled Navigator::JavaEnabled DontDelete|Function 0 0203 @end 0204 */ 0205 KJS_IMPLEMENT_PROTOFUNC(NavigatorFunc) 0206 0207 Navigator::Navigator(ExecState *exec, KHTMLPart *p) 0208 : JSObject(exec->lexicalInterpreter()->builtinObjectPrototype()), m_part(p) { } 0209 0210 bool Navigator::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) 0211 { 0212 #ifdef KJS_VERBOSE 0213 qCDebug(KHTML_LOG) << "Navigator::getOwnPropertySlot " << propertyName.ascii(); 0214 #endif 0215 return getStaticPropertySlot<NavigatorFunc, Navigator, JSObject>(exec, &NavigatorTable, this, propertyName, slot); 0216 } 0217 0218 JSValue *Navigator::getValueProperty(ExecState *exec, int token) const 0219 { 0220 QUrl url = m_part->url(); 0221 QString host = url.host(); 0222 if (host.isEmpty()) { 0223 host = "localhost"; 0224 } 0225 QString userAgent = KProtocolManager::userAgentForHost(host); 0226 // ### get the following from the spoofing UA files as well. 0227 QString appName = "Netscape"; 0228 QString product = "Gecko"; 0229 QString productSub = "20030107"; 0230 QString vendor = "KDE"; 0231 QString vendorSub = ""; 0232 0233 switch (token) { 0234 case AppCodeName: 0235 return jsString("Mozilla"); 0236 case AppName: 0237 // If we find "Mozilla" but not "(compatible, ...)" we are a real Netscape 0238 if (userAgent.indexOf(QLatin1String("Mozilla")) >= 0 && 0239 userAgent.indexOf(QLatin1String("compatible")) == -1) { 0240 //qCDebug(KHTML_LOG) << "appName -> Mozilla"; 0241 return jsString("Netscape"); 0242 } 0243 if (userAgent.indexOf(QLatin1String("Microsoft")) >= 0 || 0244 userAgent.indexOf(QLatin1String("MSIE")) >= 0) { 0245 //qCDebug(KHTML_LOG) << "appName -> IE"; 0246 return jsString("Microsoft Internet Explorer"); 0247 } 0248 //qCDebug(KHTML_LOG) << "appName -> Default"; 0249 return jsString(appName); 0250 case AppVersion: 0251 // We assume the string is something like Mozilla/version (properties) 0252 return jsString(userAgent.mid(userAgent.indexOf('/') + 1)); 0253 case Product: 0254 // We are pretending to be Mozilla or Safari 0255 if (userAgent.indexOf(QLatin1String("Mozilla")) >= 0 && 0256 userAgent.indexOf(QLatin1String("compatible")) == -1) { 0257 return jsString("Gecko"); 0258 } 0259 // When spoofing as IE, we use jsUndefined(). 0260 if (userAgent.indexOf(QLatin1String("Microsoft")) >= 0 || 0261 userAgent.indexOf(QLatin1String("MSIE")) >= 0) { 0262 return jsUndefined(); 0263 } 0264 return jsString(product); 0265 case ProductSub: { 0266 int ix = userAgent.indexOf("Gecko"); 0267 if (ix >= 0 && userAgent.length() >= ix + 14 && userAgent.at(ix + 5) == '/' && 0268 userAgent.indexOf(QRegExp("\\d{8}"), ix + 6) == ix + 6) { 0269 // We have Gecko/<productSub> in the UA string 0270 return jsString(userAgent.mid(ix + 6, 8)); 0271 } 0272 } 0273 return jsString(productSub); 0274 case Vendor: 0275 if (userAgent.indexOf(QLatin1String("Safari")) >= 0) { 0276 return jsString("Apple Computer, Inc."); 0277 } 0278 return jsString(vendor); 0279 case VendorSub: 0280 return jsString(vendorSub); 0281 case BrowserLanguage: 0282 case Language: 0283 case UserLanguage: 0284 return jsString(QLocale::languageToString(QLocale().language())); 0285 case UserAgent: 0286 return jsString(userAgent); 0287 case Platform: 0288 // yet another evil hack, but necessary to spoof some sites... 0289 if ((userAgent.indexOf(QLatin1String("Win"), 0, Qt::CaseInsensitive) >= 0)) { 0290 return jsString("Win32"); 0291 } else if ((userAgent.indexOf(QLatin1String("Macintosh"), 0, Qt::CaseInsensitive) >= 0) || 0292 (userAgent.indexOf(QLatin1String("Mac_PowerPC"), 0, Qt::CaseInsensitive) >= 0)) { 0293 return jsString("MacPPC"); 0294 } else { 0295 return jsString(QString::fromLatin1("%1 %2").arg(QSysInfo::kernelType()).arg(QSysInfo::currentCpuArchitecture())); 0296 } 0297 case CpuClass: 0298 return jsString(QSysInfo::currentCpuArchitecture()); 0299 case _Plugins: 0300 return new Plugins(exec, m_part->pluginsEnabled()); 0301 case _MimeTypes: 0302 return new MimeTypes(exec, m_part->pluginsEnabled()); 0303 case CookieEnabled: 0304 return jsBoolean(true); /// ##### FIXME 0305 default: 0306 // qCDebug(KHTML_LOG) << "WARNING: Unhandled token in DOMEvent::getValueProperty : " << token; 0307 return jsNull(); 0308 } 0309 } 0310 0311 /*******************************************************************/ 0312 0313 PluginBase::PluginBase(ExecState *exec, bool loadPluginInfo) 0314 : JSObject(exec->lexicalInterpreter()->builtinObjectPrototype()) 0315 { 0316 if (loadPluginInfo && !plugins) { 0317 plugins = new QList<const PluginInfo *>; 0318 mimes = new QList<const MimeClassInfo *>; 0319 0320 // read in using KServiceTypeTrader 0321 const KService::List offers = KServiceTypeTrader::self()->query("Browser/View"); 0322 KService::List::const_iterator it; 0323 for (it = offers.begin(); it != offers.end(); ++it) { 0324 0325 QVariant pluginsinfo = (**it).property("X-KDE-BrowserView-PluginsInfo"); 0326 if (!pluginsinfo.isValid()) { 0327 // <backwards compatible> 0328 if ((**it).library() == QLatin1String("libnsplugin")) { 0329 pluginsinfo = QVariant("nsplugins/pluginsinfo"); 0330 } else 0331 // </backwards compatible> 0332 { 0333 continue; 0334 } 0335 } 0336 // read configuration 0337 QString fn = QStandardPaths::locate(QStandardPaths::GenericDataLocation, pluginsinfo.toString()); 0338 const KSharedConfig::Ptr sc = KSharedConfig::openConfig(fn); 0339 const int num = sc->group("").readEntry("number", 0); 0340 for (int n = 0; n < num; n++) { 0341 const KConfigGroup kc = sc->group(QString::number(n)); 0342 PluginInfo *plugin = new PluginInfo; 0343 0344 plugin->name = kc.readEntry("name"); 0345 plugin->file = kc.readPathEntry("file", QString()); 0346 plugin->desc = kc.readEntry("description"); 0347 0348 plugins->append(plugin); 0349 0350 const QStringList types = kc.readXdgListEntry("mime"); 0351 QStringList::const_iterator type; 0352 for (type = types.begin(); type != types.end(); ++type) { 0353 0354 // get mime information 0355 const QStringList tokens = (*type).split(':', QString::KeepEmptyParts); 0356 if (tokens.count() < 3) { // we need 3 items 0357 continue; 0358 } 0359 0360 MimeClassInfo *mime = new MimeClassInfo; 0361 QStringList::ConstIterator token = tokens.begin(); 0362 mime->type = (*token).toLower(); 0363 //qCDebug(KHTML_LOG) << "mime->type=" << mime->type; 0364 ++token; 0365 0366 mime->suffixes = *token; 0367 ++token; 0368 0369 mime->desc = *token; 0370 ++token; 0371 0372 mime->plugin = plugin; 0373 0374 mimes->append(mime); 0375 plugin->mimes.append(mime); 0376 0377 } 0378 } 0379 } 0380 } 0381 0382 m_refCount++; 0383 } 0384 0385 PluginBase::~PluginBase() 0386 { 0387 m_refCount--; 0388 if (m_refCount == 0) { 0389 if (plugins) { 0390 qDeleteAll(*plugins); 0391 } 0392 if (mimes) { 0393 qDeleteAll(*mimes); 0394 } 0395 delete plugins; 0396 delete mimes; 0397 plugins = nullptr; 0398 mimes = nullptr; 0399 } 0400 } 0401 0402 /*******************************************************************/ 0403 0404 const ClassInfo Plugins::info = { "PluginArray", nullptr, &PluginsTable, nullptr }; 0405 /* 0406 @begin PluginsTable 4 0407 length Plugins_Length DontDelete|ReadOnly 0408 refresh Plugins_Refresh DontDelete|Function 0 0409 item Plugins_Item DontDelete|Function 1 0410 namedItem Plugins_NamedItem DontDelete|Function 1 0411 @end 0412 */ 0413 KJS_IMPLEMENT_PROTOFUNC(PluginsFunc) 0414 0415 JSValue *Plugins::getValueProperty(ExecState *, int token) const 0416 { 0417 assert(token == Plugins_Length); 0418 Q_UNUSED(token); 0419 if (pluginsEnabled()) { 0420 return jsNumber(plugins->count()); 0421 } else { 0422 return jsNumber(0); 0423 } 0424 } 0425 0426 JSValue *Plugins::indexGetter(ExecState *exec, JSObject *, const Identifier & /*propertyName*/, const PropertySlot &slot) 0427 { 0428 return new Plugin(exec, plugins->at(slot.index())); 0429 } 0430 0431 JSValue *Plugins::nameGetter(ExecState *exec, JSObject *, const Identifier &propertyName, const PropertySlot & /*slot*/) 0432 { 0433 return pluginByName(exec, propertyName.qstring()); 0434 } 0435 0436 bool Plugins::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) 0437 { 0438 #ifdef KJS_VERBOSE 0439 qCDebug(KHTML_LOG) << "Plugins::getOwnPropertySlot " << propertyName.qstring(); 0440 #endif 0441 if (getStaticOwnPropertySlot<PluginsFunc, Plugins>(&PluginsTable, this, propertyName, slot)) { 0442 return true; 0443 } 0444 0445 if (pluginsEnabled()) { 0446 // plugins[#] 0447 bool ok; 0448 unsigned int i = propertyName.toArrayIndex(&ok); 0449 if (ok && i < static_cast<unsigned>(plugins->count())) { 0450 slot.setCustomIndex(this, i, indexGetter); 0451 return true; 0452 } 0453 0454 // plugin[name] 0455 QList<const PluginInfo *>::const_iterator it, end = plugins->constEnd(); 0456 for (it = plugins->constBegin(); it != end; ++it) { 0457 if ((*it)->name == propertyName.qstring()) { 0458 slot.setCustom(this, nameGetter); 0459 return true; 0460 } 0461 } 0462 } 0463 0464 return PluginBase::getOwnPropertySlot(exec, propertyName, slot); 0465 } 0466 0467 JSValue *Plugins::pluginByName(ExecState *exec, const QString &name) 0468 { 0469 QList<const PluginInfo *>::const_iterator it, end = plugins->constEnd(); 0470 for (it = plugins->constBegin(); it != end; ++it) { 0471 if ((*it)->name == name) { 0472 return new Plugin(exec, *it); 0473 } 0474 } 0475 return jsUndefined(); 0476 } 0477 0478 JSValue *PluginsFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args) 0479 { 0480 KJS_CHECK_THIS(KJS::Plugins, thisObj); 0481 0482 KJS::Plugins *base = static_cast<KJS::Plugins *>(thisObj); 0483 if (!base->pluginsEnabled()) { 0484 return jsUndefined(); 0485 } 0486 0487 switch (id) { 0488 case Plugins_Refresh: 0489 return jsUndefined(); //## TODO 0490 case Plugins_Item: { 0491 bool ok; 0492 unsigned int i = args[0]->toString(exec).toArrayIndex(&ok); 0493 if (ok && i < static_cast<unsigned>(base->plugins->count())) { 0494 return new Plugin(exec, base->plugins->at(i)); 0495 } 0496 return jsUndefined(); 0497 } 0498 case Plugins_NamedItem: { 0499 UString s = args[0]->toString(exec); 0500 return base->pluginByName(exec, s.qstring()); 0501 } 0502 default: 0503 // qCDebug(KHTML_LOG) << "WARNING: Unhandled token in PluginsFunc::callAsFunction : " << id; 0504 return jsUndefined(); 0505 } 0506 } 0507 0508 /*******************************************************************/ 0509 0510 const ClassInfo MimeTypes::info = { "MimeTypeArray", nullptr, &MimeTypesTable, nullptr }; 0511 /* 0512 @begin MimeTypesTable 3 0513 length MimeTypes_Length DontDelete|ReadOnly 0514 item MimeTypes_Item DontDelete|Function 1 0515 namedItem MimeTypes_NamedItem DontDelete|Function 1 0516 @end 0517 */ 0518 KJS_IMPLEMENT_PROTOFUNC(MimeTypesFunc) 0519 0520 JSValue *MimeTypes::indexGetter(ExecState *exec, JSObject *, const Identifier & /*propertyName*/, const PropertySlot &slot) 0521 { 0522 return new MimeType(exec, mimes->at(slot.index())); 0523 } 0524 0525 JSValue *MimeTypes::nameGetter(ExecState *exec, JSObject *, const Identifier &propertyName, const PropertySlot & /*slot*/) 0526 { 0527 return mimeTypeByName(exec, propertyName.qstring()); 0528 } 0529 0530 bool MimeTypes::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) 0531 { 0532 #ifdef KJS_VERBOSE 0533 qCDebug(KHTML_LOG) << "MimeTypes::getOwnPropertySlot " << propertyName.qstring(); 0534 #endif 0535 if (getStaticOwnPropertySlot<MimeTypesFunc, MimeTypes>(&MimeTypesTable, this, propertyName, slot)) { 0536 return true; 0537 } 0538 0539 if (pluginsEnabled()) { 0540 // mimeTypes[#] 0541 bool ok; 0542 unsigned int i = propertyName.toArrayIndex(&ok); 0543 if (ok && i < static_cast<unsigned>(mimes->count())) { 0544 slot.setCustomIndex(this, i, indexGetter); 0545 return true; 0546 } 0547 0548 // mimeTypes[name] 0549 QList<const MimeClassInfo *>::const_iterator it, end = mimes->constEnd(); 0550 for (it = mimes->constBegin(); it != end; ++it) { 0551 if ((*it)->type == propertyName.qstring()) { 0552 slot.setCustom(this, nameGetter); 0553 return true; 0554 } 0555 } 0556 } 0557 0558 return PluginBase::getOwnPropertySlot(exec, propertyName, slot); 0559 } 0560 0561 JSValue *MimeTypes::mimeTypeByName(ExecState *exec, const QString &name) 0562 { 0563 //qCDebug(KHTML_LOG) << "MimeTypes[" << name << "]"; 0564 QList<const MimeClassInfo *>::const_iterator it, end = mimes->constEnd(); 0565 for (it = mimes->constBegin(); it != end; ++it) { 0566 if ((*it)->type == name) { 0567 return new MimeType(exec, (*it)); 0568 } 0569 } 0570 return jsUndefined(); 0571 } 0572 0573 JSValue *MimeTypes::getValueProperty(ExecState * /*exec*/, int token) const 0574 { 0575 assert(token == MimeTypes_Length); 0576 Q_UNUSED(token); 0577 if (pluginsEnabled()) { 0578 return jsNumber(mimes->count()); 0579 } else { 0580 return jsNumber(0); 0581 } 0582 } 0583 0584 JSValue *MimeTypesFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args) 0585 { 0586 KJS_CHECK_THIS(KJS::MimeTypes, thisObj); 0587 KJS::MimeTypes *base = static_cast<KJS::MimeTypes *>(thisObj); 0588 0589 if (!base->pluginsEnabled()) { 0590 return jsUndefined(); 0591 } 0592 0593 switch (id) { 0594 case MimeTypes_Item: { 0595 bool ok; 0596 unsigned int i = args[0]->toString(exec).toArrayIndex(&ok); 0597 if (ok && i < static_cast<unsigned>(base->mimes->count())) { 0598 return new MimeType(exec, base->mimes->at(i)); 0599 } 0600 return jsUndefined(); 0601 } 0602 case MimeTypes_NamedItem: { 0603 UString s = args[0]->toString(exec); 0604 return base->mimeTypeByName(exec, s.qstring()); 0605 } 0606 default: 0607 // qCDebug(KHTML_LOG) << "WARNING: Unhandled token in MimeTypesFunc::callAsFunction : " << id; 0608 return jsUndefined(); 0609 } 0610 } 0611 0612 /************************************************************************/ 0613 const ClassInfo Plugin::info = { "Plugin", nullptr, &PluginTable, nullptr }; 0614 /* 0615 @begin PluginTable 7 0616 name Plugin_Name DontDelete|ReadOnly 0617 filename Plugin_FileName DontDelete|ReadOnly 0618 description Plugin_Description DontDelete|ReadOnly 0619 length Plugin_Length DontDelete|ReadOnly 0620 item Plugin_Item DontDelete|Function 1 0621 namedItem Plugin_NamedItem DontDelete|Function 1 0622 @end 0623 */ 0624 KJS_IMPLEMENT_PROTOFUNC(PluginFunc) 0625 0626 JSValue *Plugin::indexGetter(ExecState *exec, JSObject *, const Identifier & /*propertyName*/, const PropertySlot &slot) 0627 { 0628 Plugin *thisObj = static_cast<Plugin *>(slot.slotBase()); 0629 return new MimeType(exec, thisObj->m_info->mimes.at(slot.index())); 0630 } 0631 0632 JSValue *Plugin::nameGetter(ExecState *exec, JSObject *, const Identifier &propertyName, const PropertySlot &slot) 0633 { 0634 Plugin *thisObj = static_cast<Plugin *>(slot.slotBase()); 0635 return thisObj->mimeByName(exec, propertyName.qstring()); 0636 } 0637 0638 bool Plugin::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) 0639 { 0640 #ifdef KJS_VERBOSE 0641 qCDebug(KHTML_LOG) << "Plugin::getOwnPropertySlot " << propertyName.qstring(); 0642 #endif 0643 if (getStaticOwnPropertySlot<PluginFunc, Plugin>(&PluginTable, this, propertyName, slot)) { 0644 return true; 0645 } 0646 0647 // plugin[#] 0648 bool ok; 0649 unsigned int i = propertyName.toArrayIndex(&ok); 0650 if (ok && i < static_cast<unsigned>(m_info->mimes.count())) { 0651 slot.setCustomIndex(this, i, indexGetter); 0652 return true; 0653 } 0654 0655 // plugin["name"] 0656 QList<const MimeClassInfo *>::const_iterator it, end = mimes->constEnd(); 0657 for (it = mimes->constBegin(); it != end; ++it) { 0658 if ((*it)->type == propertyName.qstring()) { 0659 slot.setCustom(this, nameGetter); 0660 return true; 0661 } 0662 } 0663 0664 return PluginBase::getOwnPropertySlot(exec, propertyName, slot); 0665 } 0666 0667 JSValue *Plugin::mimeByName(ExecState *exec, const QString &name) const 0668 { 0669 const QList<const MimeClassInfo *> &mimes = m_info->mimes; 0670 QList<const MimeClassInfo *>::const_iterator it, end = mimes.end(); 0671 for (it = mimes.begin(); it != end; ++it) { 0672 if ((*it)->type == name) { 0673 return new MimeType(exec, (*it)); 0674 } 0675 } 0676 return jsUndefined(); 0677 } 0678 0679 JSValue *Plugin::getValueProperty(ExecState * /*exec*/, int token) const 0680 { 0681 switch (token) { 0682 case Plugin_Name: 0683 return jsString(UString(m_info->name)); 0684 case Plugin_FileName: 0685 return jsString(UString(m_info->file)); 0686 case Plugin_Description: 0687 return jsString(UString(m_info->desc)); 0688 case Plugin_Length: 0689 return jsNumber(m_info->mimes.count()); 0690 default: 0691 // qCDebug(KHTML_LOG) << "WARNING: Unhandled token in Plugin::getValueProperty : " << token; 0692 return jsUndefined(); 0693 } 0694 } 0695 0696 JSValue *PluginFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args) 0697 { 0698 KJS_CHECK_THIS(KJS::Plugin, thisObj); 0699 KJS::Plugin *plugin = static_cast<KJS::Plugin *>(thisObj); 0700 switch (id) { 0701 case Plugin_Item: { 0702 bool ok; 0703 unsigned int i = args[0]->toString(exec).toArrayIndex(&ok); 0704 if (ok && i < static_cast<unsigned>(plugin->pluginInfo()->mimes.count())) { 0705 return new MimeType(exec, plugin->pluginInfo()->mimes.at(i)); 0706 } 0707 return jsUndefined(); 0708 } 0709 case Plugin_NamedItem: { 0710 UString s = args[0]->toString(exec); 0711 return plugin->mimeByName(exec, s.qstring()); 0712 } 0713 default: 0714 // qCDebug(KHTML_LOG) << "WARNING: Unhandled token in PluginFunc::callAsFunction : " << id; 0715 return jsUndefined(); 0716 } 0717 } 0718 0719 /*****************************************************************************/ 0720 0721 const ClassInfo MimeType::info = { "MimeType", nullptr, &MimeTypeTable, nullptr }; 0722 /* 0723 @begin MimeTypeTable 4 0724 description MimeType_Description DontDelete|ReadOnly 0725 enabledPlugin MimeType_EnabledPlugin DontDelete|ReadOnly 0726 suffixes MimeType_Suffixes DontDelete|ReadOnly 0727 type MimeType_Type DontDelete|ReadOnly 0728 @end 0729 */ 0730 0731 bool MimeType::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) 0732 { 0733 #ifdef KJS_VERBOSE 0734 qCDebug(KHTML_LOG) << "MimeType::get " << propertyName.qstring(); 0735 #endif 0736 return getStaticValueSlot<MimeType, JSObject>(exec, &MimeTypeTable, this, propertyName, slot); 0737 } 0738 0739 JSValue *MimeType::getValueProperty(ExecState *exec, int token) const 0740 { 0741 switch (token) { 0742 case MimeType_Type: 0743 return jsString(UString(m_info->type)); 0744 case MimeType_Suffixes: 0745 return jsString(UString(m_info->suffixes)); 0746 case MimeType_Description: 0747 return jsString(UString(m_info->desc)); 0748 case MimeType_EnabledPlugin: 0749 return new Plugin(exec, m_info->plugin); 0750 default: 0751 // qCDebug(KHTML_LOG) << "WARNING: Unhandled token in MimeType::getValueProperty : " << token; 0752 return jsUndefined(); 0753 } 0754 } 0755 0756 JSValue *NavigatorFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &) 0757 { 0758 KJS_CHECK_THIS(KJS::Navigator, thisObj); 0759 Navigator *nav = static_cast<Navigator *>(thisObj); 0760 // javaEnabled() 0761 return jsBoolean(nav->part()->javaEnabled()); 0762 }