/* parse a line that looks like * [whitespace]=[whitespace]"token" other stuff... * * return token or NULL. */ PRIVATE char * net_get_html_help_token(char *line_data, char**next_word) { char * line = line_data; char * cp; if(next_word) *next_word = NULL; while(XP_IS_SPACE(*line)) line++; if(*line != '=') return(NULL); line++; /* go past '=' */ while(XP_IS_SPACE(*line)) line++; if(*line != '"') return(NULL); line++; /* go past '"' */ for(cp=line; *cp; cp++) if(*cp == '"' && *(cp-1) != '\\') { *cp = '\0'; if(next_word) { *next_word = cp+1; while(XP_IS_SPACE(*(*next_word))) (*next_word)++; } break; } return(line); }
/* * This function parses a list of numbers (coordinates). * The numbers can have any integer value, and it is a comma separated list. * (optionally, whitespace can replace commas as separators in the list) */ int32 * lo_parse_coord_list(char *str, int32 *value_cnt, Bool must_be_odd) { char *tptr; char *n_str; int32 i, cnt, acnt; int32 *value_list; /* * Nothing in an empty list */ *value_cnt = 0; if ((str == NULL)||(*str == '\0')) { return((int32 *)NULL); } /* * Skip beginning whitespace, all whitespace is empty list. */ n_str = str; while (XP_IS_SPACE(*n_str)) { n_str++; } if (*n_str == '\0') { return((int32 *)NULL); } /* * Make a pass where any two numbers separated by just whitespace * are given a comma separator. Count entries while passing. */ cnt = 0; while (*n_str != '\0') { Bool has_comma; /* * Skip to a separator */ tptr = n_str; while ((!XP_IS_SPACE(*tptr))&&(*tptr != ',')&&(*tptr != '\0')) { tptr++; } n_str = tptr; /* * If no more entries, break out here */ if (*n_str == '\0') { break; } /* * Skip to the end of the separator, noting if we have a * comma. */ has_comma = FALSE; while ((XP_IS_SPACE(*tptr))||(*tptr == ',')) { if (*tptr == ',') { if (has_comma == FALSE) { has_comma = TRUE; } else { break; } } tptr++; } /* * If this was trailing whitespace we skipped, we are done. */ if ((*tptr == '\0')&&(has_comma == FALSE)) { break; } /* * Else if the separator is all whitespace, and this is not the * end of the string, add a comma to the separator. */ else if (has_comma == FALSE) { *n_str = ','; } /* * count the entry skipped. */ cnt++; n_str = tptr; } /* * count the last entry in the list. */ cnt++; /* * For polygons, we need a fake empty coord at the * end of the list of x,y pairs. */ if ((must_be_odd != FALSE)&&((cnt & 0x01) == 0)) { acnt = cnt + 1; } else { acnt = cnt; } *value_cnt = acnt; /* * Allocate space for the coordinate array. */ value_list = (int32 *)XP_ALLOC(acnt * sizeof(int32)); if (value_list == NULL) { return((int32 *)NULL); } /* * Second pass to copy integer values into list. */ tptr = str; for (i=0; i<cnt; i++) { char *ptr; ptr = strchr(tptr, ','); if (ptr != NULL) { *ptr = '\0'; } /* * Strip whitespace in front of number because I don't * trust atoi to do it on all platforms. */ while (XP_IS_SPACE(*tptr)) { tptr++; } if (*tptr == '\0') { value_list[i] = 0; } else { value_list[i] = (int32)XP_ATOI(tptr); } if (ptr != NULL) { *ptr = ','; tptr = (char *)(ptr + 1); } } return(value_list); }
void nsTypeAheadFind::RangeStartsInsideLink(nsIDOMRange *aRange, nsIPresShell *aPresShell, PRBool *aIsInsideLink, PRBool *aIsStartingLink) { *aIsInsideLink = PR_FALSE; *aIsStartingLink = PR_TRUE; // ------- Get nsIContent to test ------- nsCOMPtr<nsIDOMNode> startNode; nsCOMPtr<nsIContent> startContent, origContent; aRange->GetStartContainer(getter_AddRefs(startNode)); PRInt32 startOffset; aRange->GetStartOffset(&startOffset); startContent = do_QueryInterface(startNode); if (!startContent) { NS_NOTREACHED("startContent should never be null"); return; } origContent = startContent; if (startContent->IsElement()) { nsIContent *childContent = startContent->GetChildAt(startOffset); if (childContent) { startContent = childContent; } } else if (startOffset > 0) { const nsTextFragment *textFrag = startContent->GetText(); if (textFrag) { // look for non whitespace character before start offset for (PRInt32 index = 0; index < startOffset; index++) { if (!XP_IS_SPACE(textFrag->CharAt(index))) { *aIsStartingLink = PR_FALSE; // not at start of a node break; } } } } // ------- Check to see if inside link --------- // We now have the correct start node for the range // Search for links, starting with startNode, and going up parent chain nsCOMPtr<nsIAtom> tag, hrefAtom(do_GetAtom("href")); nsCOMPtr<nsIAtom> typeAtom(do_GetAtom("type")); while (PR_TRUE) { // Keep testing while startContent is equal to something, // eventually we'll run out of ancestors if (startContent->IsHTML()) { nsCOMPtr<nsILink> link(do_QueryInterface(startContent)); if (link) { // Check to see if inside HTML link *aIsInsideLink = startContent->HasAttr(kNameSpaceID_None, hrefAtom); return; } } else { // Any xml element can be an xlink *aIsInsideLink = startContent->HasAttr(kNameSpaceID_XLink, hrefAtom); if (*aIsInsideLink) { if (!startContent->AttrValueIs(kNameSpaceID_XLink, typeAtom, NS_LITERAL_STRING("simple"), eCaseMatters)) { *aIsInsideLink = PR_FALSE; // Xlink must be type="simple" } return; } } // Get the parent nsCOMPtr<nsIContent> parent = startContent->GetParent(); if (!parent) break; nsIContent *parentsFirstChild = parent->GetChildAt(0); // We don't want to look at a whitespace-only first child if (parentsFirstChild && parentsFirstChild->TextIsOnlyWhitespace()) { parentsFirstChild = parent->GetChildAt(1); } if (parentsFirstChild != startContent) { // startContent wasn't a first child, so we conclude that // if this is inside a link, it's not at the beginning of it *aIsStartingLink = PR_FALSE; } startContent = parent; } *aIsStartingLink = PR_FALSE; }
PRIVATE int net_ColorHTMLWrite (NET_StreamClass *stream, CONST char *s, int32 l) { int32 i; int32 last_output_point; char *new_markup=0; char *tmp_markup=0; char tiny_buf[4]; CONST char *cp; int status; DataObject *obj=stream->data_object; last_output_point = 0; for(i = 0, cp = s; i < l; i++, cp++) { switch(obj->state) { case IN_CONTENT: /* do nothing until you find a '<' "<!--" or '&' */ if(*cp == '<') { /* XXX we can miss a comment spanning a block boundary */ if(i+4 <= l && !XP_STRNCMP(cp, "<!--", 4)) { StrAllocCopy(new_markup, BEGIN_COMMENT_MARKUP); StrAllocCat(new_markup, "<"); obj->state = IN_COMMENT; } else { new_markup = net_BeginColorHTMLTag(obj); } } else if(*cp == '&') { StrAllocCopy(new_markup, BEGIN_AMPERSAND_THINGY_MARKUP); StrAllocCat(new_markup, "&"); obj->state = IN_AMPERSAND_THINGY; } break; case IN_SCRIPT: /* do nothing until you find '</SCRIPT>' */ if(*cp == '<') { /* XXX we can miss a </SCRIPT> spanning a block boundary */ if(i+8 <= l && !XP_STRNCASECMP(cp, "</SCRIPT", 8)) { new_markup = net_BeginColorHTMLTag(obj); } } break; case ABOUT_TO_BEGIN_TAG: /* we have seen the first '<' * once we see a non-whitespace character * we will be in the tag identifier */ if(*cp == '>') { StrAllocCopy(new_markup, END_TAG_NAME_MARKUP); tmp_markup = net_EndColorHTMLTag(obj); StrAllocCat(new_markup, tmp_markup); FREE_AND_CLEAR(tmp_markup); } else if(!XP_IS_SPACE(*cp)) { obj->state = IN_BEGIN_TAG; obj->tag_index = 0; obj->tag[obj->tag_index++] = *cp; if(*cp == '<') StrAllocCopy(new_markup, "<"); } break; case IN_BEGIN_TAG: /* go to the IN_TAG state when we see * the first whitespace */ if(XP_IS_SPACE(*cp)) { StrAllocCopy(new_markup, END_TAG_NAME_MARKUP); XP_SPRINTF(tiny_buf, "%c", *cp); StrAllocCat(new_markup, tiny_buf); obj->state = IN_TAG; obj->tag[obj->tag_index] = '\0'; obj->tag_type = pa_tokenize_tag(obj->tag); } else if(*cp == '>') { StrAllocCopy(new_markup, END_TAG_NAME_MARKUP); tmp_markup = net_EndColorHTMLTag(obj); StrAllocCat(new_markup, tmp_markup); FREE_AND_CLEAR(tmp_markup); } else if(*cp == '<') { /* protect ourselves from markup */ if(!obj->in_broken_html) { obj->in_broken_html = TRUE; StrAllocCopy(new_markup, BEGIN_BROKEN_ATTRIBUTE_MARKUP); StrAllocCat(new_markup, "<"); } else { StrAllocCopy(new_markup, "<"); } } else { if (obj->tag_index < MAXTAGLEN) obj->tag[obj->tag_index++] = *cp; } break; case IN_TAG: /* do nothing until you find a opening '=' or end '>' */ if(*cp == '=') { StrAllocCopy(new_markup, "="); StrAllocCat(new_markup, BEGIN_ATTRIBUTE_VALUE_MARKUP); obj->state = BEGIN_ATTRIBUTE_VALUE; } else if(*cp == '>') { new_markup = net_EndColorHTMLTag(obj); } else if(*cp == '<') { /* protect ourselves from markup */ StrAllocCopy(new_markup, "<"); } break; case BEGIN_ATTRIBUTE_VALUE: /* when we reach the first non-whitespace * we will enter the UNQUOTED or the QUOTED * ATTRIBUTE state */ if(!XP_IS_SPACE(*cp)) { if(*cp == '"') { obj->state = IN_QUOTED_ATTRIBUTE_VALUE; /* no need to jump to the quoted attr handler * since this char can't be a dangerous char */ } else { obj->state = IN_UNQUOTED_ATTRIBUTE_VALUE; /* need to jump to the unquoted attr handler * since this char can be a dangerous character */ goto unquoted_attribute_jump_point; } } else if(*cp == '>') { StrAllocCopy(new_markup, END_ATTRIBUTE_VALUE_MARKUP); tmp_markup = net_EndColorHTMLTag(obj); StrAllocCat(new_markup, tmp_markup); FREE_AND_CLEAR(tmp_markup); } else if(*cp == '<') { /* protect ourselves from markup */ StrAllocCopy(new_markup, "<"); } break; case IN_UNQUOTED_ATTRIBUTE_VALUE: unquoted_attribute_jump_point: /* do nothing until you find a whitespace */ if(XP_IS_SPACE(*cp)) { StrAllocCopy(new_markup, END_ATTRIBUTE_VALUE_MARKUP); XP_SPRINTF(tiny_buf, "%c", *cp); StrAllocCat(new_markup, tiny_buf); obj->state = IN_TAG; } else if(*cp == '>') { StrAllocCopy(new_markup, END_ATTRIBUTE_VALUE_MARKUP); tmp_markup = net_EndColorHTMLTag(obj); StrAllocCat(new_markup, tmp_markup); FREE_AND_CLEAR(tmp_markup); } else if(*cp == '<') { /* protect ourselves from markup */ StrAllocCopy(new_markup, "<"); } else if(*cp == '&') { /* protect ourselves from markup */ StrAllocCopy(new_markup, "&"); } break; case IN_QUOTED_ATTRIBUTE_VALUE: /* do nothing until you find a closing '"' */ if(*cp == '\"') { if(obj->in_broken_html) { StrAllocCopy(new_markup, END_BROKEN_ATTRIBUTE_MARKUP); obj->in_broken_html = FALSE; } StrAllocCat(new_markup, "\""); StrAllocCat(new_markup, END_ATTRIBUTE_VALUE_MARKUP); obj->state = IN_TAG; } else if(*cp == '<') { /* protect ourselves from markup */ StrAllocCopy(new_markup, "<"); } else if(*cp == '&') { /* protect ourselves from markup */ StrAllocCopy(new_markup, "&"); } else if(*cp == '>') { /* probably a broken attribute value */ if(!obj->in_broken_html) { obj->in_broken_html = TRUE; StrAllocCopy(new_markup, BEGIN_BROKEN_ATTRIBUTE_MARKUP); StrAllocCat(new_markup, ">"); } } break; case IN_COMMENT: /* do nothing until you find a closing '-->' */ if(!XP_STRNCMP(cp, "-->", 3)) { StrAllocCopy(new_markup, ">"); cp += 2; i += 2; StrAllocCat(new_markup, END_COMMENT_MARKUP); obj->state = IN_CONTENT; } else if(*cp == '<') { /* protect ourselves from markup */ StrAllocCopy(new_markup, "<"); } break; case IN_AMPERSAND_THINGY: /* do nothing until you find a ';' or space */ if(*cp == ';' || XP_IS_SPACE(*cp)) { XP_SPRINTF(tiny_buf, "%c", *cp); StrAllocCopy(new_markup, tiny_buf); StrAllocCat(new_markup, END_AMPERSAND_THINGY_MARKUP); obj->state = IN_CONTENT; } else if(*cp == '<') { /* protect ourselves from markup */ StrAllocCopy(new_markup, "<"); } break; default: XP_ASSERT(0); break; } if(new_markup) { /* push all the way up to but not including *cp */ status = (*obj->next_stream->put_block) (obj->next_stream, &s[last_output_point], i-last_output_point); last_output_point = i+1; if(status < 0) { FREE(new_markup); return(status); } /* add new markup */ status = (*obj->next_stream->put_block) (obj->next_stream, new_markup, XP_STRLEN(new_markup)); if(status < 0) { FREE(new_markup); return(status); } FREE_AND_CLEAR(new_markup); } } if(last_output_point < l) return((*obj->next_stream->put_block)(obj->next_stream, &s[last_output_point], (l-last_output_point))); else return(0); }
/* * Unlike hk_TagIndexToFunctionString (above) this function is passed * a PA_Tag inside extra, so it can even make the dynamic hook * name for UNKNOWN HTML tags. */ char * hk_TagFunctionString(const char *func_name, void *extra) { PA_Tag *tag; char *tag_text; char *total_name; tag_text = NULL; tag = (PA_Tag *)extra; if ((tag == NULL)||(func_name == NULL)) { return NULL; } if (tag->type == P_TEXT) { tag_text = XP_STRDUP("TEXT"); } else if (tag->type == P_UNKNOWN) { char *tptr; int32 cnt; tptr = (char *)tag->data; cnt = 0; while ((*tptr != '>')&&(!XP_IS_SPACE(*tptr))&& (cnt < tag->data_len)) { tptr++; cnt++; } if ((cnt > 0)&&(cnt < tag->data_len)) { char tchar; tchar = *tptr; *tptr = '\0'; tag_text = XP_STRDUP((char *)tag->data); *tptr = tchar; } else { tag_text = XP_STRDUP("UNKNOWN"); } } else { const char *tag_name; tag_name = PA_TagString((int32)tag->type); if (tag_name == NULL) { tag_text = XP_STRDUP("UNKNOWN"); } else { tag_text = XP_STRDUP(tag_name); } } if (tag_text != NULL) { int32 total_len; total_len = XP_STRLEN(func_name) + XP_STRLEN(tag_text) + 3; total_name = XP_ALLOC(total_len); if (total_name == NULL) { XP_FREE(tag_text); return NULL; } XP_STRCPY(total_name, tag_text); XP_STRCAT(total_name, func_name); return total_name; } else { return NULL; } }
nsresult nsXBLContentSink::FlushText(PRBool aReleaseTextNode) { if (mTextLength != 0) { const nsASingleFragmentString& text = Substring(mText, mText+mTextLength); if (mState == eXBL_InHandlers) { NS_ASSERTION(mBinding, "Must have binding here"); // Get the text and add it to the event handler. if (mSecondaryState == eXBL_InHandler) mHandler->AppendHandlerText(text); mTextLength = 0; return NS_OK; } else if (mState == eXBL_InImplementation) { NS_ASSERTION(mBinding, "Must have binding here"); if (mSecondaryState == eXBL_InConstructor || mSecondaryState == eXBL_InDestructor) { // Construct a method for the constructor/destructor. nsXBLProtoImplMethod* method; if (mSecondaryState == eXBL_InConstructor) method = mBinding->GetConstructor(); else method = mBinding->GetDestructor(); // Get the text and add it to the constructor/destructor. method->AppendBodyText(text); } else if (mSecondaryState == eXBL_InGetter || mSecondaryState == eXBL_InSetter) { // Get the text and add it to the getter/setter if (mSecondaryState == eXBL_InGetter) mProperty->AppendGetterText(text); else mProperty->AppendSetterText(text); } else if (mSecondaryState == eXBL_InBody) { // Get the text and add it to the method if (mMethod) mMethod->AppendBodyText(text); } else if (mSecondaryState == eXBL_InField) { // Get the text and add it to the method mField->AppendFieldText(text); } mTextLength = 0; return NS_OK; } nsIContent* content = GetCurrentContent(); if (content && (content->NodeInfo()->NamespaceEquals(kNameSpaceID_XBL) || (content->NodeInfo()->NamespaceEquals(kNameSpaceID_XUL) && content->Tag() != nsGkAtoms::label && content->Tag() != nsGkAtoms::description))) { PRBool isWS = PR_TRUE; if (mTextLength > 0) { const PRUnichar* cp = mText; const PRUnichar* end = mText + mTextLength; while (cp < end) { PRUnichar ch = *cp++; if (!XP_IS_SPACE(ch)) { isWS = PR_FALSE; break; } } } if (isWS && mTextLength > 0) { mTextLength = 0; // Make sure to drop the textnode, if any return nsXMLContentSink::FlushText(aReleaseTextNode); } } } return nsXMLContentSink::FlushText(aReleaseTextNode); }