예제 #1
0
void
lo_FormatJavaObject(MWContext *context, lo_DocState *state, PA_Tag *tag, LO_JavaAppStruct *java_app)
{
    PA_Block buff;

    buff = lo_FetchParamValue(context, tag, PARAM_CLASSID);
    if (buff != NULL)
    {
        char* str;
        PA_LOCK(str, char *, buff);
        if (XP_STRNCASECMP(str, "java:", 5) == 0)
            java_app->selector_type = LO_JAVA_SELECTOR_OBJECT_JAVA;
        else if (XP_STRNCASECMP(str, "javaprogram:", 12) == 0)
            java_app->selector_type = LO_JAVA_SELECTOR_OBJECT_JAVAPROGRAM;
        else if (XP_STRNCASECMP(str, "javabean:", 8) == 0)
            java_app->selector_type = LO_JAVA_SELECTOR_OBJECT_JAVABEAN;
        PA_UNLOCK(buff);
        XP_FREE(buff);
    }

    if (java_app->selector_type == LO_JAVA_SELECTOR_OBJECT_JAVAPROGRAM)
    {
        java_app->ele_attrmask |= LO_ELE_HIDDEN;
    }
    else 
    {
        /* Get the HIDDEN parameter */
        java_app->ele_attrmask = 0;
        buff = lo_FetchParamValue(context, tag, PARAM_HIDDEN);
        if (buff != NULL)
        {
            Bool hidden = TRUE;
            char* str;

            PA_LOCK(str, char *, buff);
            if (pa_TagEqual("no", str))
            {
                hidden = FALSE;
            }
            else if (pa_TagEqual("false", str))
            {
                hidden = FALSE;
            }
            else if (pa_TagEqual("off", str))
            {
                hidden = FALSE;
            }
            PA_UNLOCK(buff);
            PA_FREE(buff);

            if (hidden != FALSE)
            {
                java_app->ele_attrmask |= LO_ELE_HIDDEN;
            }
        }
    }

    /* Finish formatting the object */
    lo_FormatJavaAppInternal(context, state, tag, java_app);
}
예제 #2
0
static void
lo_ParseScriptLanguage(MWContext * context, PA_Tag * tag, int8 * type,
		       JSVersion * version)
{
    PA_Block buff;
    char * str;

    buff = lo_FetchParamValue(context, tag, PARAM_LANGUAGE);
    if (buff != NULL) {
        PA_LOCK(str, char *, buff);
        if ((XP_STRCASECMP(str, js_language_name) == 0) ||
            (XP_STRCASECMP(str, "LiveScript") == 0) ||
            (XP_STRCASECMP(str, "Mocha") == 0)) {
            *type = SCRIPT_TYPE_MOCHA;
            *version = JSVERSION_DEFAULT;
        } 
        else if (XP_STRCASECMP(str, "JavaScript1.1") == 0) {
            *type = SCRIPT_TYPE_MOCHA;
            *version = JSVERSION_1_1;
        } 
        else if (XP_STRCASECMP(str, "JavaScript1.2") == 0) {
            *type = SCRIPT_TYPE_MOCHA;
            *version = JSVERSION_1_2;
        } 
        else if (XP_STRCASECMP(str, "JavaScript1.3") == 0) {
            *type = SCRIPT_TYPE_MOCHA;
            *version = JSVERSION_1_3;
        } 

        else {
            *type = SCRIPT_TYPE_UNKNOWN;
        }
        PA_FREE(buff);
    }
}
예제 #3
0
/*
 * The beginning of a usemap MAP record.
 * Allocate the structure and initialize it.  It will be filled
 * by later AREA tags.
 */
void
lo_BeginMap(MWContext *context, lo_DocState *state, PA_Tag *tag)
{
	PA_Block buff;
	char *str;
	lo_MapRec *map;

	map = XP_NEW(lo_MapRec);
	if (map == NULL)
	{
		state->top_state->out_of_memory = TRUE;
		return;
	}

	map->name = NULL;
	map->areas = NULL;
	map->areas_last = NULL;
	map->next = NULL;

	buff = lo_FetchParamValue(context, tag, PARAM_NAME);
	if (buff != NULL)
	{
		char *name;

		PA_LOCK(str, char *, buff);
		if (str != NULL)
		{
			int32 len;

			len = lo_StripTextWhitespace(str, XP_STRLEN(str));
		}
		name = (char *)XP_ALLOC(XP_STRLEN(str) + 1);
		if (name == NULL)
		{
			map->name = NULL;
		}
		else
		{
			XP_STRCPY(name, str);
			map->name = name;
		}
		PA_UNLOCK(buff);
		PA_FREE(buff);
	}
	else
	{
		map->name = NULL;
	}

	if (map->name == NULL)
	{
		XP_DELETE(map);
		return;
	}

	state->top_state->current_map = map;
}
예제 #4
0
/* Generate mimetype string corresponding to this script language.  
   Specifically, <SCRIPT language = blah> should yield a mimetype
   of "script/blah"
 */
