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 = KProtocolManager::userAgentForHost(url.host());
00173 switch (token) {
00174 case AppCodeName:
00175 return String("Mozilla");
00176 case AppName:
00177
00178 if (userAgent.find(QString::fromLatin1("Mozilla")) >= 0 &&
00179 userAgent.find(QString::fromLatin1("compatible")) == -1)
00180 {
00181
00182 return String("Netscape");
00183 }
00184 if (userAgent.find(QString::fromLatin1("Microsoft")) >= 0 ||
00185 userAgent.find(QString::fromLatin1("MSIE")) >= 0)
00186 {
00187
00188 return String("Microsoft Internet Explorer");
00189 }
00190
00191 return String("Konqueror");
00192 case AppVersion:
00193
00194 return String(userAgent.mid(userAgent.find('/') + 1));
00195 case Product:
00196 return String("Konqueror/khtml");
00197 case ProductSub:
00198 {
00199 int ix = userAgent.find("Gecko");
00200 if (ix >= 0 && userAgent.length() >= (uint)ix+14 && userAgent.at(ix+5) == '/' &&
00201 userAgent.find(QRegExp("\\d{8}"), ix+6) == ix+6)
00202 {
00203
00204 return String(userAgent.mid(ix+6, 8));
00205 }
00206 else if (ix >= 0)
00207 {
00208 return String("20040107");
00209 }
00210 }
00211 return Undefined();
00212 case Vendor:
00213 return String("KDE");
00214 case BrowserLanguage:
00215 case Language:
00216 case UserLanguage:
00217 return String(KGlobal::locale()->language());
00218 case UserAgent:
00219 return String(userAgent);
00220 case Platform:
00221
00222 if ( (userAgent.find(QString::fromLatin1("Win"),0,false)>=0) )
00223 return String(QString::fromLatin1("Win32"));
00224 else if ( (userAgent.find(QString::fromLatin1("Macintosh"),0,false)>=0) ||
00225 (userAgent.find(QString::fromLatin1("Mac_PowerPC"),0,false)>=0) )
00226 return String(QString::fromLatin1("MacPPC"));
00227 else
00228 {
00229 struct utsname name;
00230 int ret = uname(&name);
00231 if ( ret >= 0 )
00232 return String(QString::fromLatin1("%1 %1 X11").arg(name.sysname).arg(name.machine));
00233 else
00234 return String(QString::fromLatin1("Unix X11"));
00235 }
00236 case CpuClass:
00237 {
00238 struct utsname name;
00239 int ret = uname(&name);
00240 if ( ret >= 0 )
00241 return String(name.machine);
00242 else
00243 return String("x86");
00244 }
00245 case _Plugins:
00246 return Value(new Plugins(exec));
00247 case _MimeTypes:
00248 return Value(new MimeTypes(exec));
00249 case CookieEnabled:
00250 return Boolean(true);
00251 default:
00252 kdDebug(6070) << "WARNING: Unhandled token in DOMEvent::getValueProperty : " << token << endl;
00253 return Value();
00254 }
00255 }
00256
00257
00258
00259 PluginBase::PluginBase(ExecState *exec)
00260 : ObjectImp(exec->interpreter()->builtinObjectPrototype() )
00261 {
00262 if ( !plugins ) {
00263 plugins = new QPtrList<PluginInfo>;
00264 mimes = new QPtrList<MimeClassInfo>;
00265 plugins->setAutoDelete( true );
00266 mimes->setAutoDelete( true );
00267
00268
00269 KConfig kc("konquerorrc", true);
00270 if (!KConfigGroup(&kc, "Java/JavaScript Settings").readBoolEntry("EnablePlugins", true))
00271 return;
00272
00273
00274 KTrader::OfferList offers = KTrader::self()->query("Browser/View");
00275 KTrader::OfferList::iterator it;
00276 for ( it = offers.begin(); it != offers.end(); ++it ) {
00277
00278 QVariant pluginsinfo = (**it).property( "X-KDE-BrowserView-PluginsInfo" );
00279 if ( !pluginsinfo.isValid() ) {
00280
00281 if ((**it).library() == QString("libnsplugin"))
00282 pluginsinfo = QVariant("nsplugins/pluginsinfo");
00283 else
00284
00285 continue;
00286 }
00287
00288 KConfig kc( locate ("data", pluginsinfo.toString()) );
00289 unsigned num = (unsigned int) kc.readNumEntry("number");
00290 for ( unsigned n = 0; n < num; n++ ) {
00291 kc.setGroup( QString::number(n) );
00292 PluginInfo *plugin = new PluginInfo;
00293
00294 plugin->name = kc.readEntry("name");
00295 plugin->file = kc.readPathEntry("file");
00296 plugin->desc = kc.readEntry("description");
00297
00298 plugins->append( plugin );
00299
00300
00301 QStringList types = QStringList::split( ';', kc.readEntry("mime") );
00302 QStringList::Iterator type;
00303 for ( type=types.begin(); type!=types.end(); ++type ) {
00304
00305
00306 QStringList tokens = QStringList::split(':', *type, true);
00307 if ( tokens.count() < 3 )
00308 continue;
00309
00310 MimeClassInfo *mime = new MimeClassInfo;
00311 QStringList::Iterator token = tokens.begin();
00312 mime->type = (*token).lower();
00313
00314 ++token;
00315
00316 mime->suffixes = *token;
00317 ++token;
00318
00319 mime->desc = *token;
00320 ++token;
00321
00322 mime->plugin = plugin;
00323
00324 mimes->append( mime );
00325 plugin->mimes.append( mime );
00326
00327 }
00328 }
00329 }
00330 }
00331
00332 m_refCount++;
00333 }
00334
00335 PluginBase::~PluginBase()
00336 {
00337 m_refCount--;
00338 if ( m_refCount==0 ) {
00339 delete plugins;
00340 delete mimes;
00341 plugins = 0;
00342 mimes = 0;
00343 }
00344 }
00345
00346
00347
00348
00349 const ClassInfo Plugins::info = { "PluginArray", 0, &PluginsTable, 0 };
00350
00351
00352
00353
00354
00355
00356
00357
00358 IMPLEMENT_PROTOFUNC_DOM(PluginsFunc)
00359
00360 Value Plugins::get(ExecState *exec, const Identifier &propertyName) const
00361 {
00362 #ifdef KJS_VERBOSE
00363 kdDebug(6070) << "Plugins::get " << propertyName.qstring() << endl;
00364 #endif
00365 if ( propertyName == lengthPropertyName )
00366 return Number(plugins->count());
00367
00368
00369 bool ok;
00370 unsigned int i = propertyName.toULong(&ok);
00371 if( ok && i<plugins->count() )
00372 return Value( new Plugin( exec, plugins->at(i) ) );
00373
00374
00375 Value val = pluginByName( exec, propertyName.qstring() );
00376 if (!val.isA(UndefinedType))
00377 return val;
00378
00379 return lookupGet<PluginsFunc,Plugins,ObjectImp>(exec,propertyName,&PluginsTable,this);
00380 }
00381
00382 Value Plugins::pluginByName( ExecState* exec, const QString& name ) const
00383 {
00384 for ( PluginInfo *pl = plugins->first(); pl!=0; pl = plugins->next() ) {
00385 if ( pl->name == name )
00386 return Value( new Plugin( exec, pl ) );
00387 }
00388 return Undefined();
00389 }
00390
00391 Value Plugins::getValueProperty(ExecState* , int token) const
00392 {
00393 kdDebug(6070) << "WARNING: Unhandled token in Plugins::getValueProperty : " << token << endl;
00394 return Undefined();
00395 }
00396
00397 Value PluginsFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
00398 {
00399 KJS_CHECK_THIS( KJS::Plugins, thisObj );
00400 KJS::Plugins* base = static_cast<KJS::Plugins *>(thisObj.imp());
00401 switch( id ) {
00402 case Plugins_Refresh:
00403 return Undefined();
00404 case Plugins_Item:
00405 {
00406 bool ok;
00407 unsigned int i = args[0].toString(exec).toArrayIndex(&ok);
00408 if( ok && i<base->plugins->count() )
00409 return Value( new Plugin( exec, base->plugins->at(i) ) );
00410 return Undefined();
00411 }
00412 case Plugins_NamedItem:
00413 {
00414 UString s = args[0].toString(exec);
00415 return base->pluginByName( exec, s.qstring() );
00416 }
00417 default:
00418 kdDebug(6070) << "WARNING: Unhandled token in PluginsFunc::tryCall : " << id << endl;
00419 return Undefined();
00420 }
00421 }
00422
00423
00424
00425 const ClassInfo MimeTypes::info = { "MimeTypeArray", 0, &MimeTypesTable, 0 };
00426
00427
00428
00429
00430
00431
00432
00433 IMPLEMENT_PROTOFUNC_DOM(MimeTypesFunc)
00434
00435 Value MimeTypes::get(ExecState *exec, const Identifier &propertyName) const
00436 {
00437 #ifdef KJS_VERBOSE
00438 kdDebug(6070) << "MimeTypes::get " << propertyName.qstring() << endl;
00439 #endif
00440 if( propertyName==lengthPropertyName )
00441 return Number( mimes->count() );
00442
00443
00444 bool ok;
00445 unsigned int i = propertyName.toULong(&ok);
00446 if( ok && i<mimes->count() )
00447 return Value( new MimeType( exec, mimes->at(i) ) );
00448
00449
00450 Value val = mimeTypeByName( exec, propertyName.qstring() );
00451 if (!val.isA(UndefinedType))
00452 return val;
00453
00454 return lookupGet<MimeTypesFunc,MimeTypes,ObjectImp>(exec,propertyName,&MimeTypesTable,this);
00455 }
00456
00457 Value MimeTypes::mimeTypeByName( ExecState* exec, const QString& name ) const
00458 {
00459
00460 for ( MimeClassInfo *m = mimes->first(); m!=0; m = mimes->next() ) {
00461 if ( m->type == name )
00462 return Value( new MimeType( exec, m ) );
00463 }
00464 return Undefined();
00465 }
00466
00467 Value MimeTypes::getValueProperty(ExecState* , int token) const
00468 {
00469 kdDebug(6070) << "WARNING: Unhandled token in MimeTypes::getValueProperty : " << token << endl;
00470 return Undefined();
00471 }
00472
00473 Value MimeTypesFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
00474 {
00475 KJS_CHECK_THIS( KJS::MimeTypes, thisObj );
00476 KJS::MimeTypes* base = static_cast<KJS::MimeTypes *>(thisObj.imp());
00477 switch( id ) {
00478 case MimeTypes_Item:
00479 {
00480 bool ok;
00481 unsigned int i = args[0].toString(exec).toArrayIndex(&ok);
00482 if( ok && i<base->mimes->count() )
00483 return Value( new MimeType( exec, base->mimes->at(i) ) );
00484 return Undefined();
00485 }
00486 case MimeTypes_NamedItem:
00487 {
00488 UString s = args[0].toString(exec);
00489 return base->mimeTypeByName( exec, s.qstring() );
00490 }
00491 default:
00492 kdDebug(6070) << "WARNING: Unhandled token in MimeTypesFunc::tryCall : " << id << endl;
00493 return Undefined();
00494 }
00495 }
00496
00497
00498 const ClassInfo Plugin::info = { "Plugin", 0, &PluginTable, 0 };
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509 IMPLEMENT_PROTOFUNC_DOM(PluginFunc)
00510
00511 Value Plugin::get(ExecState *exec, const Identifier &propertyName) const
00512 {
00513 #ifdef KJS_VERBOSE
00514 kdDebug(6070) << "Plugin::get " << propertyName.qstring() << endl;
00515 #endif
00516 if ( propertyName == lengthPropertyName )
00517 return Number( m_info->mimes.count() );
00518
00519
00520 bool ok;
00521 unsigned int i = propertyName.toULong(&ok);
00522
00523 if( ok && i<m_info->mimes.count() )
00524 {
00525
00526 return Value(new MimeType(exec, m_info->mimes.at(i)));
00527 }
00528
00529
00530 Value val = mimeByName( exec, propertyName.qstring() );
00531 if (!val.isA(UndefinedType))
00532 return val;
00533
00534 return lookupGet<PluginFunc,Plugin,ObjectImp>(exec, propertyName, &PluginTable, this );
00535 }
00536
00537 Value Plugin::mimeByName(ExecState* exec, const QString& name) const
00538 {
00539 for ( PluginBase::MimeClassInfo *m = m_info->mimes.first();
00540 m != 0; m = m_info->mimes.next() ) {
00541 if ( m->type == name )
00542 return Value(new MimeType(exec, m));
00543 }
00544 return Undefined();
00545 }
00546
00547 Value Plugin::getValueProperty(ExecState* , int token) const
00548 {
00549 switch( token ) {
00550 case Plugin_Name:
00551 return String( m_info->name );
00552 case Plugin_FileName:
00553 return String( m_info->file );
00554 case Plugin_Description:
00555 return String( m_info->desc );
00556 default:
00557 kdDebug(6070) << "WARNING: Unhandled token in Plugin::getValueProperty : " << token << endl;
00558 return Undefined();
00559 }
00560 }
00561
00562 Value PluginFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
00563 {
00564 KJS_CHECK_THIS( KJS::Plugin, thisObj );
00565 KJS::Plugin* plugin = static_cast<KJS::Plugin *>(thisObj.imp());
00566 switch( id ) {
00567 case Plugin_Item:
00568 {
00569 bool ok;
00570 unsigned int i = args[0].toString(exec).toArrayIndex(&ok);
00571 if( ok && i< plugin->pluginInfo()->mimes.count() )
00572 return Value( new MimeType( exec, plugin->pluginInfo()->mimes.at(i) ) );
00573 return Undefined();
00574 }
00575 case Plugin_NamedItem:
00576 {
00577 UString s = args[0].toString(exec);
00578 return plugin->mimeByName( exec, s.qstring() );
00579 }
00580 default:
00581 kdDebug(6070) << "WARNING: Unhandled token in PluginFunc::tryCall : " << id << endl;
00582 return Undefined();
00583 }
00584 }
00585
00586
00587
00588 const ClassInfo MimeType::info = { "MimeType", 0, &MimeTypesTable, 0 };
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598 Value MimeType::get(ExecState *exec, const Identifier &propertyName) const
00599 {
00600 #ifdef KJS_VERBOSE
00601 kdDebug(6070) << "MimeType::get " << propertyName.qstring() << endl;
00602 #endif
00603 return lookupGetValue<MimeType,ObjectImp>(exec, propertyName, &MimeTypeTable, this );
00604 }
00605
00606 Value MimeType::getValueProperty(ExecState* exec, int token) const
00607 {
00608 switch( token ) {
00609 case MimeType_Type:
00610 return String( m_info->type );
00611 case MimeType_Suffixes:
00612 return String( m_info->suffixes );
00613 case MimeType_Description:
00614 return String( m_info->desc );
00615 case MimeType_EnabledPlugin:
00616 return Value(new Plugin(exec, m_info->plugin));
00617 default:
00618 kdDebug(6070) << "WARNING: Unhandled token in MimeType::getValueProperty : " << token << endl;
00619 return Undefined();
00620 }
00621 }
00622
00623
00624 Value NavigatorFunc::tryCall(ExecState *exec, Object &thisObj, const List &)
00625 {
00626 KJS_CHECK_THIS( KJS::Navigator, thisObj );
00627 Navigator *nav = static_cast<Navigator *>(thisObj.imp());
00628
00629 return Boolean(nav->part()->javaEnabled());
00630 }