1
// -*- c-basic-offset: 2 -*-
3
* This file is part of the KDE libraries
4
* Copyright (C) 2000 Harri Porten (porten@kde.org)
5
* Copyright (c) 2000 Daniel Molkentin (molkentin@kde.org)
6
* Copyright (c) 2000 Stefan Schimanski (schimmi@kde.org)
7
* Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.
9
* This library is free software; you can redistribute it and/or
10
* modify it under the terms of the GNU Lesser General Public
11
* License as published by the Free Software Foundation; either
12
* version 2 of the License, or (at your option) any later version.
14
* This library is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17
* Lesser General Public License for more details.
19
* You should have received a copy of the GNU Lesser General Public
20
* License along with this library; if not, write to the Free Software
21
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
#include "kjs_navigator.h"
27
#include "AtomicString.h"
28
#include "CookieJar.h"
31
#include "FrameLoader.h"
34
#include "PlugInInfoStore.h"
37
#ifndef WEBCORE_NAVIGATOR_PLATFORM
38
#if PLATFORM(MAC) && PLATFORM(PPC)
39
#define WEBCORE_NAVIGATOR_PLATFORM "MacPPC"
40
#elif PLATFORM(MAC) && PLATFORM(X86)
41
#define WEBCORE_NAVIGATOR_PLATFORM "MacIntel"
42
#elif PLATFORM(WIN_OS)
43
#define WEBCORE_NAVIGATOR_PLATFORM "Win32"
45
#define WEBCORE_NAVIGATOR_PLATFORM ""
47
#endif // ifndef WEBCORE_NAVIGATOR_PLATFORM
49
#ifndef WEBCORE_NAVIGATOR_PRODUCT
50
#define WEBCORE_NAVIGATOR_PRODUCT "Gecko"
51
#endif // ifndef WEBCORE_NAVIGATOR_PRODUCT
53
#ifndef WEBCORE_NAVIGATOR_PRODUCT_SUB
54
#define WEBCORE_NAVIGATOR_PRODUCT_SUB "20030107"
55
#endif // ifndef WEBCORE_NAVIGATOR_PRODUCT_SUB
57
#ifndef WEBCORE_NAVIGATOR_VENDOR
58
#define WEBCORE_NAVIGATOR_VENDOR "Apple Computer, Inc."
59
#endif // ifndef WEBCORE_NAVIGATOR_VENDOR
61
#ifndef WEBCORE_NAVIGATOR_VENDOR_SUB
62
#define WEBCORE_NAVIGATOR_VENDOR_SUB ""
63
#endif // ifndef WEBCORE_NAVIGATOR_VENDOR_SUB
65
using namespace WebCore;
69
class PluginBase : public DOMObject {
71
PluginBase(ExecState *exec);
72
virtual ~PluginBase();
74
static void refresh(bool reload);
77
static void cachePluginDataIfNecessary();
78
static Vector<PluginInfo*> *plugins;
79
static Vector<MimeClassInfo*> *mimes;
82
static int m_plugInCacheRefCount;
86
class Plugins : public PluginBase {
88
Plugins(ExecState *exec) : PluginBase(exec) {};
89
virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
90
JSValue *getValueProperty(ExecState *, int token) const;
91
virtual const ClassInfo* classInfo() const { return &info; }
92
static const ClassInfo info;
93
enum { Length, Refresh };
95
static JSValue *indexGetter(ExecState *, JSObject *, const Identifier&, const PropertySlot&);
96
static JSValue *nameGetter(ExecState *, JSObject *, const Identifier&, const PropertySlot&);
99
class MimeTypes : public PluginBase {
101
MimeTypes(ExecState *exec) : PluginBase(exec) { };
102
virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
103
JSValue *getValueProperty(ExecState *, int token) const;
104
virtual const ClassInfo* classInfo() const { return &info; }
105
static const ClassInfo info;
108
static JSValue *indexGetter(ExecState *, JSObject *, const Identifier&, const PropertySlot&);
109
static JSValue *nameGetter(ExecState *, JSObject *, const Identifier&, const PropertySlot&);
112
class Plugin : public PluginBase {
114
Plugin(ExecState *exec, PluginInfo *info) : PluginBase(exec), m_info(info) { }
115
virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
116
JSValue *getValueProperty(ExecState *, int token) const;
117
virtual const ClassInfo* classInfo() const { return &info; }
118
static const ClassInfo info;
119
enum { Name, Filename, Description, Length };
121
static JSValue *indexGetter(ExecState *, JSObject *, const Identifier&, const PropertySlot&);
122
static JSValue *nameGetter(ExecState *, JSObject *, const Identifier&, const PropertySlot&);
127
class MimeType : public PluginBase {
129
MimeType( ExecState *exec, MimeClassInfo *info ) : PluginBase(exec), m_info(info) { }
130
virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
131
JSValue *getValueProperty(ExecState *, int token) const;
132
virtual const ClassInfo* classInfo() const { return &info; }
133
static const ClassInfo info;
134
enum { Type, Suffixes, Description, EnabledPlugin };
136
MimeClassInfo *m_info;
141
#include "kjs_navigator.lut.h"
145
const ClassInfo Plugins::info = { "PluginArray", 0, &PluginsTable, 0 };
146
const ClassInfo MimeTypes::info = { "MimeTypeArray", 0, &MimeTypesTable, 0 };
147
const ClassInfo Plugin::info = { "Plugin", 0, &PluginTable, 0 };
148
const ClassInfo MimeType::info = { "MimeType", 0, &MimeTypeTable, 0 };
150
Vector<PluginInfo*> *KJS::PluginBase::plugins = 0;
151
Vector<MimeClassInfo*> *KJS::PluginBase::mimes = 0;
152
int KJS::PluginBase::m_plugInCacheRefCount = 0;
154
const ClassInfo Navigator::info = { "Navigator", 0, &NavigatorTable, 0 };
156
@begin NavigatorTable 13
157
appCodeName Navigator::AppCodeName DontDelete|ReadOnly
158
appName Navigator::AppName DontDelete|ReadOnly
159
appVersion Navigator::AppVersion DontDelete|ReadOnly
160
language Navigator::Language DontDelete|ReadOnly
161
userAgent Navigator::UserAgent DontDelete|ReadOnly
162
platform Navigator::Platform DontDelete|ReadOnly
163
plugins Navigator::_Plugins DontDelete|ReadOnly
164
mimeTypes Navigator::_MimeTypes DontDelete|ReadOnly
165
product Navigator::Product DontDelete|ReadOnly
166
productSub Navigator::ProductSub DontDelete|ReadOnly
167
vendor Navigator::Vendor DontDelete|ReadOnly
168
vendorSub Navigator::VendorSub DontDelete|ReadOnly
169
cookieEnabled Navigator::CookieEnabled DontDelete|ReadOnly
170
javaEnabled Navigator::JavaEnabled DontDelete|Function 0
173
KJS_IMPLEMENT_PROTOTYPE_FUNCTION(NavigatorFunc)
175
Navigator::Navigator(ExecState *exec, Frame *f)
178
setPrototype(exec->lexicalInterpreter()->builtinObjectPrototype());
181
bool Navigator::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
183
return getStaticPropertySlot<NavigatorFunc, Navigator, JSObject>(exec, &NavigatorTable, this, propertyName, slot);
186
JSValue* Navigator::getValueProperty(ExecState* exec, int token) const
190
return jsString("Mozilla");
192
return jsString("Netscape");
194
// Version is everything in the user agent string past the "Mozilla/" prefix.
195
const String userAgent = m_frame->loader()->userAgent(m_frame->document() ? m_frame->document()->URL() : KURL());
196
return jsString(userAgent.substring(userAgent.find('/') + 1));
199
return jsString(WEBCORE_NAVIGATOR_PRODUCT);
201
return jsString(WEBCORE_NAVIGATOR_PRODUCT_SUB);
203
return jsString(WEBCORE_NAVIGATOR_VENDOR);
205
return jsString(WEBCORE_NAVIGATOR_VENDOR_SUB);
207
return jsString(defaultLanguage());
209
return jsString(m_frame->loader()->userAgent(m_frame->document() ? m_frame->document()->URL() : KURL()));
211
return jsString(WEBCORE_NAVIGATOR_PLATFORM);
213
return new Plugins(exec);
215
return new MimeTypes(exec);
217
return jsBoolean(cookiesEnabled());
222
/*******************************************************************/
224
void PluginBase::cachePluginDataIfNecessary()
227
plugins = new Vector<PluginInfo*>;
228
mimes = new Vector<MimeClassInfo*>;
230
// read configuration
232
unsigned pluginCount = c.pluginCount();
233
for (unsigned n = 0; n < pluginCount; n++) {
234
PluginInfo* plugin = c.createPluginInfoForPluginAtIndex(n);
238
plugins->append(plugin);
242
Vector<MimeClassInfo*>::iterator end = plugin->mimes.end();
243
for (Vector<MimeClassInfo*>::iterator itr = plugin->mimes.begin(); itr != end; itr++)
249
PluginBase::PluginBase(ExecState *exec)
251
setPrototype(exec->lexicalInterpreter()->builtinObjectPrototype());
253
cachePluginDataIfNecessary();
254
m_plugInCacheRefCount++;
257
PluginBase::~PluginBase()
259
m_plugInCacheRefCount--;
260
if (!m_plugInCacheRefCount) {
262
deleteAllValues(*plugins);
267
deleteAllValues(*mimes);
274
void PluginBase::refresh(bool reload)
277
deleteAllValues(*plugins);
282
deleteAllValues(*mimes);
287
refreshPlugins(reload);
288
cachePluginDataIfNecessary();
292
/*******************************************************************/
295
@begin PluginsTable 2
296
length Plugins::Length DontDelete|ReadOnly
297
refresh Plugins::Refresh DontDelete|Function 0
300
KJS_IMPLEMENT_PROTOTYPE_FUNCTION(PluginsFunc)
302
JSValue *Plugins::getValueProperty(ExecState *exec, int token) const
304
ASSERT(token == Length);
305
return jsNumber(plugins->size());
308
JSValue *Plugins::indexGetter(ExecState *exec, JSObject *originalObject, const Identifier& propertyName, const PropertySlot& slot)
310
return new Plugin(exec, plugins->at(slot.index()));
313
JSValue *Plugins::nameGetter(ExecState *exec, JSObject *originalObject, const Identifier& propertyName, const PropertySlot& slot)
315
AtomicString atomicPropertyName = propertyName;
316
Vector<PluginInfo*>::iterator end = plugins->end();
317
for (Vector<PluginInfo*>::iterator itr = plugins->begin(); itr != end; itr++) {
318
PluginInfo *pl = *itr;
319
if (pl->name == atomicPropertyName)
320
return new Plugin(exec, pl);
322
return jsUndefined();
325
bool Plugins::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
327
const HashEntry* entry = Lookup::findEntry(&PluginsTable, propertyName);
329
if (entry->attr & Function)
330
slot.setStaticEntry(this, entry, staticFunctionGetter<PluginsFunc>);
332
slot.setStaticEntry(this, entry, staticValueGetter<Plugins>);
337
unsigned int i = propertyName.toUInt32(&ok);
338
if (ok && i < plugins->size()) {
339
slot.setCustomIndex(this, i, indexGetter);
344
AtomicString atomicPropertyName = propertyName;
345
Vector<PluginInfo*>::iterator end = plugins->end();
346
for (Vector<PluginInfo*>::iterator itr = plugins->begin(); itr != end; itr++) {
347
if ((*itr)->name == atomicPropertyName) {
348
slot.setCustom(this, nameGetter);
354
return PluginBase::getOwnPropertySlot(exec, propertyName, slot);
357
/*******************************************************************/
360
@begin MimeTypesTable 1
361
length MimeTypes::Length DontDelete|ReadOnly
365
JSValue *MimeTypes::getValueProperty(ExecState *exec, int token) const
367
ASSERT(token == Length);
368
return jsNumber(mimes->size());
371
JSValue *MimeTypes::indexGetter(ExecState *exec, JSObject *originalObject, const Identifier& propertyName, const PropertySlot& slot)
373
return new MimeType(exec, mimes->at(slot.index()));
376
JSValue *MimeTypes::nameGetter(ExecState *exec, JSObject *originalObject, const Identifier& propertyName, const PropertySlot& slot)
378
AtomicString atomicPropertyName = propertyName;
379
Vector<MimeClassInfo*>::iterator end = mimes->end();
380
for (Vector<MimeClassInfo*>::iterator itr = mimes->begin(); itr != end; itr++) {
381
MimeClassInfo *m = (*itr);
382
if (m->type == atomicPropertyName)
383
return new MimeType(exec, m);
385
return jsUndefined();
388
bool MimeTypes::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
390
const HashEntry* entry = Lookup::findEntry(&MimeTypesTable, propertyName);
392
slot.setStaticEntry(this, entry, staticValueGetter<MimeTypes>);
397
unsigned int i = propertyName.toUInt32(&ok);
398
if (ok && i < mimes->size()) {
399
slot.setCustomIndex(this, i, indexGetter);
404
AtomicString atomicPropertyName = propertyName;
405
Vector<MimeClassInfo*>::iterator end = mimes->end();
406
for (Vector<MimeClassInfo*>::iterator itr = mimes->begin(); itr != end; itr++) {
407
if ((*itr)->type == atomicPropertyName) {
408
slot.setCustom(this, nameGetter);
414
return PluginBase::getOwnPropertySlot(exec, propertyName, slot);
418
/************************************************************************/
422
name Plugin::Name DontDelete|ReadOnly
423
filename Plugin::Filename DontDelete|ReadOnly
424
description Plugin::Description DontDelete|ReadOnly
425
length Plugin::Length DontDelete|ReadOnly
429
JSValue *Plugin::getValueProperty(ExecState *exec, int token) const
433
return jsString(m_info->name);
435
return jsString(m_info->file);
437
return jsString(m_info->desc);
439
return jsNumber(m_info->mimes.size());
442
return jsUndefined();
446
JSValue *Plugin::indexGetter(ExecState *exec, JSObject *originalObject, const Identifier& propertyName, const PropertySlot& slot)
448
Plugin *thisObj = static_cast<Plugin *>(slot.slotBase());
449
return new MimeType(exec, thisObj->m_info->mimes.at(slot.index()));
452
JSValue *Plugin::nameGetter(ExecState *exec, JSObject *originalObject, const Identifier& propertyName, const PropertySlot& slot)
454
Plugin *thisObj = static_cast<Plugin *>(slot.slotBase());
455
AtomicString atomicPropertyName = propertyName;
456
Vector<MimeClassInfo*>::iterator end = thisObj->m_info->mimes.end();
457
for (Vector<MimeClassInfo*>::iterator itr = thisObj->m_info->mimes.begin(); itr != end; itr++) {
458
MimeClassInfo *m = (*itr);
459
if (m->type == atomicPropertyName)
460
return new MimeType(exec, m);
462
return jsUndefined();
466
bool Plugin::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
468
const HashEntry* entry = Lookup::findEntry(&PluginTable, propertyName);
470
slot.setStaticEntry(this, entry, staticValueGetter<Plugin>);
475
unsigned int i = propertyName.toUInt32(&ok);
476
if (ok && i < m_info->mimes.size()) {
477
slot.setCustomIndex(this, i, indexGetter);
482
AtomicString atomicPropertyName = propertyName;
483
Vector<MimeClassInfo*>::iterator end = m_info->mimes.end();
484
for (Vector<MimeClassInfo*>::iterator itr = m_info->mimes.begin(); itr != end; itr++) {
485
if ((*itr)->type == atomicPropertyName) {
486
slot.setCustom(this, nameGetter);
492
return PluginBase::getOwnPropertySlot(exec, propertyName, slot);
495
/*****************************************************************************/
498
@begin MimeTypeTable 4
499
type MimeType::Type DontDelete|ReadOnly
500
suffixes MimeType::Suffixes DontDelete|ReadOnly
501
description MimeType::Description DontDelete|ReadOnly
502
enabledPlugin MimeType::EnabledPlugin DontDelete|ReadOnly
506
JSValue *MimeType::getValueProperty(ExecState *exec, int token) const
510
return jsString(m_info->type);
512
return jsString(m_info->suffixes);
514
return jsString(m_info->desc);
515
case EnabledPlugin: {
516
ScriptInterpreter *interpreter = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter());
517
Frame *frame = interpreter->frame();
519
Settings* settings = frame->settings();
520
if (settings && settings->arePluginsEnabled())
521
return new Plugin(exec, m_info->plugin);
523
return jsUndefined();
526
return jsUndefined();
530
bool MimeType::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
532
return getStaticValueSlot<MimeType, PluginBase>(exec, &MimeTypeTable, this, propertyName, slot);
535
JSValue *PluginsFunc::callAsFunction(ExecState *exec, JSObject *, const List &args)
537
PluginBase::refresh(args[0]->toBoolean(exec));
538
return jsUndefined();
541
JSValue *NavigatorFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &)
543
if (!thisObj->inherits(&KJS::Navigator::info))
544
return throwError(exec, TypeError);
545
Navigator *nav = static_cast<Navigator *>(thisObj);
547
Settings* settings = nav->frame() ? nav->frame()->settings() : 0;
548
return jsBoolean(settings && settings->isJavaEnabled());