char * npl_Script2mimeType(MWContext *context, PA_Tag *tag)
{
	PA_Block buff;
	char * language;
	char * preface = "script/";
    uint32 prefLen = XP_STRLEN(preface);
	char * mimebuf = NULL;
	uint32 len;

	buff = lo_FetchParamValue(context, tag, PARAM_LANGUAGE);
	if (buff != NULL) {
		PA_LOCK(language, char *, buff);
		len = prefLen + XP_STRLEN(language);
		mimebuf = XP_ALLOC(len+1);
		if (mimebuf)
		{
			XP_STRCPY(mimebuf, preface);
			XP_STRCAT(mimebuf, language);
		}
		PA_FREE(buff);
	}
	return mimebuf;
}
예제 #5
0
void
lo_format_block_spacer(MWContext *context, lo_DocState *state, PA_Tag *tag, Bool relayout)
{
	Bool line_break;
	Bool floating;
	int32 baseline_inc, line_inc;
	int32 alignment;
	int16 x_offset;
	int32 y_offset;
	int32 x, y;
	int32 width, height;
	int32 doc_width;
	int32 val;
	PA_Block buff;
	char *str;
	LO_TextStruct tmp_text;
	LO_TextInfo text_info;
	LO_Element *eptr;

	x = state->x;
	y = state->y;
	width = 0;
	height = 0;
	alignment = LO_ALIGN_BASELINE;
	floating = FALSE;

	/*
	 * Check for an align parameter
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_ALIGN);
	if (buff != NULL)
	{

		PA_LOCK(str, char *, buff);
		alignment = lo_EvalAlignParam(str, &floating);
		PA_UNLOCK(buff);
		PA_FREE(buff);
	}

	doc_width = state->right_margin - state->left_margin;

	/*
	 * Get the width parameter, in absolute or percentage.
	 * If percentage, make it absolute.
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_WIDTH);
	if (buff != NULL)
	{
		Bool is_percent;

		PA_LOCK(str, char *, buff);
		val = lo_ValueOrPercent(str, &is_percent);
		if (is_percent != FALSE)
		{
			if (state->allow_percent_width == FALSE)
			{
				val = 0;
			}
			else
			{
				val = doc_width * val / 100;
				if (val < 1)
				{
					val = 1;
				}
			}
		}
		else
		{
			val = FEUNITS_X(val, context);
			if (val < 1)
			{
				val = 1;
			}
		}
		width = val;
		PA_UNLOCK(buff);
		PA_FREE(buff);
	}

	/*
	 * Get the height parameter, in absolute or percentage.
	 * If percentage, make it absolute.
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_HEIGHT);
	if (buff != NULL)
	{
		Bool is_percent;

		PA_LOCK(str, char *, buff);
		val = lo_ValueOrPercent(str, &is_percent);
		if (is_percent != FALSE)
		{
			if (state->allow_percent_height == FALSE)
			{
				val = 0;
			}
			else
			{
				val = state->win_height * val / 100;
				if (val < 1)
				{
					val = 1;
				}
			}
		}
		else
		{
			val = FEUNITS_Y(val, context);
			if (val < 1)
			{
				val = 1;
			}
		}
		height = val;
		PA_UNLOCK(buff);
		PA_FREE(buff);
	}

	/*
         * All this work is to get the text_info filled in for the current
         * font in the font stack. Yuck, there must be a better way.
         */
	memset (&tmp_text, 0, sizeof (tmp_text));
	buff = PA_ALLOC(1);
	if (buff == NULL)
	{
		state->top_state->out_of_memory = TRUE;
		return;
	}
	PA_LOCK(str, char *, buff);
	str[0] = ' ';
	PA_UNLOCK(buff);
	tmp_text.text = buff;
	tmp_text.text_len = 1;
	tmp_text.text_attr = state->font_stack->text_attr;
	FE_GetTextInfo(context, &tmp_text, &text_info);
	PA_FREE(buff);

	/*
	 * If both dimentions are bogus, no spacer.
	 * If only one dimension bogus, then make it 1.
	 */
	if ((width < 1)&&(height < 1))
	{
		return;
	}
	else if (width < 1)
	{
		width = 1;
	}
	else if (height < 1)
	{
		height = 1;
	}


	/*
	 * SEVERE FLOW BREAK!  This may be a floating image,
	 * which means at this point we go do something completely
	 * different.
	 */
	if (floating != FALSE)
	{
		if (alignment == LO_ALIGN_RIGHT)
		{
			if (state->right_margin_stack == NULL)
			{
				x = state->right_margin - width;
			}
			else
			{
				x = state->right_margin_stack->margin - width;
			}
			if (x < 0)
			{
				x = 0;
			}
		}
		else
		{
			x = state->left_margin;
		}

		y = -1;

		lo_AddMarginStack(state, x, y,
			width, height, 0, 0, 0, alignment);

		if (state->at_begin_line != FALSE)
		{
			lo_FindLineMargins(context, state, TRUE);
			state->x = state->left_margin;
		}

		return;
	}

	/*
	 * Will this spacer make the line too wide.
	 */
	if ((state->x + width) > state->right_margin)
	{
		line_break = TRUE;
	}
	else
	{
		line_break = FALSE;
	}

	/*
	 * if we are at the beginning of the line.  There is
	 * no point in breaking, we are just too wide.
	 * Also don't break in unmapped preformatted text.
	 * Also can't break inside a NOBR section.
	 */
	if ((state->at_begin_line != FALSE)||
		(state->preformatted == PRE_TEXT_YES)||
		(state->breakable == FALSE))
	{
		line_break = FALSE;
	}

	/*
	 * break on the spacer if we have
	 * a break.
	 */
	if (line_break != FALSE)
	{
		lo_SoftLineBreak(context, state, TRUE);
		x = state->x;
		y = state->y;
	}

	/*
	 * Figure out how to align this spacer.
	 * baseline_inc is how much to increase the baseline
	 * of previous element of this line.  line_inc is how
	 * much to increase the line height below the baseline.
	 */
	baseline_inc = 0;
	line_inc = 0;
	x_offset = 0;
	y_offset = 0;

	lo_CalcAlignOffsets(state, &text_info, alignment,
		width, height,
		&x_offset, &y_offset, &line_inc, &baseline_inc);

	width += x_offset;
	height += y_offset;

	/*
	 * Change the rest of the line the way lo_AppendToLineList()
	 * would if we were adding a real element.
	 */
	eptr = state->line_list;
        if (eptr != NULL)
        {
                while (eptr->lo_any.next != NULL)
                {
                        eptr->lo_any.y_offset += baseline_inc;
                        eptr = eptr->lo_any.next;
                }
                eptr->lo_any.y_offset += baseline_inc;
        }

	state->baseline += (intn) baseline_inc;
	state->line_height += (intn) (baseline_inc + line_inc);

	/*
	 * Clean up state
	 */
	state->x = state->x + width;
	state->linefeed_state = 0;
	state->at_begin_line = FALSE;
	state->trailing_space = FALSE;
	state->cur_ele_type = LO_NONE;
}
예제 #6
0
void
lo_ProcessSpacerTag(MWContext *context, lo_DocState *state, PA_Tag *tag)
{
	int32 type;
	int32 size;
	PA_Block buff;
	LO_SpacerStruct *spacer;
	
	spacer = (LO_SpacerStruct*)lo_NewElement(context, state, LO_SPACER, NULL, 0);
	XP_ASSERT(spacer);
	if (!spacer) 
	{
		state->top_state->out_of_memory = TRUE;
		return;
	}

	type = SPACE_WORD;
	buff = lo_FetchParamValue(context, tag, PARAM_TYPE);
	if (buff != NULL)
	{
		char *type_str;

		PA_LOCK(type_str, char *, buff);
		if (pa_TagEqual("line", type_str))
		{
			type = SPACE_LINE;
		}
		else if (pa_TagEqual("vert", type_str))
		{
			type = SPACE_LINE;
		}
		else if (pa_TagEqual("vertical", type_str))
		{
			type = SPACE_LINE;
		}
		else if (pa_TagEqual("block", type_str))
		{
			type = SPACE_BLOCK;
		}
		PA_UNLOCK(buff);
		PA_FREE(buff);
	}

	size = 0;
	buff = lo_FetchParamValue(context, tag, PARAM_SIZE);
	if (buff != NULL)
	{
		char *str;

		PA_LOCK(str, char *, buff);
		size = XP_ATOI(str);
		PA_UNLOCK(buff);
		PA_FREE(buff);
		if (size < 1)
		{
			size = 0;
		}
	}	

	spacer->size = size;
	spacer->type = (int8) type;
	spacer->tag = tag;

	lo_AppendSpacerElementToLineList( context, state, spacer );
	lo_LayoutSpacerElement(context, state, spacer, FALSE);

	/*
	 * Spacers of size 0 do nothing.
	 * Unless they are block spacers that use WIDTH and HEIGHT.
	 */
	/*
	if ((size == 0)&&(type != SPACE_BLOCK))
	{
		return;
	}

	if (type == SPACE_WORD)
	{
		lo_InsertWordBreak(context, state);
		size = FEUNITS_X(size, context);
		state->x += size;
	}
	else if (type == SPACE_LINE)
	{
		lo_SetSoftLineBreakState(context, state, FALSE, 1);
		size = FEUNITS_Y(size, context);
		state->y += size;
	}
	else if (type == SPACE_BLOCK)
	{
		lo_format_block_spacer(context, state, tag);
	}
	*/
}
예제 #7
0
static void lo_ParseAttributesForBlockSpacer( MWContext *context, lo_DocState *state, LO_SpacerStruct *spacer )
{
	Bool floating;
	int32 alignment;
	int32 val;
	PA_Block buff;
	PA_Tag *tag = spacer->tag;
	char *str;

	alignment = LO_ALIGN_BASELINE;
	floating = FALSE;

	/*
	 * Check for an align parameter
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_ALIGN);
	if (buff != NULL)
	{
		PA_LOCK(str, char *, buff);
		alignment = lo_EvalAlignParam(str, &floating);
		PA_UNLOCK(buff);
		PA_FREE(buff);
	}
	spacer->alignment = alignment;
	spacer->floating = floating;	

	/*
	 * Get the width parameter, in absolute or percentage.
	 * If percentage, make it absolute.
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_WIDTH);
	if (buff != NULL)
	{
		Bool is_percent;

		PA_LOCK(str, char *, buff);
		val = lo_ValueOrPercent(str, &is_percent);
		if (is_percent != FALSE)
		{
			spacer->is_percent_width = TRUE;
			spacer->width = val;			
		}
		else
		{
			spacer->is_percent_width = FALSE;
			val = FEUNITS_X(val, context);
			if (val < 1)
			{
				val = 1;
			}
			spacer->width = val;
		}		
		PA_UNLOCK(buff);
		PA_FREE(buff);
	}

	/*
	 * Get the height parameter, in absolute or percentage.
	 * If percentage, make it absolute.
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_HEIGHT);
	if (buff != NULL)
	{
		Bool is_percent;

		PA_LOCK(str, char *, buff);
		val = lo_ValueOrPercent(str, &is_percent);
		if (is_percent != FALSE)
		{
			spacer->is_percent_height = TRUE;
			spacer->height = val;
		}
		else
		{
			spacer->is_percent_height = FALSE;
			val = FEUNITS_Y(val, context);
			if (val < 1)
			{
				val = 1;
			}
			spacer->height = val;
		}
		PA_UNLOCK(buff);
		PA_FREE(buff);
	}
}
예제 #8
0
/*
 * This is an AREA tag.  Create the structure, fill it in based on the
 * attributes passed, and add it to the map record for the current
 * MAP tag.
 */
void
lo_BeginMapArea(MWContext *context, lo_DocState *state, PA_Tag *tag)
{
	PA_Block buff;
	char *str;
	lo_MapRec *map;
	lo_MapAreaRec *area;
        lo_DocLists *doc_lists;
        
        doc_lists = lo_GetCurrentDocLists(state);

	/*
	 * Get the current map, if there is none, error out.
	 */
	map = state->top_state->current_map;
	if (map == NULL)
	{
		return;
	}

	area = XP_NEW(lo_MapAreaRec);
	if (area == NULL)
	{
		state->top_state->out_of_memory = TRUE;
		return;
	}

	area->type = AREA_SHAPE_RECT;
	area->coords = NULL;
	area->coord_cnt = 0;
	area->anchor = NULL;
	area->alt = NULL;
	area->alt_len = 0;
	area->next = NULL;

	buff = lo_FetchParamValue(context, tag, PARAM_SHAPE);
	if (buff != NULL)
	{
		PA_LOCK(str, char *, buff);
		if (pa_TagEqual(S_AREA_SHAPE_RECT, str))
		{
			area->type = AREA_SHAPE_RECT;
		}
		else if (pa_TagEqual(S_AREA_SHAPE_CIRCLE, str))
		{
			area->type = AREA_SHAPE_CIRCLE;
		}
		else if (pa_TagEqual(S_AREA_SHAPE_POLY, str))
		{
			area->type = AREA_SHAPE_POLY;
		}
		else if (pa_TagEqual(S_AREA_SHAPE_POLYGON, str))
		{
			area->type = AREA_SHAPE_POLY;
		}
		else if (pa_TagEqual(S_AREA_SHAPE_DEFAULT, str))
		{
			area->type = AREA_SHAPE_DEFAULT;
		}
		else
		{
			area->type = AREA_SHAPE_UNKNOWN;
		}
		PA_UNLOCK(buff);
		PA_FREE(buff);
	}

	/*
	 * Get the alt parameter, and store the resulting
	 * text, and its length.
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_ALT);
	if (buff != NULL)
	{
		PA_LOCK(str, char *, buff);
		area->alt_len = XP_STRLEN(str);
		area->alt_len = (int16)lo_StripTextNewlines(str,
						(int32)area->alt_len);
		PA_UNLOCK(buff);
	}
	area->alt = buff;

	/*
	 * Parse the comma separated coordinate list into an
	 * array of integers.
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_COORDS);
	if (buff != NULL)
	{
		int32 cnt;
		Bool must_be_odd;

		must_be_odd = FALSE;
		if (area->type == AREA_SHAPE_POLY)
		{
			must_be_odd = TRUE;
		}
		PA_LOCK(str, char *, buff);
		area->coords = lo_parse_coord_list(str, &cnt, must_be_odd);
		if (area->coords != NULL)
		{
			area->coord_cnt = cnt;
		}
		PA_UNLOCK(buff);
		PA_FREE(buff);
	}

	/*
	 * Get the HREF, and if one exists, get the TARGET to go along
	 * with it.
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_HREF);
	if (buff != NULL)
	{
		char *target;
		PA_Block targ_buff;
		PA_Block href_buff;
		LO_AnchorData *anchor;

		anchor = NULL;
		PA_LOCK(str, char *, buff);
		if (str != NULL)
		{
			int32 len;

			len = lo_StripTextWhitespace(str, XP_STRLEN(str));
		}
		str = NET_MakeAbsoluteURL(state->top_state->base_url, str);
		if (str == NULL)
		{
			href_buff = NULL;
		}
		else
		{
			href_buff = PA_ALLOC(XP_STRLEN(str) + 1);
			if (href_buff != NULL)
			{
				char *full_url;

				PA_LOCK(full_url, char *, href_buff);
				XP_STRCPY(full_url, str);
				PA_UNLOCK(href_buff);
			}
			else
			{
				state->top_state->out_of_memory = TRUE;
			}
			XP_FREE(str);
		}
		PA_UNLOCK(buff);
		PA_FREE(buff);

		if (href_buff != NULL)
		{
			targ_buff = lo_FetchParamValue(context, tag, PARAM_TARGET);
			if (targ_buff != NULL)
			{
				int32 len;

				PA_LOCK(target, char *, targ_buff);
				len = lo_StripTextWhitespace(target,
						XP_STRLEN(target));
				if ((*target == '\0')||
				    (lo_IsValidTarget(target) == FALSE))
				{
					PA_UNLOCK(targ_buff);
					PA_FREE(targ_buff);
					targ_buff = NULL;
				}
				else
				{
					PA_UNLOCK(targ_buff);
				}
			}

			/*
			 * If there was no target use the default one.
			 * (default provided by BASE tag)
			 */
			if ((targ_buff == NULL)&&
			    (state->top_state->base_target != NULL))
			{
				targ_buff = PA_ALLOC(XP_STRLEN(
					state->top_state->base_target) + 1);
				if (targ_buff != NULL)
				{
					char *targ;

					PA_LOCK(targ, char *, targ_buff);
					XP_STRCPY(targ,
						state->top_state->base_target);
					PA_UNLOCK(targ_buff);
				}
				else
				{
					state->top_state->out_of_memory = TRUE;
				}
			}

			anchor = lo_NewAnchor(state, href_buff, targ_buff);
			if (anchor == NULL)
			{
				PA_FREE(href_buff);
				if (targ_buff != NULL)
				{
					PA_FREE(targ_buff);
				}
			}
			/*
			 * If the AREA tag has an ALT attribute,
			 * stick that text into the anchor data.
			 */
			else if (area->alt != NULL)
			{
				PA_Block alt_buff;
				char *alt_text;

				PA_LOCK(alt_text, char *, area->alt);
				alt_buff = PA_ALLOC(area->alt_len + 1);
				if (alt_buff != NULL)
				{
					char *new_alt;

					PA_LOCK(new_alt, char *, alt_buff);
					XP_STRCPY(new_alt, alt_text);
					PA_UNLOCK(alt_buff);
				}
				PA_UNLOCK(area->alt);
				anchor->alt = alt_buff;
			}
예제 #9
0
static void
lo_FormatJavaAppInternal(MWContext *context, lo_DocState *state, PA_Tag *tag, LO_JavaAppStruct *java_app)
{
	PA_Block buff;
	char *str;
	int32 val;
	int32 doc_width;
	Bool widthSpecified = FALSE;
	Bool heightSpecified = FALSE;
	lo_DocLists *doc_lists;

    java_app->nextApplet = NULL;
#ifdef MOCHA
    java_app->mocha_object = NULL;
#endif

	java_app->FE_Data = NULL;
	java_app->session_data = NULL;
	java_app->line_height = state->line_height;

	java_app->base_url = NULL;
	java_app->attr_code = NULL;
	java_app->attr_codebase = NULL;
	java_app->attr_archive = NULL;
	java_app->attr_name = NULL;

	java_app->param_cnt = 0;
	java_app->param_names = NULL;
	java_app->param_values = NULL;

	java_app->may_script = FALSE;

	java_app->alignment = LO_ALIGN_BASELINE;
	java_app->border_width = JAVA_DEF_BORDER;
	java_app->border_vert_space = JAVA_DEF_VERTICAL_SPACE;
	java_app->border_horiz_space = JAVA_DEF_HORIZONTAL_SPACE;
	
	java_app->layer = NULL;
	java_app->tag = tag;

	/*
	 * Assign a unique index for this object 
	 * and increment the master index.
	 */
	java_app->embed_index = state->top_state->embed_count++;

	/*
	 * Save away the base of the document
	 */
	buff = PA_ALLOC(XP_STRLEN(state->top_state->base_url) + 1);
	if (buff != NULL)
	{
		char *cp;
		PA_LOCK(cp, char*, buff);
		XP_STRCPY(cp, state->top_state->base_url);
		PA_UNLOCK(buff);
		java_app->base_url = buff;
	}
	else
	{
		state->top_state->out_of_memory = TRUE;
		return;
	}

	/*
	 * Check for an align parameter
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_ALIGN);
	if (buff != NULL)
	{
		Bool floating;

		floating = FALSE;
		PA_LOCK(str, char *, buff);
		java_app->alignment = lo_EvalAlignParam(str, &floating);
		if (floating != FALSE)
		{
			java_app->ele_attrmask |= LO_ELE_FLOATING;
		}
		PA_UNLOCK(buff);
		PA_FREE(buff);
	}

	/*
	 * Get the applet CODE or object CLASSID parameter. In both
	 * cases the value is place in java_app->attr_code
	 */
	if (java_app->selector_type == LO_JAVA_SELECTOR_APPLET)
	{
		/* APPLET tag CODE attribute */

		buff = lo_FetchParamValue(context, tag, PARAM_CODE);
	}
	else
	{
		/* OBJECT tag CLASSID attribute */

		char * str1, * str2;
		PA_Block new_buff;

		int selectorLength;

		selectorLength = 5;
		if (java_app->selector_type == LO_JAVA_SELECTOR_OBJECT_JAVAPROGRAM)
			selectorLength = 12;
		else if (java_app->selector_type == LO_JAVA_SELECTOR_OBJECT_JAVABEAN)
			selectorLength = 9;

		buff = lo_FetchParamValue(context, tag, PARAM_CLASSID);

		if (buff != NULL)
		{
			/* remove the "java:", "javaprogram:", or "javabean:"
			 * protocol selector.
			 */
			PA_LOCK(str1, char *, buff);
			new_buff = PA_ALLOC(XP_STRLEN(str1) + 1);
			PA_LOCK(str2, char *, new_buff);
			XP_STRCPY(str2, str1 + selectorLength);
			PA_UNLOCK(new_buff);
			PA_UNLOCK(buff);
			PA_FREE(buff);
			buff = new_buff;
		}
	}
	java_app->attr_code = buff;

	/*
	 * Check for the loaderbase parameter.
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_CODEBASE);
	java_app->attr_codebase = buff;

	/*
	 * Check for the archive parameter.
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_ARCHIVE);
	java_app->attr_archive = buff;

	/*
	 * Check for a mayscript attribute
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_MAYSCRIPT);
	if (buff != NULL)
	{
		java_app->may_script = TRUE;
		PA_FREE(buff);
	}

	/*
	 * Get the name of this java applet.
	 */
	if (java_app->selector_type != LO_JAVA_SELECTOR_APPLET)
		buff = lo_FetchParamValue(context, tag, PARAM_ID);
	else
		buff = lo_FetchParamValue(context, tag, PARAM_NAME);
	if (buff != NULL)
	{
		PA_LOCK(str, char *, buff);
		if (str != NULL)
		{
			int32 len;

			len = lo_StripTextWhitespace(str, XP_STRLEN(str));
		}
		PA_UNLOCK(buff);
	}
	java_app->attr_name = buff;

	doc_width = state->right_margin - state->left_margin;

	/*
	 * Get the width parameter, in absolute or percentage.
	 * If percentage, make it absolute.
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_WIDTH);
	if (buff != NULL)
	{
		Bool is_percent;

		PA_LOCK(str, char *, buff);
		val = lo_ValueOrPercent(str, &is_percent);
		if (is_percent != FALSE)
		{
			java_app->percent_width = val;
		}
		else
		{
			java_app->percent_width = 0;
			java_app->width = val;
			val = FEUNITS_X(val, context);
		}
		PA_UNLOCK(buff);
		PA_FREE(buff);
		widthSpecified = TRUE;
	}
	val = LO_GetWidthFromStyleSheet(context, state);
	if(val)
	{
		java_app->width = val;
		widthSpecified = TRUE;
	}

	/*
	 * Get the height parameter, in absolute or percentage.
	 * If percentage, make it absolute.
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_HEIGHT);
	if (buff != NULL)
	{
		Bool is_percent;

		PA_LOCK(str, char *, buff);
		val = lo_ValueOrPercent(str, &is_percent);
		if (is_percent != FALSE)
		{
			java_app->percent_height = val;
		}
		else
		{
			java_app->percent_height = 0;
			val = FEUNITS_Y(val, context);
		}
		java_app->height = val;
		PA_UNLOCK(buff);
		PA_FREE(buff);
		heightSpecified = TRUE;
	}

	val = LO_GetHeightFromStyleSheet(context, state);
	if(val)
	{
		java_app->height = val;
		heightSpecified = TRUE;
	}

	/* If they forgot to specify a width, make one up. */
	if (!widthSpecified) {
		val = 0;
		if (heightSpecified) {
			val = java_app->height;
		}
		else if (state->allow_percent_width) {
			val = state->win_width * 90 / 100;
		}
		if (val < 1) {
			val = 600;
		}
		java_app->width = val;
	}
	
	/* If they forgot to specify a height, make one up. */
	if (!heightSpecified) {
		val = 0;
		if (widthSpecified) {
			val = java_app->width;
		}
		else if (state->allow_percent_height) {
			val = state->win_height / 2;
		}
		if (val < 1) {
			val = 400;
		}
		java_app->height = val;
	}

    /* After going through all the trouble, just to make sure
     * the object tag HIDDEN case is covered as well.
     */
    if (java_app->ele_attrmask & LO_ELE_HIDDEN)
    {
        java_app->width = 0;
        java_app->height = 0;
    }

	/*
	 * Get the border parameter.
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_BORDER);
	if (buff != NULL)
	{
		PA_LOCK(str, char *, buff);
		val = XP_ATOI(str);
		if (val < 0)
		{
			val = 0;
		}
		java_app->border_width = val;
		PA_UNLOCK(buff);
		PA_FREE(buff);
	}
	java_app->border_width = FEUNITS_X(java_app->border_width, context);

	/*
	 * Get the extra vertical space parameter.
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_VSPACE);
	if (buff != NULL)
	{
		PA_LOCK(str, char *, buff);
		val = XP_ATOI(str);
		if (val < 0)
		{
			val = 0;
		}
		java_app->border_vert_space = val;
		PA_UNLOCK(buff);
		PA_FREE(buff);
	}
	java_app->border_vert_space = FEUNITS_Y(java_app->border_vert_space,
							context);

	/*
	 * Get the extra horizontal space parameter.
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_HSPACE);
	if (buff != NULL)
	{
		PA_LOCK(str, char *, buff);
		val = XP_ATOI(str);
		if (val < 0)
		{
			val = 0;
		}
		java_app->border_horiz_space = val;
		PA_UNLOCK(buff);
		PA_FREE(buff);
	}
	java_app->border_horiz_space = FEUNITS_X(java_app->border_horiz_space,
						context);

	lo_FillInJavaAppGeometry(state, java_app, FALSE);

	/*
	 * See if we have some saved embed/java_app session data to restore.
	 */
	if (state->top_state->savedData.EmbedList != NULL)
	{
		lo_SavedEmbedListData *embed_list;
		embed_list = state->top_state->savedData.EmbedList;

		/*
		 * If there is still valid data to restore available.
		 */
		if (java_app->embed_index < embed_list->embed_count)
		{
			lo_EmbedDataElement* embed_data_list;

			PA_LOCK(embed_data_list, lo_EmbedDataElement*,
				embed_list->embed_data_list);
			java_app->session_data =
				embed_data_list[java_app->embed_index].data;
			PA_UNLOCK(embed_list->embed_data_list);
		}
예제 #10
0
void
lo_FormatObject(MWContext* context, lo_DocState* state, PA_Tag* tag)
{
	lo_TopState* top_state = state->top_state;
	lo_ObjectStack* top;
	LO_ObjectStruct* object;
	PA_Block buff;
	int16 type = LO_NONE;
	char* str;

#ifdef	ANTHRAX
	XP_Bool javaMimetypeHandler = FALSE;
	char* appletName;
	NET_cinfo* fileInfo;
#endif /* ANTHRAX */
	
	/*
	 * Make a new default object.  Passing LO_OBJECT will create an
	 * LO_Element, which being a union of all other layout element types
	 * is guaranteed to be big enough to transmogrify into one of these
	 * specific types later if necessary.
	 */
	object = (LO_ObjectStruct*) lo_NewElement(context, state, LO_OBJECT, NULL, 0);
	if (object == NULL)
	{
		state->top_state->out_of_memory = TRUE;
		return;
	}
	
	top = top_state->object_stack;
	top->object = object;

	/*
	 * Set up default fields for this object that are common
	 * to all possible object types.
	 */
	object->lo_element.type = LO_NONE;
	object->lo_element.lo_any.ele_id = NEXT_ELEMENT;
	object->lo_element.lo_any.x = state->x;
	object->lo_element.lo_any.x_offset = 0;
	object->lo_element.lo_any.y = state->y;
	object->lo_element.lo_any.y_offset = 0;
	object->lo_element.lo_any.width = 0;
	object->lo_element.lo_any.height = 0;
	object->lo_element.lo_any.next = NULL;
	object->lo_element.lo_any.prev = NULL;

	
	/*
	 * Now attempt to figure out what type of object we have.
	 * If the type can be determined here, great; otherwise
	 * we have to block until the type can be determined by
	 * reading in additional data.
	 *
	 * Initially the type of the object is LO_NONE.  When
	 * we figure out enough to know the type, we set it to
	 * LO_EMBED, LO_JAVA, or LO_IMAGE.  If the type had
	 * already been changed to a different incompatible type,
	 * then the tag is malformed and we should ignore it, so
	 * set the type to LO_UNKNOWN.
	 */
	
#if 0 
	/*
	 * Check the "codetype" attribute, which optionally determines
	 * the MIME type of the object code itself (as opposed to its
	 * data).  The only code type we know about right now is
	 * application/java-vm for Java applets.
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_CODETYPE);
	if (buff != NULL)
	{
		PA_LOCK(str, char *, buff);
		if (pa_TagEqual(APPLICATION_JAVAVM, str))
		{
			/* It's a Java applet */
			if (type == LO_NONE)
				type = LO_JAVA;
			else if (type != LO_JAVA)
				type = LO_UNKNOWN;
		}
		else if (pa_TagEqual(APPLICATION_OLEOBJECT, str) ||
				 pa_TagEqual(APPLICATION_OLEOBJECT2, str))
		{
			/* It's an OLE object */
			if (type == LO_NONE)
				type = LO_EMBED;
			else if (type != LO_EMBED)
				type = LO_UNKNOWN;
		}
		PA_UNLOCK(buff);
		XP_FREE(buff);
	}
#endif

	/*
	 * Check the "classid" attribute, which optionally determines
	 * the specific implementation of the object.  The classid
	 * could be a normal URL, in which case we have to retrieve
	 * that URL and match it against a known code type (see above).
	 * There are also two "magic" URL types supported for classid:
	 * "clsid:", which indicates a COM 376-hex-digit class ID,
	 * and "java:", which indicates a specific java class to run.
	 * Note that the "java:" URL is different from the APPLET
	 * "code" attribute: the "java:" URL specifies a particular
	 * method (e.g. "java:program.run"), while the APPLET CODE
	 * attribute specifies an applet subclass (e.g. "MyApplet.class").
     *
     * Further notes about "java:"
     * We are adding two related "magic" protocol selectors to
     * augment "java:". These are "javaprogram:" and "javabean:".
     * They are used with embedded applications and application
     * objects. "javaprogram:" identifies an object as being a
     * subclass of netscape.application.Application, and is used
     * to start an instance of such application. "javabean:" is
     * used to add an embedded object to an application.
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_CLASSID);
	if (buff != NULL)
	{
		PA_LOCK(str, char *, buff);
		if (XP_STRNCASECMP(str, "clsid:", 6) == 0)
		{
			/*
			 * It's a COM class ID, so make sure we have an
			 * appropriate plug-in to handle ActiveX controls.
			 */
			if (NPL_FindPluginEnabledForType(APPLICATION_OLEOBJECT) != NULL)
			{
				if (type == LO_NONE)
					type = LO_EMBED;
				else if (type != LO_EMBED)
					type = LO_UNKNOWN;
			}
		}
		else if ( (XP_STRNCASECMP(str, "java:", 5) == 0) ||
                  (XP_STRNCASECMP(str, "javaprogram:", 12) == 0) ||
                  (XP_STRNCASECMP(str, "javabean:", 9) == 0) )
		{
			/* It's a Java class */
			if (type == LO_NONE)
				type = LO_JAVA;
			else if (type != LO_JAVA)
				type = LO_UNKNOWN;
		}
		else
		{
			/*
			 * Must be a URL to the code; we'll need to fetch it to
			 * determine the type.  bing: How should we do this?
			 */
		}
		PA_UNLOCK(buff);
		XP_FREE(buff);
	}

	/*
	 * Check the "type" attribute, which optionally determines
	 * the type of the data for the object.  The data type
	 * can be used to infer the object implementation type if
	 * the implementation hasn't been specified via "classid"
	 * or "codetype" (see above).  The two kinds of objects
	 * we currently support with typed data are plug-ins and
	 * images; for plug-ins we can ask libplug if the type is
	 * currently handled by a plug-in; for images we just check
	 * against a hard-coded list of image types we natively
	 * support (yuck).
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_TYPE);
	if (buff != NULL)
	{
		PA_LOCK(str, char *, buff);
		if (NPL_FindPluginEnabledForType(str) != NULL)
		{
			/* It's a plug-in */
			if (type == LO_NONE)
				type = LO_EMBED;
			else if (type != LO_EMBED)
				type = LO_UNKNOWN;
		}

		/*  
			Adding a check for applets that handle mimetypes.
			The pref is stored based on the particular mimetype.
			We do a lookup and if there is an association, the name
			of the applet is placed into "appletName".  
			
			NOTE: PREF_CopyCharPref() allocates memory for appletName
					and we must free it.
					
			9.23.97		amusil
		*/
