00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <klocale.h>
00025
00026 #include <kstandarddirs.h>
00027 #include <kconfig.h>
00028 #include <kdebug.h>
00029
00030 #include <kio/kprotocolmanager.h>
00031 #include <kio/kmimetype.h>
00032 #include <kio/kservice.h>
00033 #include <kio/ktrader.h>
00034 #include "kjs_navigator.h"
00035 #include "kjs/lookup.h"
00036 #include "kjs_binding.h"
00037 #include "khtml_part.h"
00038 #include <sys/utsname.h>
00039 #include "kjs_navigator.lut.h"
00040
00041 using namespace KJS;
00042
00043 namespace KJS {
00044
00045
00046
00047 class PluginBase : public ObjectImp {
00048 public:
00049 PluginBase(ExecState *exec);
00050 virtual ~PluginBase();
00051
00052 struct MimeClassInfo;
00053 struct PluginInfo;
00054
00055 struct MimeClassInfo {
00056 QString type;
00057 QString desc;
00058 QString suffixes;
00059 PluginInfo *plugin;
00060 };
00061
00062 struct PluginInfo {
00063 QString name;
00064 QString file;
00065 QString desc;
00066 QPtrList<MimeClassInfo> mimes;
00067 };
00068
00069 static QPtrList<PluginInfo> *plugins;
00070 static QPtrList<MimeClassInfo> *mimes;
00071
00072 private:
00073 static int m_refCount;
00074 };
00075
00076
00077 class Plugins : public PluginBase {
00078 public:
00079 Plugins(ExecState *exec) : PluginBase(exec) {};
00080 virtual Value get(ExecState *exec, const Identifier &propertyName) const;
00081 Value getValueProperty(ExecState *exec, int token) const;
00082 virtual const ClassInfo* classInfo() const { return &info; }
00083 static const ClassInfo info;
00084 Value pluginByName( ExecState* exec, const QString& name ) const;
00085 };
00086
00087
00088 class MimeTypes : public PluginBase {
00089 public:
00090 MimeTypes(ExecState *exec) : PluginBase(exec) { };
00091 virtual Value get(ExecState *exec, const Identifier &propertyName) const;
00092 virtual const ClassInfo* classInfo() const { return &info; }
00093 static const ClassInfo info;
00094 Value getValueProperty(ExecState *exec, int token) const;
00095 Value mimeTypeByName( ExecState* exec, const QString& name ) const;
00096 };
00097
00098
00099 class Plugin : public PluginBase {
00100 public:
00101 Plugin( ExecState *exec, PluginBase::PluginInfo *info )
00102 : PluginBase( exec )
00103 { m_info = info; };
00104 virtual Value get(ExecState *exec, const Identifier &propertyName) const;
00105 virtual const ClassInfo* classInfo() const { return &info; }
00106 static const ClassInfo info;
00107 Value mimeByName(ExecState* exec, const QString& name ) const;
00108 Value getValueProperty(ExecState *exec, int token) const;
00109 PluginBase::PluginInfo *pluginInfo() const { return m_info; }
00110 private:
00111 PluginBase::PluginInfo *m_info;
00112 };
00113
00114
00115 class MimeType : public PluginBase {
00116 public:
00117 MimeType( ExecState *exec, PluginBase::MimeClassInfo *info )
00118 : PluginBase( exec )
00119 { m_info = info; };
00120 virtual Value get(ExecState *exec, const Identifier &propertyName) const;
00121 virtual const ClassInfo* classInfo() const { return &info; }
00122 static const ClassInfo info;
00123 Value getValueProperty(ExecState *exec, int token) const;
00124 private:
00125 PluginBase::MimeClassInfo *m_info;
00126 };
00127
00128 }
00129
00130
00131 QPtrList<PluginBase::PluginInfo> *KJS::PluginBase::plugins = 0;
00132 QPtrList<PluginBase::MimeClassInfo> *KJS::PluginBase::mimes = 0;
00133 int KJS::PluginBase::m_refCount = 0;
00134
00135 const ClassInfo Navigator::info = { "Navigator", 0, &NavigatorTable, 0 };
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 IMPLEMENT_PROTOFUNC_DOM(NavigatorFunc)
00157
00158 Navigator::Navigator(ExecState *exec, KHTMLPart *p)
00159 : ObjectImp(exec->interpreter()->builtinObjectPrototype()), m_part(p) { }
00160
00161 Value Navigator::get(ExecState *exec, const Identifier &propertyName) const
00162 {
00163 #ifdef KJS_VERBOSE
00164 kdDebug(6070) << "Navigator::get " << propertyName.ascii() << endl;
00165 #endif
00166 return lookupGet<NavigatorFunc,Navigator,ObjectImp>(exec,propertyName,&NavigatorTable,this);
00167 }
00168
00169 Value Navigator::getValueProperty(ExecState *exec, int token) const
00170 {
00171 KURL url = m_part->url();
00172 QString userAgent = url.host();
00173 if (userAgent.isEmpty())
00174 userAgent = "localhost";
00175 userAgent = KProtocolManager::userAgentForHost(userAgent);
00176 switch (token) {
00177 case AppCodeName:
00178 return String("Mozilla");
00179 case AppName:
00180
00181 if (userAgent.find(QString::fromLatin1("Mozilla")) >= 0 &&
00182 userAgent.find(QString::fromLatin1("compatible")) == -1)
00183 {
00184
00185 return String("Netscape");
00186 }
00187 if (userAgent.find(QString::fromLatin1("Microsoft")) >= 0 ||
00188 userAgent.find(QString::fromLatin1("MSIE")) >= 0)
00189 {
00190
00191 return String("Microsoft Internet Explorer");
00192 }
00193
00194 return String("Konqueror");
00195 case AppVersion:
00196
00197 return String(userAgent.mid(userAgent.find('/') + 1));
00198 case Product:
00199
00200 if (userAgent.find(QString::fromLatin1("Mozilla")) >= 0 &&
00201 userAgent.find(QString::fromLatin1("compatible")) == -1)
00202 {
00203 return String("Gecko");
00204 }
00205
00206 if (userAgent.find(QString::fromLatin1("Microsoft")) >= 0 ||
00207 userAgent.find(QString::fromLatin1("MSIE")) >= 0)
00208 {
00209 return Undefined();
00210 }
00211
00212 return String("Konqueror/khtml");
00213 case ProductSub:
00214 {
00215 int ix = userAgent.find("Gecko");
00216 if (ix >= 0 && userAgent.length() >= (uint)ix+14 && userAgent.unicode()[ix+5] == QChar('/') &&
00217 userAgent.find(QRegExp("\\d{8}"), ix+6) == ix+6)
00218 {
00219
00220 return String(userAgent.mid(ix+6, 8));
00221 }
00222 else if (ix >= 0)
00223 {
00224 return String("20040107");
00225 }
00226 }
00227 return Undefined();
00228 case Vendor:
00229 return String("KDE");
00230 case BrowserLanguage:
00231 case Language:
00232 case UserLanguage:
00233 return String(KGlobal::locale()->language());
00234 case UserAgent:
00235 return String(userAgent);
00236 case Platform:
00237
00238 if ( (userAgent.find(QString::fromLatin1("Win"),0,false)>=0) )
00239 return String(QString::fromLatin1("Win32"));
00240 else if ( (userAgent.find(QString::fromLatin1("Macintosh"),0,false)>=0) ||
00241 (userAgent.find(QString::fromLatin1("Mac_PowerPC"),0,false)>=0) )
00242 return String(QString::fromLatin1("MacPPC"));
00243 else
00244 {
00245 struct utsname name;
00246 int ret = uname(&name);
00247 if ( ret >= 0 )
00248 return String(QString::fromLatin1("%1 %1 X11").arg(name.sysname).arg(name.machine));
00249 else
00250 return String(QString::fromLatin1("Unix X11"));
00251 }
00252 case CpuClass:
00253 {
00254 struct utsname name;
00255 int ret = uname(&name);
00256 if ( ret >= 0 )
00257 return String(name.machine);
00258 else
00259 return String("x86");
00260 }
00261 case _Plugins:
00262 return Value(new Plugins(exec));
00263 case _MimeTypes:
00264 return Value(new MimeTypes(exec));
00265 case CookieEnabled:
00266 return Boolean(true);
00267 default:
00268 kdDebug(6070) << "WARNING: Unhandled token in DOMEvent::getValueProperty : " << token << endl;
00269 return Value();
00270 }
00271 }
00272
00273
00274
00275 PluginBase::PluginBase(ExecState *exec)
00276 : ObjectImp(exec->interpreter()->builtinObjectPrototype() )
00277 {
00278 if ( !plugins ) {
00279 plugins = new QPtrList<PluginInfo>;
00280 mimes = new QPtrList<MimeClassInfo>;
00281 plugins->setAutoDelete( true );
00282 mimes->setAutoDelete( true );
00283
00284
00285 KConfig kc("konquerorrc", true);
00286 if (!KConfigGroup(&kc, "Java/JavaScript Settings").readBoolEntry("EnablePlugins", true))
00287 return;
00288
00289
00290 KTrader::OfferList offers = KTrader::self()->query("Browser/View");
00291 KTrader::OfferList::iterator it;
00292 for ( it = offers.begin(); it != offers.end(); ++it ) {
00293
00294 QVariant pluginsinfo = (**it).property( "X-KDE-BrowserView-PluginsInfo" );
00295 if ( !pluginsinfo.isValid() ) {
00296
00297 if ((**it).library() == QString("libnsplugin"))
00298 pluginsinfo = QVariant("nsplugins/pluginsinfo");
00299 else
00300
00301 continue;
00302 }
00303
00304 KConfig kc( locate ("data", pluginsinfo.toString()) );
00305 unsigned num = (unsigned int) kc.readNumEntry("number");
00306 for ( unsigned n = 0; n < num; n++ ) {
00307 kc.setGroup( QString::number(n) );
00308 PluginInfo *plugin = new PluginInfo;
00309
00310 plugin->name = kc.readEntry("name");
00311 plugin->file = kc.readPathEntry("file");
00312 plugin->desc = kc.readEntry("description");
00313
00314 plugins->append( plugin );
00315
00316
00317 QStringList types = QStringList::split( ';', kc.readEntry("mime") );
00318 QStringList::Iterator type;
00319 for ( type=types.begin(); type!=types.end(); ++type ) {
00320
00321
00322 QStringList tokens = QStringList::split(':', *type, true);
00323 if ( tokens.count() < 3 )
00324 continue;
00325
00326 MimeClassInfo *mime = new MimeClassInfo;
00327 QStringList::Iterator token = tokens.begin();
00328 mime->type = (*token).lower();
00329
00330 ++token;
00331
00332 mime->suffixes = *token;
00333 ++token;
00334
00335 mime->desc = *token;
00336 ++token;
00337
00338 mime->plugin = plugin;
00339
00340 mimes->append( mime );
00341 plugin->mimes.append( mime );
00342
00343 }
00344 }
00345 }
00346 }
00347
00348 m_refCount++;
00349 }
00350
00351 PluginBase::~PluginBase()
00352 {
00353 m_refCount--;
00354 if ( m_refCount==0 ) {
00355 delete plugins;
00356 delete mimes;
00357 plugins = 0;
00358 mimes = 0;
00359 }
00360 }
00361
00362
00363
00364
00365 const ClassInfo Plugins::info = { "PluginArray", 0, &PluginsTable, 0 };
00366
00367
00368
00369
00370
00371
00372
00373
00374 IMPLEMENT_PROTOFUNC_DOM(PluginsFunc)
00375
00376 Value Plugins::get(ExecState *exec, const Identifier &propertyName) const
00377 {
00378 #ifdef KJS_VERBOSE
00379 kdDebug(6070) << "Plugins::get " << propertyName.qstring() << endl;
00380 #endif
00381 if ( propertyName == lengthPropertyName )
00382 return Number(plugins->count());
00383
00384
00385 bool ok;
00386 unsigned int i = propertyName.toULong(&ok);
00387 if( ok && i<plugins->count() )
00388 return Value( new Plugin( exec, plugins->at(i) ) );
00389
00390
00391 Value val = pluginByName( exec, propertyName.qstring() );
00392 if (!val.isA(UndefinedType))
00393 return val;
00394
00395 return lookupGet<PluginsFunc,Plugins,ObjectImp>(exec,propertyName,&PluginsTable,this);
00396 }
00397
00398 Value Plugins::pluginByName( ExecState* exec, const QString& name ) const
00399 {
00400 for ( PluginInfo *pl = plugins->first(); pl!=0; pl = plugins->next() ) {
00401 if ( pl->name == name )
00402 return Value( new Plugin( exec, pl ) );
00403 }
00404 return Undefined();
00405 }
00406
00407 Value Plugins::getValueProperty(ExecState* , int token) const
00408 {
00409 kdDebug(6070) << "WARNING: Unhandled token in Plugins::getValueProperty : " << token << endl;
00410 return Undefined();
00411 }
00412
00413 Value PluginsFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
00414 {
00415 KJS_CHECK_THIS( KJS::Plugins, thisObj );
00416 KJS::Plugins* base = static_cast<KJS::Plugins *>(thisObj.imp());
00417 switch( id ) {
00418 case Plugins_Refresh:
00419 return Undefined();
00420 case Plugins_Item:
00421 {
00422 bool ok;
00423 unsigned int i = args[0].toString(exec).toArrayIndex(&ok);
00424 if( ok && i<base->plugins->count() )
00425 return Value( new Plugin( exec, base->plugins->at(i) ) );
00426 return Undefined();
00427 }
00428 case Plugins_NamedItem:
00429 {
00430 UString s = args[0].toString(exec);
00431 return base->pluginByName( exec, s.qstring() );
00432 }
00433 default:
00434 kdDebug(6070) << "WARNING: Unhandled token in PluginsFunc::tryCall : " << id << endl;
00435 return Undefined();
00436 }
00437 }
00438
00439
00440
00441 const ClassInfo MimeTypes::info = { "MimeTypeArray", 0, &MimeTypesTable, 0 };
00442
00443
00444
00445
00446
00447
00448
00449 IMPLEMENT_PROTOFUNC_DOM(MimeTypesFunc)
00450
00451 Value MimeTypes::get(ExecState *exec, const Identifier &propertyName) const
00452 {
00453 #ifdef KJS_VERBOSE
00454 kdDebug(6070) << "MimeTypes::get " << propertyName.qstring() << endl;
00455 #endif
00456 if( propertyName==lengthPropertyName )
00457 return Number( mimes->count() );
00458
00459
00460 bool ok;
00461 unsigned int i = propertyName.toULong(&ok);
00462 if( ok && i<mimes->count() )
00463 return Value( new MimeType( exec, mimes->at(i) ) );
00464
00465
00466 Value val = mimeTypeByName( exec, propertyName.qstring() );
00467 if (!val.isA(UndefinedType))
00468 return val;
00469
00470 return lookupGet<MimeTypesFunc,MimeTypes,ObjectImp>(exec,propertyName,&MimeTypesTable,this);
00471 }
00472
00473 Value MimeTypes::mimeTypeByName( ExecState* exec, const QString& name ) const
00474 {
00475
00476 for ( MimeClassInfo *m = mimes->first(); m!=0; m = mimes->next() ) {
00477 if ( m->type == name )
00478 return Value( new MimeType( exec, m ) );
00479 }
00480 return Undefined();
00481 }
00482
00483 Value MimeTypes::getValueProperty(ExecState* , int token) const
00484 {
00485 kdDebug(6070) << "WARNING: Unhandled token in MimeTypes::getValueProperty : " << token << endl;
00486 return Undefined();
00487 }
00488
00489 Value MimeTypesFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
00490 {
00491 KJS_CHECK_THIS( KJS::MimeTypes, thisObj );
00492 KJS::MimeTypes* base = static_cast<KJS::MimeTypes *>(thisObj.imp());
00493 switch( id ) {
00494 case MimeTypes_Item:
00495 {
00496 bool ok;
00497 unsigned int i = args[0].toString(exec).toArrayIndex(&ok);
00498 if( ok && i<base->mimes->count() )
00499 return Value( new MimeType( exec, base->mimes->at(i) ) );
00500 return Undefined();
00501 }
00502 case MimeTypes_NamedItem:
00503 {
00504 UString s = args[0].toString(exec);
00505 return base->mimeTypeByName( exec, s.qstring() );
00506 }
00507 default:
00508 kdDebug(6070) << "WARNING: Unhandled token in MimeTypesFunc::tryCall : " << id << endl;
00509 return Undefined();
00510 }
00511 }
00512
00513
00514 const ClassInfo Plugin::info = { "Plugin", 0, &PluginTable, 0 };
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525 IMPLEMENT_PROTOFUNC_DOM(PluginFunc)
00526
00527 Value Plugin::get(ExecState *exec, const Identifier &propertyName) const
00528 {
00529 #ifdef KJS_VERBOSE
00530 kdDebug(6070) << "Plugin::get " << propertyName.qstring() << endl;
00531 #endif
00532 if ( propertyName == lengthPropertyName )
00533 return Number( m_info->mimes.count() );
00534
00535
00536 bool ok;
00537 unsigned int i = propertyName.toULong(&ok);
00538
00539 if( ok && i<m_info->mimes.count() )
00540 {
00541
00542 return Value(new MimeType(exec, m_info->mimes.at(i)));
00543 }
00544
00545
00546 Value val = mimeByName( exec, propertyName.qstring() );
00547 if (!val.isA(UndefinedType))
00548 return val;
00549
00550 return lookupGet<PluginFunc,Plugin,ObjectImp>(exec, propertyName, &PluginTable, this );
00551 }
00552
00553 Value Plugin::mimeByName(ExecState* exec, const QString& name) const
00554 {
00555 for ( PluginBase::MimeClassInfo *m = m_info->mimes.first();
00556 m != 0; m = m_info->mimes.next() ) {
00557 if ( m->type == name )
00558 return Value(new MimeType(exec, m));
00559 }
00560 return Undefined();
00561 }
00562
00563 Value Plugin::getValueProperty(ExecState* , int token) const
00564 {
00565 switch( token ) {
00566 case Plugin_Name:
00567 return String( m_info->name );
00568 case Plugin_FileName:
00569 return String( m_info->file );
00570 case Plugin_Description:
00571 return String( m_info->desc );
00572 default:
00573 kdDebug(6070) << "WARNING: Unhandled token in Plugin::getValueProperty : " << token << endl;
00574 return Undefined();
00575 }
00576 }
00577
00578 Value PluginFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
00579 {
00580 KJS_CHECK_THIS( KJS::Plugin, thisObj );
00581 KJS::Plugin* plugin = static_cast<KJS::Plugin *>(thisObj.imp());
00582 switch( id ) {
00583 case Plugin_Item:
00584 {
00585 bool ok;
00586 unsigned int i = args[0].toString(exec).toArrayIndex(&ok);
00587 if( ok && i< plugin->pluginInfo()->mimes.count() )
00588 return Value( new MimeType( exec, plugin->pluginInfo()->mimes.at(i) ) );
00589 return Undefined();
00590 }
00591 case Plugin_NamedItem:
00592 {
00593 UString s = args[0].toString(exec);
00594 return plugin->mimeByName( exec, s.qstring() );
00595 }
00596 default:
00597 kdDebug(6070) << "WARNING: Unhandled token in PluginFunc::tryCall : " << id << endl;
00598 return Undefined();
00599 }
00600 }
00601
00602
00603
00604 const ClassInfo MimeType::info = { "MimeType", 0, &MimeTypesTable, 0 };
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614 Value MimeType::get(ExecState *exec, const Identifier &propertyName) const
00615 {
00616 #ifdef KJS_VERBOSE
00617 kdDebug(6070) << "MimeType::get " << propertyName.qstring() << endl;
00618 #endif
00619 return lookupGetValue<MimeType,ObjectImp>(exec, propertyName, &MimeTypeTable, this );
00620 }
00621
00622 Value MimeType::getValueProperty(ExecState* exec, int token) const
00623 {
00624 switch( token ) {
00625 case MimeType_Type:
00626 return String( m_info->type );
00627 case MimeType_Suffixes:
00628 return String( m_info->suffixes );
00629 case MimeType_Description:
00630 return String( m_info->desc );
00631 case MimeType_EnabledPlugin:
00632 return Value(new Plugin(exec, m_info->plugin));
00633 default:
00634 kdDebug(6070) << "WARNING: Unhandled token in MimeType::getValueProperty : " << token << endl;
00635 return Undefined();
00636 }
00637 }
00638
00639
00640 Value NavigatorFunc::tryCall(ExecState *exec, Object &thisObj, const List &)
00641 {
00642 KJS_CHECK_THIS( KJS::Navigator, thisObj );
00643 Navigator *nav = static_cast<Navigator *>(thisObj.imp());
00644
00645 return Boolean(nav->part()->javaEnabled());
00646 }