home *** CD-ROM | disk | FTP | other *** search
- /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * The contents of this file are subject to the Netscape Public License
- * Version 1.0 (the "NPL"); you may not use this file except in
- * compliance with the NPL. You may obtain a copy of the NPL at
- * http://www.mozilla.org/NPL/
- *
- * Software distributed under the NPL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
- * for the specific language governing rights and limitations under the
- * NPL.
- *
- * The Initial Developer of this code under the NPL is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1998 Netscape Communications Corporation. All Rights
- * Reserved.
- */
- #include "xp_core.h"
- #include "xp_mcom.h"
- #include "hk_types.h"
- #include "jsapi.h"
- #include "prefapi.h"
- #include "ntypes.h"
- #include "structs.h"
- #include "pa_tags.h"
-
- #include "hk_private.h"
-
- #ifdef XP_MAC
- #include "hk_funcs.h"
- #endif
-
-
- static hk_FunctionRec **FunctionList = NULL;
- static int32 FunctionCount = 0;
-
- static char *hk_FunctionStrings[HK_MAX] = {
- NULL,
- "location_hook",
- "_hook",
- "document_start_hook"};
-
- static JSClass autoconf_class = {
- "HookConfig", 0,
- hk_HookObjectAddProperty, hk_HookObjectDeleteProperty,
- JS_PropertyStub, hk_HookObjectSetProperty,
- JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
- };
-
-
- /*******************************************
- * This function really bugs me! It needs to
- * be super fast since it will be called for every
- * HTML tag ever processed. This means it should be
- * self-contained, and not call off to other functions.
- * Making it do that means it can't call off into
- * hk_tag.c to get inside the PA_Tag structure in extra,
- * and thus makes me include ntypes.h, structs.h, and pa_tags.h.
- ********************************************/
- /*
- * A FAST function existence lookup, using an array set up in
- * the initialization process.
- */
- intn
- HK_IsHook(int32 hook_id, void *extra)
- {
- int32 func_id;
- hk_FunctionRec *rec_ptr;
-
- /*
- * The no hook case never exists.
- */
- if (hook_id == HK_NONE)
- {
- return 0;
- }
- /*
- * Tag hooks map to the tag types, or alternatly
- * unknown tags which are handled elsewhere.
- */
- else if (hook_id == HK_TAG)
- {
- PA_Tag *tag;
-
- tag = (PA_Tag *)extra;
- if (tag->type != P_UNKNOWN)
- {
- func_id = HK_MAX - 1 + tag->type;
- }
- /*
- * P_UNKNOWN tags must be looked up the slow
- * dynamic way.
- */
- else
- {
- return(hk_IsUnknownTagHook(extra));
- }
- }
- else
- {
- func_id = hook_id - 1;
- }
-
- /*
- * If we are outside the known funtion array, fail.
- */
- if ((func_id < 0)||(func_id >= FunctionCount))
- {
- return 0;
- }
-
- /*
- * If no function is registered, fail.
- */
- rec_ptr = FunctionList[func_id];
- if (rec_ptr == NULL)
- {
- return 0;
- }
-
- if (rec_ptr->func_exists == FALSE)
- {
- return 0;
- }
- else
- {
- return 1;
- }
- }
-
-
- /*
- * Set the existence state of a particular index in the array.
- */
- static void
- hk_set_function_existence(int32 indx, XP_Bool exists)
- {
- if ((indx < 0)||(indx >= FunctionCount))
- {
- return;
- }
-
- if (FunctionList[indx] != NULL)
- {
- FunctionList[indx]->func_exists = exists;
- }
- }
-
-
- void
- hk_SetFunctionExistence(char *func_name, XP_Bool exists)
- {
- int32 i, len;
- char *tptr;
- char *up_str;
- char *ptr1, *ptr2;
- int32 indx;
-
- /*
- * A NULL function one too short for the hook suffix
- * cannot be a hook function.
- */
- if (func_name == NULL)
- {
- return;
- }
- len = XP_STRLEN(func_name);
- if (len < XP_STRLEN("_hook"))
- {
- return;
- }
-
- /*
- * If the function has no hook suffix we just don't care.
- */
- tptr = func_name + len - XP_STRLEN("_hook");
- if (XP_STRCMP(tptr, "_hook") != 0)
- {
- return;
- }
-
-
- /*
- * Make an all upper-case copy of the prefix.
- */
- *tptr = '\0';
- up_str = XP_ALLOC(XP_STRLEN(func_name) + 1);
- /*
- * If allocation fails, restore original and return.
- */
- if (up_str == NULL)
- {
- *tptr = '_';
- return;
- }
- ptr1 = func_name;
- ptr2 = up_str;
- while (*ptr1 != '\0')
- {
- *ptr2 = (char)(XP_TO_UPPER(*ptr1));
- ptr1++;
- ptr2++;
- }
- *ptr2 = '\0';
- *tptr = '_';
-
- /*
- * Check if the prefix is a known TAG name.
- */
- indx = hk_TagStringToIndex(up_str);
- XP_FREE(up_str);
- if (indx >= 0)
- {
- indx = HK_MAX - 1 + indx;
- hk_set_function_existence(indx, exists);
- return;
- }
-
- /*
- * Special check for the TEXT_hook which is a tag hook but
- * won't be caught by the hk_TagStringToIndex test.
- */
- if (XP_STRCMP(func_name, "TEXT_hook") == 0)
- {
- indx = HK_MAX - 1 + 0;
- hk_set_function_existence(indx, exists);
- return;
- }
-
- /*
- * Finally, check the array of known tag hooks.
- */
- for (i=1; i<HK_MAX; i++)
- {
- if ((hk_FunctionStrings[i] != NULL)&&
- (XP_STRCMP(func_name, hk_FunctionStrings[i]) == 0))
- {
- indx = i - 1;
- hk_set_function_existence(indx, exists);
- return;
- }
- }
- }
-
-
- /*
- * Free all members of the function list array up to
- * the passed index.
- */
- static void
- hk_free_function_list(int32 indx)
- {
- int32 i;
-
- for (i=0; i<indx; i++)
- {
- if (FunctionList[i] != NULL)
- {
- if (FunctionList[i]->func_name != NULL)
- {
- XP_FREE(FunctionList[i]->func_name);
- FunctionList[i]->func_name = NULL;
- }
- XP_FREE(FunctionList[i]);
- FunctionList[i] = NULL;
- }
- }
- XP_FREE(FunctionList);
- FunctionList = NULL;
- FunctionCount = 0;
- }
-
-
- /*
- * Initialize the function list array to contain all the known tags
- * plus all the known special hook functions.
- */
- static intn
- hk_initialize_function_list(void)
- {
- int32 i, indx;
- int32 tag_cnt;
-
- /*
- * Subtract one from HK_MAX because it includes the unknown
- * at 0. For the tag count, unknown is -1, so we can just
- * use it as is.
- */
- tag_cnt = hk_NumKnownTags();
- FunctionCount = HK_MAX - 1 + tag_cnt;
- FunctionList = (hk_FunctionRec **)XP_ALLOC(FunctionCount *
- sizeof(hk_FunctionRec *));
- if (FunctionList == NULL)
- {
- return 0;
- }
-
- indx = 0;
- /*
- * First allocate all the known special hooks.
- */
- for (i=1; i < HK_MAX; i++)
- {
- hk_FunctionRec *rec_ptr;
-
- rec_ptr = XP_NEW(hk_FunctionRec);
- if (rec_ptr == NULL)
- {
- hk_free_function_list(indx);
- return 0;
- }
- rec_ptr->func_exists = FALSE;
- rec_ptr->func_name = hk_FunctionStrings[i];
- FunctionList[indx] = rec_ptr;
- indx++;
- }
-
- /*
- * Now do all known tags.
- */
- for (i=0; i < tag_cnt; i++)
- {
- hk_FunctionRec *rec_ptr;
-
- rec_ptr = XP_NEW(hk_FunctionRec);
- if (rec_ptr == NULL)
- {
- hk_free_function_list(indx);
- return 0;
- }
- rec_ptr->func_exists = FALSE;
- rec_ptr->func_name = hk_TagIndexToFunctionString(i);
- FunctionList[indx] = rec_ptr;
- indx++;
- }
-
- return 1;
- }
-
-
- /*
- * Initialize all the libhook stuff. SHould only be called once.
- * Usually just before reading hook.js.
- */
- intn
- HK_Init(void)
- {
- intn ret;
- JSContext *j_context;
- JSObject *j_object;
- JSObject *hook_obj;
-
- /*
- * If a hook object does not already exist, create
- * one. If you cannot create one, then return failure.
- */
- hook_obj = hk_GetHookObject();
- if (hook_obj == NULL)
- {
- if ((!PREF_GetConfigContext(&j_context))||
- (!PREF_GetGlobalConfigObject(&j_object)))
- {
- return 0;
- }
-
- hook_obj = JS_DefineObject(j_context, j_object,
- "HookConfig",
- &autoconf_class,
- NULL,
- JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT);
- }
- if (hook_obj == NULL)
- {
- return 0;
- }
-
- hk_SetHookObject(hook_obj);
-
- ret = hk_initialize_function_list();
-
- return ret;
- }
-
-
- /*
- * Get the hook know for the passed hook id.
- */
- const char *
- HK_GetFunctionName(int32 hook_id, void *extra)
- {
- if ((hook_id < 0)||(hook_id >= HK_MAX))
- {
- return NULL;
- }
-
- /*
- * Special name creation for tag hooks.
- */
- if (hook_id == HK_TAG)
- {
- const char *ret_str;
-
- ret_str = (const char *)hk_TagFunctionString(
- hk_FunctionStrings[hook_id], extra);
- return ret_str;
- }
- else
- {
- return hk_FunctionStrings[hook_id];
- }
- }
-
-