#ifdef	ANTHRAX
		if((appletName = NPL_FindAppletEnabledForMimetype(str)) != NULL)
			{
			/* Set the type */
			type = LO_JAVA;
			
			/* set the CLASSID to whatever was put into "appletName" */
			lo_SetClassID(tag, appletName);
			
			/* set this so that we know later to translate the DATA/SRC param to a Java arg */
			javaMimetypeHandler = TRUE;
			XP_FREE(appletName);
			}
#endif	/* ANTHRAX */	
		
#if 0
		else if (XP_STRNCASECMP(str, "image/", 6) == 0)
		{
			if (XP_STRCASECMP(str, IMAGE_GIF) ||
				XP_STRCASECMP(str, IMAGE_JPG) ||
				XP_STRCASECMP(str, IMAGE_PJPG) ||
				XP_STRCASECMP(str, IMAGE_XBM) ||
				XP_STRCASECMP(str, IMAGE_XBM2) ||
				XP_STRCASECMP(str, IMAGE_XBM3))
			{
				/* It's an image */
				if (type == LO_NONE)
					type = LO_IMAGE;
				else if (type != LO_IMAGE)
					type = LO_UNKNOWN;
			}
		}
#endif /* if 0 */

#ifdef SHACK
		if (XP_STRNCASECMP(str, "builtin", 7) == 0)
		{
			if (type == LO_NONE)
				type = LO_EMBED;
			else if (type != LO_EMBED)
				type = LO_UNKNOWN;
		}
#endif /* SHACK */

		PA_UNLOCK(buff);
		XP_FREE(buff);
	}
#ifdef	ANTHRAX
	else /* we didn't find a TYPE param, so check the filename to get the type - amusil */
		{
		buff = lo_FetchParamValue(context, tag, PARAM_SRC);
		/* if no src, check if there's a DATA param */
		if(buff == NULL)
			buff = lo_FetchParamValue(context, tag, PARAM_DATA);
			
		
		/* extract the mimetype info */
		PA_LOCK(str, char *, buff);
		fileInfo = NET_cinfo_find_type(str);
		
		str = fileInfo->type;
		if((appletName = NPL_FindAppletEnabledForMimetype(str)) != NULL)
			{
			/* Set the type */
			type = LO_JAVA;
			
			/* set the CLASSID to whatever was put into "appletName" */
			lo_SetClassID(tag, appletName);
			
			/* set this so that we know later to translate the DATA/SRC param to a Java arg */
			javaMimetypeHandler = TRUE;
			XP_FREE(appletName);			/* do we need to free this regardless? */	
			}
		if(buff)
			XP_FREE(buff);
		}
#endif	/* ANTRHAX */


	if (type == LO_EMBED)
	{
		object->lo_element.type = LO_EMBED;
	}
#ifdef JAVA
	else if (type == LO_JAVA)
	{
		if (LJ_GetJavaEnabled() != FALSE)
		{
			/*
			 * Close out the current applet if necessary
			 * (people tend to forget "</APPLET>").
			 */
			if (state->current_java != NULL)
				lo_CloseJavaApp(context, state, state->current_java);
				
			object->lo_element.type = LO_JAVA;
			lo_FormatJavaObject(context, state, tag, (LO_JavaAppStruct*) object);
			
			/* 
				If we determined previously that this is an applet to mimetype
				association, we must set up the SRC or DATA as an arg for the 
				applet.
				
				9.8.97		amusil
			*/
#ifdef	ANTHRAX
			if(javaMimetypeHandler)
				lo_SetJavaArgs((char*)tag->data, state->current_java);
#endif	/* ANTHRAX */
		}
	}
#endif /* JAVA */
#if 0
	else if (type == LO_IMAGE)
	{
		object->type = LO_IMAGE;
		lo_FormatImageObject(context, state, tag, (LO_ImageStruct*) object);
	}
#endif /* if 0 */
	else
	{
		/*
		 * Check for a "data" attribute; if it exists, we can get
		 * the URL later to see what the type of the object should be.
		 */
		buff = lo_FetchParamValue(context, tag, PARAM_DATA);
		if (buff != NULL)
		{
			PA_LOCK(str, char *, buff);
			if (XP_STRNCASECMP(str, "data:", 5) == 0)
			{
				/* bing: deal with magic data URLs here */
				PA_UNLOCK(buff);
				XP_FREE(buff);
			}
			else
			{
				
				/*
				 * Block layout until we can read the PARAM tags
				 * and closing </OBJECT> tag, go get the data URL,
				 * and determine its type.  At that point (in
				 * either LO_NewObjectStream, or lo_ObjectURLExit),
				 * we know the object type and can unblock.
				 */
				top->data_url = str;
				state->top_state->layout_blocking_element = (LO_Element*) object;
				PA_UNLOCK(buff);
				/* Don't free buff; we stored it in the object stack */
			}
		}
		else
		{
			/*
			 * Otherwise we just don't know what to do with this!
			 */
			object->lo_element.type = LO_UNKNOWN;
		}
	}
}
예제 #11
0
/* 
 * Takes a "PARAM" tag and pointers to the object's attribute
 * count, attribute name array, and attribute value array.
 * Parses the name and value of the PARAM and adjusts the
 * attribute count, names, and values accordingly.
 */
void
lo_ObjectParam(MWContext* context, lo_DocState* state, PA_Tag* tag,
			   uint32* count, char*** names, char*** values)
{
	PA_Block buff;
	char *str;
	char *param_name = NULL;
	char *param_value = NULL;
	char **name_list;
	char **value_list;
	
	/*
	 * Get the name of this parameter.
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_NAME);
	if (buff != NULL)
	{
		PA_LOCK(str, char *, buff);
		if (str != NULL)
		{
			int32 len;
			char *new_str;

			len = lo_StripTextWhitespace(str, XP_STRLEN(str));
			new_str = (char *)XP_ALLOC(len + 1);
			if (new_str != NULL)
			{
				XP_STRCPY(new_str, str);
			}
			param_name = new_str;
		}
		PA_UNLOCK(buff);
		PA_FREE(buff);
	}
	else
	{
		/* If we don't have a parameter name, it's useless */
		return;
	}

	/*
	 * Get the value of this parameter.
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_VALUE);
	if (buff != NULL)
	{
		PA_LOCK(str, char *, buff);
		if (str != NULL)
		{
			int32 len;
			char *new_str;

			len = lo_StripTextWhitespace(str, XP_STRLEN(str));
			new_str = (char *)XP_ALLOC(len + 1);
			if (new_str != NULL)
			{
				XP_STRCPY(new_str, str);
			}
			param_value = new_str;
		}
		PA_UNLOCK(buff);
		PA_FREE(buff);
	}

	/*
	 * Add the parameter to the name/value list.
	 */
	if (*names == NULL)
		name_list = (char **)XP_ALLOC(sizeof(char *));
	else
		name_list = (char **)XP_REALLOC(*names,
						((*count + 1) * sizeof(char *)));
	
	/*
	 * If we run out of memory here, free up what
	 * we can and return.
	 */
	if (name_list == NULL)
	{
		state->top_state->out_of_memory = TRUE;
		XP_FREE(param_name);
		if (param_value != NULL)
			XP_FREE(param_value);
		return;
	}

	if (*values == NULL)
		value_list = (char **)XP_ALLOC(sizeof(char *));
	else
		value_list = (char **)XP_REALLOC(*values,
						((*count + 1) * sizeof(char *)));

	/*
	 * If we run out of memory here, free up what
	 * we can and return.
	 */
	if (value_list == NULL)
	{
		state->top_state->out_of_memory = TRUE;
		XP_FREE(param_name);
		if (param_value != NULL)
			XP_FREE(param_value);
		return;
	}
	
	*names = name_list;
	*values = value_list;
	(*names)[*count] = param_name;
	(*values)[*count] = param_value;
	(*count)++;

}
예제 #12
0
void
lo_ProcessScriptTag(MWContext *context, lo_DocState *state, PA_Tag *tag, JSObject *obj)
{
    lo_TopState *top_state;
    pa_DocData *doc_data;
    XP_Bool type_explicitly_set=FALSE;
    XP_Bool saw_archive=FALSE;
#ifdef DEBUG_ScriptPlugin
	char * mimebuf = NULL;
#endif

    top_state = state->top_state;
    doc_data = (pa_DocData *)top_state->doc_data;
    XP_ASSERT(doc_data != NULL || state->in_relayout || tag->lo_data);

    if (tag->is_end == FALSE) {
        PA_Block buff;
        char *str, *url, *archiveSrc, *id, *codebase;

        /* Controversial default language value. */
        top_state->version = JSVERSION_DEFAULT;
        if (tag->type == P_STYLE || tag->type == P_LINK) {
            top_state->in_script = top_state->default_style_script_type;
        }
        else {
            /* in order to get old script behaviour, pretend
             * that the content-type is explicitly set for all scripts
             */
            type_explicitly_set = TRUE;
            top_state->in_script = SCRIPT_TYPE_MOCHA;
        }

        /* XXX account for HTML comment bytes and  "lost" newlines */
        if (lo_IsAnyCurrentAncestorSourced(state))
            top_state->script_bytes = top_state->layout_bytes;
        else
            top_state->script_bytes = top_state->layout_bytes - tag->true_len;
        if (tag->lo_data != NULL) {
            top_state->script_bytes += (int32)tag->lo_data - 1;
            tag->lo_data = NULL;
        } 
        else if (doc_data != NULL) {
            top_state->script_bytes += doc_data->comment_bytes;
        } 
        else {
            XP_ASSERT(state->in_relayout);
        }

	lo_ParseScriptLanguage(context, tag, &top_state->in_script,
			       &top_state->version);
#ifdef DEBUG_ScriptPlugin
		if (top_state->in_script == SCRIPT_TYPE_UNKNOWN)
		{
			mimebuf = npl_Script2mimeType(context,tag);
			if (mimebuf){
				if (NPL_FindPluginEnabledForType(mimebuf)){
					top_state->in_script = SCRIPT_TYPE_PLUGIN;
					XP_ASSERT(top_state->mimetype == NULL);
					StrAllocCopy((char *)top_state->mimetype,mimebuf);
					XP_FREE(mimebuf);
					mimebuf = NULL;
				}
				else{
					XP_FREE(mimebuf);
					mimebuf = NULL;
				}
			}
		}
#endif /* DEBUG_ScriptPlugin */

        buff = lo_FetchParamValue(context, tag, PARAM_TYPE);
        if (buff != NULL) {
            PA_LOCK(str, char *, buff);
            if ((XP_STRCASECMP(str, js_content_type) == 0) ||
                (!XP_STRCASECMP(str, "text/javascript"))) {
		if(tag->type == P_STYLE || tag->type == P_LINK)
		{
		    top_state->in_script = SCRIPT_TYPE_JSSS;
		    top_state->default_style_script_type = SCRIPT_TYPE_JSSS;
		}
		else
		{
		    top_state->in_script = SCRIPT_TYPE_MOCHA;                    
		}
                type_explicitly_set = TRUE;
            } 
            else if ((XP_STRCASECMP(str, TEXT_CSS) == 0)) {
                top_state->in_script = SCRIPT_TYPE_CSS;
                top_state->default_style_script_type = SCRIPT_TYPE_CSS;
                type_explicitly_set = TRUE;
            } 
            else {
                top_state->in_script = SCRIPT_TYPE_UNKNOWN;
                top_state->default_style_script_type = SCRIPT_TYPE_UNKNOWN;
            }
            PA_UNLOCK(buff);
            PA_FREE(buff);
        } 

	/* check for media=screen
	 * don't load the style sheet if there 
	 * is a media not equal to screen
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_MEDIA);
	if (buff) {
	    if (strcasecomp((char*)buff, "screen")) {
		/* set the script type to UNKNOWN
		 * so that it will get thrown away
		 */
		top_state->in_script = SCRIPT_TYPE_UNKNOWN;
	    }
	    PA_FREE(buff);
	}

        /*
         * Flush the line buffer so we can start storing Mocha script
         * source lines in there.
         */
        lo_FlushLineBuffer(context, state);

        url = archiveSrc = id = codebase = NULL;
        if (top_state->in_script != SCRIPT_TYPE_NOT) {
            /*
             * Check for the archive parameter for known languages.
             */
            buff = lo_FetchParamValue(context, tag, PARAM_ARCHIVE);
            if (buff != NULL) {
                saw_archive = TRUE;
                PA_LOCK(str, char *, buff);
                url = NET_MakeAbsoluteURL(top_state->base_url, str);
                PA_UNLOCK(buff);
                PA_FREE(buff);
		if (url == NULL) {
                    top_state->out_of_memory = TRUE;
                    return;
		}
            }

            /* 
             * Look for ID attribute. If it's there we have may have
             * an inline signed script.
             */
            buff = lo_FetchParamValue(context, tag, PARAM_ID);
            if (buff != NULL) {
                PA_LOCK(str, char *, buff);
                StrAllocCopy(id, str);
                PA_UNLOCK(buff);
                PA_FREE(buff);
		if (id == NULL) {
                    top_state->out_of_memory = TRUE;
		    XP_FREEIF(url);
                    return;
		}
            }

            /*
             * Now look for a SRC="url" attribute for known languages.
             * If found, synchronously load the url.
             */
	    buff = lo_FetchParamValue(context, tag, PARAM_SRC);  /* XXX overloaded rv */
            if (buff != NULL) {
		XP_Bool allowFileSrc = FALSE;
                char *absUrl;

                PA_LOCK(str, char *, buff);

		PREF_GetBoolPref(lo_jsAllowFileSrcFromNonFile, &allowFileSrc);
                absUrl = NET_MakeAbsoluteURL(top_state->base_url, str);
		if (absUrl == NULL) {
		    top_state->out_of_memory = TRUE;
		    XP_FREEIF(id);
                } else if (allowFileSrc == FALSE &&
		           NET_URL_Type(absUrl) == FILE_TYPE_URL &&
		           NET_URL_Type(top_state->url) != FILE_TYPE_URL) {
		    /*
		     * Deny access from http: to file: via SCRIPT SRC=...
		     * XXX silently
		     */
                    top_state->in_script = SCRIPT_TYPE_UNKNOWN;
                    XP_FREE(absUrl);
                    XP_FREEIF(url);
		    XP_FREEIF(id);
		} else if (url != NULL) {
                    XP_FREE(absUrl);
                    StrAllocCopy(archiveSrc, str);
		    if (archiveSrc == NULL) {
			top_state->out_of_memory = TRUE;
			XP_FREE(url);
			XP_FREEIF(id);
		    }
                } else {
                    url = absUrl;
                }
                PA_UNLOCK(buff);
                PA_FREE(buff);
		if (top_state->out_of_memory)
		    return;

                /*
                 * If we are doing a <script src=""> mocha script but JS
                 *   is turned off just ignore the tag
                 */
		if (!LM_CanDoJS(context)) {
                    top_state->in_script = SCRIPT_TYPE_UNKNOWN;
                    XP_FREE(url);
		    XP_FREEIF(id);
		    XP_FREEIF(archiveSrc);
                    return;
                }
            }
        }

        /*
         * Set text_divert so we know to accumulate text in line_buf
         * without interpretation.
         */
        state->text_divert = tag->type;

        /*
         * XXX need to stack these to handle blocked SCRIPT tags
         */
        top_state->script_lineno = tag->newline_count + 1;

        /* if we got here as a result of a LINK tag
         * check to make sure rel=stylesheet and then
         * check for an HREF and if one does not exist
         * fail
         */
        if (tag->type == P_LINK) {
            char *cbuff = (char*)lo_FetchParamValue(context, tag, PARAM_REL);
                        
            if (cbuff && !strcasecomp(cbuff, "stylesheet")) {
                XP_FREE(cbuff);

                cbuff = (char*)lo_FetchParamValue(context, tag, PARAM_HREF);

                if (cbuff) {
                    if (saw_archive && url) {
                        archiveSrc = XP_STRDUP(cbuff);
                    } else {
		        XP_FREEIF(url);
                        url = NET_MakeAbsoluteURL(top_state->base_url, cbuff);
                    }
		}
            }

            XP_FREEIF(cbuff);
        }

        if (url != NULL || id != NULL || codebase != NULL) {
            if ((doc_data != NULL) &&
                (state->in_relayout == FALSE) &&
                SCRIPT_EXEC_OK(top_state, state, tag->type, P_SCRIPT)) {
                ScriptData *data;

                data = XP_ALLOC(sizeof(ScriptData));
                if (data == NULL) {
                    top_state->out_of_memory = TRUE;
                    return;
                }
                data->context = context;
                data->state = state;
                data->tag = PA_CloneMDLTag(tag);
                if (data->tag == NULL) {
                    top_state->out_of_memory = TRUE;
		    XP_FREE(data);
                    return;
                }
                data->url = url;
                data->archiveSrc = archiveSrc;
                data->id = id;
                if (codebase == NULL) {
                    StrAllocCopy(codebase, top_state->base_url);
                }
                data->codebase = codebase;
                data->buffer = NULL;
                data->bufferSize = 0;
                data->version = top_state->version;

		/*
		 * Only SCRIPT ARCHIVE= ID= without SRC= is an inline signed
		 * script -- if there is a SRC= attribute, archiveSrc will be
		 * non-null.
		 */
                data->inlineSigned = (JSBool)
		    (url != NULL && archiveSrc == NULL && id != NULL);

                /* Reset version accumulator */
                top_state->version = JSVERSION_UNKNOWN;

                XP_ASSERT (tag->type == P_SCRIPT || tag->type == P_STYLE || 
			   tag->type == P_LINK);

	        /* 
		 * Out-of-line included (by src=) or inline signed script.
		 * Save continuatation data on top_state.  If it's signed,
		 * we'll verify the signature once we see </script> and
		 * have the inline script to verify.
		 */
		top_state->scriptData = data;

            } 
	    else {
                XP_FREE(url);
		XP_FREEIF(id);
		XP_FREEIF(archiveSrc);
            }
        }
    } 
    else {

	/*
	 * We are in the </script> tag now...
	 */

        size_t line_buf_len;
        intn script_type;
        char *scope_to=NULL;
        char *untransformed = NULL;

        script_type = top_state->in_script;
        top_state->in_script = SCRIPT_TYPE_NOT;

	/* guard against superfluous end tags */
	if (script_type == SCRIPT_TYPE_NOT)
	    goto end_tag_out;

	/* convert from CSS to JavaScript here */
        if (tag->type != P_LINK && script_type == SCRIPT_TYPE_CSS) {
            char *new_buffer;
            int32 new_buffer_length;

            CSS_ConvertToJS((char *)state->line_buf, 
                            state->line_buf_len,
                            &new_buffer,
                            &new_buffer_length);

            if (!new_buffer) {
                /* css translator error, unblock layout and return */
                state->text_divert = P_UNKNOWN;
                state->line_buf_len = 0; /* clear script text */
                goto end_tag_out;
            }

            untransformed = (char *) state->line_buf;
            state->line_buf = (PA_Block) new_buffer;
            state->line_buf_len = new_buffer_length;
            state->line_buf_size = new_buffer_length;

            if (state->line_buf_len)
                state->line_buf_len--; /* hack: subtract one to remove final \n */

            script_type = SCRIPT_TYPE_JSSS;
        }

        if (tag->type == P_STYLE) {
            /* mocha scoped to document == jsss */
            scope_to = "document";
        }

        /*
         * Reset these before potentially recursing indirectly through
         * the document.write() built-in function, which writes to the
         * very same doc_data->parser_stream that this <SCRIPT> tag
         * came in on.
         */
        state->text_divert = P_UNKNOWN;
        line_buf_len = state->line_buf_len;
        state->line_buf_len = 0;

        if (script_type != SCRIPT_TYPE_UNKNOWN && 
	    script_type != SCRIPT_TYPE_NOT) {
            /*
             * If mocha is disabled or can't be done in this context we
             *   are going to just ignore the buffer contents
             */
            if (!LM_CanDoJS(context)) {
				top_state->in_script = SCRIPT_TYPE_UNKNOWN;
                goto end_tag_out;
            }

            if ((doc_data != NULL) &&
                (state->in_relayout == FALSE) &&
                SCRIPT_EXEC_OK(top_state, state, tag->type, P_SCRIPT)) {

                /*
                 * First off, make sure layout is blocking on us
                 */
                if (lo_create_script_blockage(context, state, 
					tag->type == P_SCRIPT ? LO_SCRIPT : LO_UNKNOWN)) 
				{
                    ScriptData *data;

                    /*
                     * Extreme hackery.  Hideous and shameful.  See the comment
						* in lo_BlockScriptTag before similar is_end/overflow code
						* and commence vomiting.
                     */
                    lo_BlockScriptTag(context, state, NULL);

		    if (tag->is_end == (PRPackedBool)1) {
			  PA_PushOverflow(doc_data);
			  doc_data->overflow_depth ++;
		    }

		    /*
		     * Set the document.write tag insertion point.
		     */
             top_state->input_write_point[top_state->input_write_level] = &top_state->tags;

		    data = top_state->scriptData;
                    top_state->scriptData = NULL;
                    if (data && data->url) {
			/*
			 * Three cases:
			 * 1.  SCRIPT SRC=: url non-null
			 * 2.  SCRIPT ARCHIVE= SRC=: url, archiveSrc non-null
			 * 3.  SCRIPT ARCHIVE= ID=: url, id non-null
			 * In the last case, we copy the inline script into
			 * data's buffer and let lo_script_archive_exit_fn do
			 * the eval.  We use an inlineSigned flag to avoid a
			 * bunch of (url != NULL && archiveSrc == NULL && id
			 * != NULL) tests.
			 */
			if (data->inlineSigned) {
                            StrAllocCopy(data->buffer, (char *) state->line_buf);
                            data->bufferSize = line_buf_len;
			}
			lo_GetScriptFromURL(data, script_type);
                    }
		    else {
                        JSPrincipals *principals = NULL;
			ETEvalStuff * stuff;
			
                        if (data) {
			    principals = LM_NewJSPrincipals(NULL, data->id, 
							    data->codebase);
                            if (untransformed &&
				!LM_SetUntransformedSource(principals, 
                                                           untransformed,
                                                           (char *) state->line_buf))
                            {
                                top_state->out_of_memory = TRUE;
                            }
                            lo_DestroyScriptData(data);
			}

                        /* 
                         * send the buffer off to be evaluated 
			 */
#ifdef DEBUG_ScriptPlugin
			 			if (script_type == SCRIPT_TYPE_PLUGIN)
						{
							XP_ASSERT(mimebuf == NULL);
							npl_ScriptPlugin(context, state, tag, line_buf_len,top_state->mimetype);
						    lo_unblock_script_tag(context, TRUE);
						}
						else
#endif /* DEBUG_ScriptPlugin */
 

			stuff = (ETEvalStuff *) XP_NEW_ZAP(ETEvalStuff);
			if (!stuff)
			    goto end_tag_out;

			stuff->len = line_buf_len;
			stuff->line_no = top_state->script_lineno;
			if (scope_to)
			    stuff->scope_to = XP_STRDUP(scope_to);
			else
			    stuff->scope_to = NULL;
			stuff->want_result = JS_FALSE;
			stuff->data = context;
			stuff->version = top_state->version;
			stuff->principals = principals;

                        ET_EvaluateScript(context, 
                                          (char *) state->line_buf,
					  stuff,
                                          lo_ScriptEvalExitFn);
                    }

                    /* Reset version accumulator */
                    top_state->version = JSVERSION_UNKNOWN;
                }
            }
        }
      end_tag_out:
	/*
	 * If we got a </SCRIPT> and still have scriptData set here, it must
	 *   be left over from an error case above, so we free it.
	 */
	if (top_state->scriptData) {
	    XP_ASSERT(!top_state->layout_blocking_element);
            lo_DestroyScriptData(top_state->scriptData);
	    top_state->scriptData = NULL;
	}
        XP_FREEIF(untransformed);
    }
}
예제 #13
0
/* evaluate the buffer encompassed by the style attribute on any tag.
 * this will be JSS or CSS 
 *
 * Returns TRUE if it needs to block layout
 * Returns FALSE if not.
 */
XP_Bool
lo_ProcessStyleAttribute(MWContext *context, lo_DocState *state, PA_Tag *tag, char *script_buff)
{
    lo_TopState *top_state;
    char *scope_to = NULL;
    int32 script_buff_len;
    char *new_id;
    XP_Bool in_double_quote=FALSE, in_single_quote=FALSE;
    char *ptr, *end;
    ETEvalStuff * stuff;

    if (!state)
  	{
       XP_FREEIF(script_buff);
	   return FALSE;
	}


    if (!script_buff)
        return FALSE;

    /* @@@ A bit of a hack.
     * Get rid of the style attribute in the tag->data so that we don't
     * go circular
     *
     * get rid of STYLE by rewriting it as SYTLE so that the parser 
     * ignores it :)
     */
    for (ptr=(char*)tag->data, end = ptr+tag->data_len; ptr < end; ptr++) {
        if (*ptr == '"') {
            in_double_quote = !in_double_quote;
        }
        else if (*ptr == '\'') {
            in_single_quote = !in_single_quote;
        }
        else if (!in_single_quote &&
                 !in_double_quote &&
                 !strncasecomp(ptr, PARAM_STYLE, sizeof(PARAM_STYLE)-1)) {
            *ptr = 'T';    /* ttyle NOT style */
            break;
        }
    }

    script_buff_len = XP_STRLEN(script_buff);

    top_state = state->top_state;

    /* get the tag ID if it has one */
    new_id = (char *)lo_FetchParamValue(context, tag, PARAM_ID);

    if (!new_id)
        new_id = PR_smprintf(NSIMPLICITID"%ld", top_state->tag_count);

    if (!new_id)
        return FALSE;

    if (top_state->default_style_script_type == SCRIPT_TYPE_JSSS ||
	top_state->default_style_script_type == SCRIPT_TYPE_MOCHA) {

    	StrAllocCopy(scope_to, "document.ids.");
    	StrAllocCat(scope_to, new_id);

    	if (!scope_to) {
    	    XP_FREE(new_id);
	    return(FALSE);
	}
    }
    else if (top_state->default_style_script_type == SCRIPT_TYPE_CSS) {
        char *new_jss_buff;
        int32 new_jss_buff_len;
        char *new_css_buff;
        int32 new_css_buff_len;

        /* scope the css to the ns implicit ID */
        new_css_buff = PR_smprintf("#%s { %s }", new_id, script_buff);

        XP_FREE(script_buff);

        if (!new_css_buff) {
	    XP_FREE(new_id);
	    return FALSE;
	}

        new_css_buff_len = XP_STRLEN(new_css_buff);
        
        /* convert to JSS */
        CSS_ConvertToJS(new_css_buff,
                        new_css_buff_len,
                        &new_jss_buff,
                        &new_jss_buff_len);

        XP_FREE(new_css_buff);

        if (!new_jss_buff) {
	    XP_FREE(new_id);
	    return FALSE;
	}

        script_buff = new_jss_buff;
        script_buff_len = new_jss_buff_len;
    }
    else {
        /* unknown script type, punt */
        XP_FREE(script_buff);
	XP_FREE(new_id);
        return FALSE;
    }

    /* not needed anymore */
    XP_FREE(new_id);

    stuff = (ETEvalStuff *) XP_NEW_ZAP(ETEvalStuff);
    if (!stuff) {
	/* what do we free here? */
	XP_FREE(new_id);
        return FALSE;
    }

    if (lo_CloneTagAndBlockLayout(context, state, tag)) {
        tag->type = P_UNKNOWN;
	stuff->len = XP_STRLEN(script_buff);
	stuff->line_no = top_state->script_lineno;
	stuff->scope_to = scope_to;
	stuff->want_result = JS_FALSE;
	stuff->data = context;
	stuff->version = top_state->version;
	stuff->principals = NULL;

        ET_EvaluateScript(context, script_buff, stuff, lo_StyleEvalExitFn);

	/* don't free scope_to, ET_EvaluateScript has taken possession */
        XP_FREE(script_buff);

        return TRUE;
    }

    XP_FREEIF(scope_to);
    XP_FREE(script_buff);
    
    return FALSE;
}
예제 #14
0
void
lo_BeginMulticolumn(MWContext *context, lo_DocState *state, PA_Tag *tag, LO_MulticolumnStruct *multicolEle)
{
	lo_MultiCol *multicol;
	PA_Block buff;
	char *str;
	int32 val;
	int32 doc_width;
	/* int32 width; */

	multicol = XP_NEW(lo_MultiCol);
	if (multicol == NULL)
	{
		state->top_state->out_of_memory = TRUE;
		return;
	}

	multicol->width = 0;
	multicol->isPercentWidth = FALSE;	

	/* Put a pointer to lo_multicol inside the MULTICOLUMN layout element that will be placed on the
	   line list */
	multicolEle->multicol = multicol;
    
	/*
     * If this multicol is within a layer, then we have to create an
     * artificial TABLE around it (since the multicol code depends on
     * the state's line array, which isn't in an updated state within
     * a layer). 
     */
    if (state->layer_nest_level > 0)
    {
        PA_Tag *tmp_tag;
        lo_TableRec *table;

        if (state->in_paragraph != FALSE)
        {
            lo_CloseParagraph(context, &state, tag, 2);
        }

        lo_BeginTableAttributes(context, state, NULL, NULL, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                NULL, NULL, NULL);
        
        table = state->current_table;
        if (table) {
            lo_BeginTableRowAttributes(context, state, table,
                                       NULL, NULL, NULL, NULL);

            lo_BeginTableCellAttributes(context, state, table,
                                        NULL, NULL, NULL, NULL, NULL,
                                        LO_TILE_BOTH, NULL, NULL, NULL, NULL,
                                        FALSE, TRUE);

            /* 
             * If we've successfully created a subdoc, we need to clone
             * the MULTICOL tag and save it in the subdoc, since the code
             * above us doesn't realize we're now in a table.
             */
            if (state->sub_state) {
                state = state->sub_state;
                tmp_tag = PA_CloneMDLTag(tag);
                lo_SaveSubdocTags(context, state, tmp_tag);
            }
            multicol->close_table = TRUE;
        }
    }
    else {		
		/* if (line will not be flushed by lo_SetSoftLineBreak) and (there exist some elements on the line list) */
		if (state->linefeed_state >= 2 && state->line_list != NULL)
		{
			/* Append zero width and height line feed to the line list and flush the line list into
			   the line array. This forces the layout of elements contained within the MULTICOL tags
			   to start on a blank line_list and hence on a new line.  lo_EndMultiColumn needs this to
			   do its line array hacking properly. */
			lo_AppendZeroWidthAndHeightLF(context, state);			
		}

		lo_SetSoftLineBreakState(context, state, FALSE, 2);
        multicol->close_table = FALSE;		
    }

	/*
	 * Since we are going to block layout during multicol
	 * processing, we need to flush the compositor of any
	 * pending displays.
	 */
	if (context->compositor)
	{
		CL_CompositeNow(context->compositor);
	}

	lo_StartMultiColInit( state, multicol );

	/*
	multicol->end_last_line = state->end_last_line;
	multicol->start_ele = state->top_state->element_id;
	multicol->start_line = state->line_num;
	multicol->end_line = multicol->start_line;
	multicol->start_x = state->x;
	multicol->start_y = state->y;
	multicol->end_y = multicol->start_y;
	*/
	multicol->cols = 1;
	multicol->gutter = MULTICOL_GUTTER_WIDTH;

	/*	
     * Get the cols parameter.
     */
    buff = lo_FetchParamValue(context, tag, PARAM_COLS);
    if (buff != NULL)
    {
		PA_LOCK(str, char *, buff);
		multicol->cols = XP_ATOI(str);
		PA_UNLOCK(buff);
		PA_FREE(buff);
	}

	if (multicol->cols <= 1)
	{
		XP_DELETE(multicol);
		multicolEle->multicol = NULL;
		return;
	}

	/*
     * Get the gutter parameter.
     */
    buff = lo_FetchParamValue(context, tag, PARAM_GUTTER);
    if (buff != NULL)
    {
        PA_LOCK(str, char *, buff);
		multicol->gutter = XP_ATOI(str);
		if (multicol->gutter < 1)
		{
			multicol->gutter = 1;
		}
		PA_UNLOCK(buff);
		PA_FREE(buff);
	}

	multicol->gutter = FEUNITS_X(multicol->gutter, context);

	doc_width = state->right_margin - state->left_margin;
	/* width = doc_width; */

	/*
	 * Get the width parameter, in absolute or percentage.
	 * If percentage, make it absolute.
	 */
	/*
	buff = lo_FetchParamValue(context, tag, PARAM_WIDTH);
	if (buff != NULL)
	{
		Bool is_percent;

		PA_LOCK(str, char *, buff);
		val = lo_ValueOrPercent(str, &is_percent);
		if (is_percent != FALSE)
		{
			if (state->allow_percent_width == FALSE)
			{
				val = 0;
			}
			else
			{
				val = doc_width * val / 100;
				if (val < 1)
				{
					val = 1;
				}
			}
		}
		else
		{
			val = FEUNITS_X(val, context);
			if (val < 1)
			{
				val = 1;
			}
		}
		width = val;
		PA_UNLOCK(buff);
		PA_FREE(buff);
	}
	*/

	buff = lo_FetchParamValue(context, tag, PARAM_WIDTH);
	if (buff != NULL)
	{
		Bool is_percent;

		PA_LOCK(str, char *, buff);
		val = lo_ValueOrPercent(str, &is_percent);
		if (is_percent != FALSE)
		{
			multicol->width = val;
			multicol->isPercentWidth = TRUE;
		}
		else
		{
			multicol->width = val;
			multicol->isPercentWidth = FALSE;
			val = FEUNITS_X(val, context);
			if (val < 1)
			{
				val = 1;
			}
		}
		PA_UNLOCK(buff);
		PA_FREE(buff);
	}

	/*
	width = width - ((multicol->cols - 1) * multicol->gutter);
	multicol->col_width = width / multicol->cols;
	if (multicol->col_width < MULTICOL_MIN_WIDTH)
	{
		multicol->col_width = MULTICOL_MIN_WIDTH;
	}

	multicol->orig_margin = state->right_margin;

	lo_PushList(state, tag, QUOTE_NONE);
*/

	lo_SetupStateForBeginMulticol( state, multicol, doc_width );
	
	/*
	state->right_margin = state->left_margin + multicol->col_width;
	state->x = state->left_margin;
	state->list_stack->old_left_margin = state->left_margin;
	state->list_stack->old_right_margin = state->right_margin;

	multicol->orig_min_width = state->min_width;
	state->min_width = 0;
	*/

	/*
	 * Don't display anything while processing the multicolumn text.
	 */
	/*
	multicol->orig_display_blocking_element_y = state->display_blocking_element_y;
	state->display_blocking_element_y = -1;
	multicol->orig_display_blocked = state->display_blocked;
	state->display_blocked = TRUE;

	multicol->next = state->current_multicol;
	state->current_multicol = multicol;
	*/
}
예제 #15
0
JSObject *
LM_ReflectNamedAnchor(MWContext *context, lo_NameList *name_rec,
                      PA_Tag * tag, int32 layer_id, uint index)
{
    JSObject *obj, *array_obj, *document;
    MochaDecoder *decoder;
    JSContext *cx;
    JSObjectArray *array;
    JSAnchor *named_anchor;
    lo_TopState *top_state;
    PRHashTable *map;
    JSString *str;

    obj = name_rec->mocha_object;
    if (obj)
        return obj;

    decoder = LM_GetMochaDecoder(context);
    if (!decoder)
        return NULL;
    cx = decoder->js_context;

    top_state = lo_GetMochaTopState(context);
    if (top_state->resize_reload) {
        map = lm_GetIdToObjectMap(decoder);

        if (map)
            obj = (JSObject *)PR_HashTableLookup(map,
                                         LM_GET_MAPPING_KEY(LM_NAMEDANCHORS,
                                                            layer_id, index));
        if (obj) {
            name_rec->mocha_object = obj;
            LM_PutMochaDecoder(decoder);
            return obj;
        }
    }

    /* Get the document object that will hold this anchor */
    document = lm_GetDocumentFromLayerId(decoder, layer_id);
    if (!document) {
	LM_PutMochaDecoder(decoder);
	return NULL;
    }

    array_obj = lm_GetNameArray(decoder, document);
    if (!array_obj) {
        LM_PutMochaDecoder(decoder);
        return NULL;
    }
    array = JS_GetPrivate(cx, array_obj);
    if (!array) {
        LM_PutMochaDecoder(decoder);
	return NULL;
    }

    named_anchor = JS_malloc(cx, sizeof *named_anchor);
    if (!named_anchor) {
        LM_PutMochaDecoder(decoder);
        return NULL;
    }
    XP_BZERO(named_anchor, sizeof *named_anchor);

    obj = JS_NewObject(cx, &lm_anchor_class, decoder->anchor_prototype,
		       document);

    if (!obj || !JS_SetPrivate(cx, obj, named_anchor)) {
        JS_free(cx, named_anchor);
        LM_PutMochaDecoder(decoder);
        return NULL;
    }

    /* Put obj into the document.anchors array. */
    JS_DefineProperty(cx, array_obj, (char *) name_rec->name,
		      OBJECT_TO_JSVAL(obj), NULL, NULL,
		      JSPROP_ENUMERATE|JSPROP_READONLY);
    JS_AliasElement(cx, array_obj, (char *) name_rec->name, index);

    /* Put it in the index to object hash table */
    map = lm_GetIdToObjectMap(decoder);
    if (map) {
        PR_HashTableAdd(map,
                        LM_GET_MAPPING_KEY(LM_NAMEDANCHORS, layer_id, index),
                        obj);
    }
    if ((jsint) index >= array->length)
	array->length = index + 1;

    named_anchor->decoder = HOLD_BACK_COUNT(decoder);
    named_anchor->layer_id = layer_id;
    named_anchor->index = index;
    if (name_rec->element && name_rec->element->type == LO_TEXT) {
	str = lm_LocalEncodingToStr(context, 
				    (char *) name_rec->element->lo_text.text);
	if (!str || !JS_LockGCThing(cx, str)) {
	    LM_PutMochaDecoder(decoder);
	    return NULL;
	}
	named_anchor->text = str;
    }
    str = JS_NewStringCopyZ(cx, (char *) name_rec->name);
    if (!str || !JS_LockGCThing(cx, str)) {
        LM_PutMochaDecoder(decoder);
	return NULL;
    }
    named_anchor->name = str;

    name_rec->mocha_object = obj;

    /* see if there are any attributes for event handlers */
    if(tag) {
        PA_Block onlocate, id;

	/* don't hold the layout lock across compiles */
	LO_UnlockLayout();

        onlocate = lo_FetchParamValue(context, tag, PARAM_ONLOCATE);
        id = lo_FetchParamValue(context, tag, PARAM_ID);
        if (onlocate) {
	    (void) lm_CompileEventHandler(decoder, id, tag->data,
					  tag->newline_count, obj,
					  PARAM_ONLOCATE, onlocate);
            PA_FREE(onlocate);
        }
	if (id)
	    PA_FREE(id);
	LO_LockLayout();
    }

    LM_PutMochaDecoder(decoder);
    return obj;
}
예제 #16
0
JSObject *
LM_ReflectLink(MWContext *context, LO_AnchorData *anchor_data, PA_Tag * tag,
               int32 layer_id, uint index)
{
    JSObject *obj, *array_obj, *document;
    MochaDecoder *decoder;
    JSContext *cx;
    JSURL *url;
    lo_TopState *top_state;
    PRHashTable *map;

    anchor_data = LO_GetLinkByIndex(context, layer_id, index);
    if (!anchor_data)
	return NULL;

    obj = anchor_data->mocha_object;
    if (obj)
	return obj;

    decoder = LM_GetMochaDecoder(context);
    if (!decoder)
	return NULL;
    cx = decoder->js_context;

    top_state = lo_GetMochaTopState(context);
    if (top_state->resize_reload) {
        map = lm_GetIdToObjectMap(decoder);

        if (map)
            obj = (JSObject *)PR_HashTableLookup(map,
                             LM_GET_MAPPING_KEY(LM_LINKS, layer_id, index));
        if (obj) {
            anchor_data->mocha_object = obj;
            LM_PutMochaDecoder(decoder);
            return obj;
        }
    }

    /* Get the document object that will hold this link */
    document = lm_GetDocumentFromLayerId(decoder, layer_id);
    if (!document) {
	LM_PutMochaDecoder(decoder);
	return NULL;
    }

    array_obj = lm_GetLinkArray(decoder, document);
    if (!array_obj) {
	LM_PutMochaDecoder(decoder);
	return NULL;
    }

    url = lm_NewURL(cx, decoder, anchor_data, document);

    if (!url) {
	LM_PutMochaDecoder(decoder);
	return NULL;
    }
    url->index = index;
    url->layer_id = layer_id;
    obj = url->url_object;

    /* XXX should find a name/id to pass in */
    /* put it in the links array */
    if (!lm_AddObjectToArray(cx, array_obj, NULL, index, obj)) {
	LM_PutMochaDecoder(decoder);
    	return NULL;
    }

    /* Put it in the index to object hash table */
    map = lm_GetIdToObjectMap(decoder);
    if (map)
        PR_HashTableAdd(map, LM_GET_MAPPING_KEY(LM_LINKS, layer_id, index),
                        obj);

    anchor_data->mocha_object = obj;
    LM_PutMochaDecoder(decoder);

    /* see if there are any event handlers we need to reflect */
    if(tag) {

	PA_Block onclick, onmouseover, onmouseout, onmousedown, onmouseup, ondblclick, id;

	/* don't hold the layout lock across compiles */
	LO_UnlockLayout();

	onclick = lo_FetchParamValue(context, tag, PARAM_ONCLICK);
	onmouseover = lo_FetchParamValue(context, tag, PARAM_ONMOUSEOVER);
	onmouseout  = lo_FetchParamValue(context, tag, PARAM_ONMOUSEOUT);
	onmousedown = lo_FetchParamValue(context, tag, PARAM_ONMOUSEDOWN);
	onmouseup   = lo_FetchParamValue(context, tag, PARAM_ONMOUSEUP);
	ondblclick  = lo_FetchParamValue(context, tag, PARAM_ONDBLCLICK);
        id = lo_FetchParamValue(context, tag, PARAM_ID);

	if (onclick) {
	    (void) lm_CompileEventHandler(decoder, id, tag->data,
					  tag->newline_count, url->url_object,
				          PARAM_ONCLICK, onclick);
	    PA_FREE(onclick);
	    anchor_data->event_handler_present = TRUE;
	}
	if (onmouseover) {
	    (void) lm_CompileEventHandler(decoder, id, tag->data,
					  tag->newline_count, url->url_object,
					  PARAM_ONMOUSEOVER, onmouseover);
	    PA_FREE(onmouseover);
	    anchor_data->event_handler_present = TRUE;
	}
	if (onmouseout) {
	    (void) lm_CompileEventHandler(decoder, id, tag->data,
					  tag->newline_count, url->url_object,
					  PARAM_ONMOUSEOUT, onmouseout);
	    PA_FREE(onmouseout);
	    anchor_data->event_handler_present = TRUE;
	}
	if (onmousedown) {
	    (void) lm_CompileEventHandler(decoder, id, tag->data,
					  tag->newline_count, url->url_object,
					  PARAM_ONMOUSEDOWN, onmousedown);
	    PA_FREE(onmousedown);
	    anchor_data->event_handler_present = TRUE;
	}
	if (onmouseup) {
	    (void) lm_CompileEventHandler(decoder, id, tag->data,
					  tag->newline_count, url->url_object,
					  PARAM_ONMOUSEUP, onmouseup);
	    PA_FREE(onmouseup);
	    anchor_data->event_handler_present = TRUE;
	}
	if (ondblclick) {
	    (void) lm_CompileEventHandler(decoder, id, tag->data,
					  tag->newline_count, url->url_object,
					  PARAM_ONDBLCLICK, ondblclick);
	    PA_FREE(ondblclick);
	    anchor_data->event_handler_present = TRUE;
	}
	if (id)
	    PA_FREE(id);
        LO_LockLayout();
    }

    return obj;
}