/* * * (c) COPYRIGHT MIT and INRIA, 1996. * Please first read the full copyright statement in file COPYRIGHT. * */ /* included headers */ #include "thot_gui.h" #include "thot_sys.h" #include "appaction.h" #include "application.h" #include "attribute.h" #include "document.h" #include "fileaccess.h" #include "genericdriver.h" #include "interface.h" #include "message.h" #include "pschema.h" #include "presentdriver.h" #include "thotmsg.h" #include "view.h" #include "StyleCss.h" #include "CssMsgTable.h" #include "UIcss.h" #include "StyleRules_f.h" #include "StyleCss_f.h" #include "StyleParser_f.h" #include "UIcss_f.h" extern CSSInfoPtr ListCSS[]; /* list of CSSInfos per doc */ extern int CssMsgTable; /* message table */ extern Document currentDocument; /* id of current document */ /************************************************************************* * * * CSS RULES RELATED FUNCTIONS * * * *************************************************************************/ /*---------------------------------------------------------------------- CollapseRuleStrings : Makes a string containing a CSS rule, with a selector and an attribute. params : selector : string beginning with a selector attrstr : string beginning with an attribute. returns : the created string containing the rule. ----------------------------------------------------------------------*/ #ifdef __STDC__ char *CollapseRuleStrings(char *selector, char *attrstr) #else char *CollapseRuleStrings(selector, attrstr) char *selector; char *attrstr; #endif { int size; char *rule, *rulefill; /* final rule */ char *sel, *sel2, *attr, *attr2; /* to scan strings */ size = 0; sel = sel2 = selector; attr = attr2 = attrstr; /* scanning selector */ while ((*sel != 0 ) && (*sel != ',') && (*sel != '.') && (*sel != ':') && (*sel != '{')) { sel++; size++; } /* scanning attribute */ while ((*attr != 0 ) && (*attr != ';') && (*attr != '}')) { attr++; size++; } size += 3; /* for '{', '}' and '\0' */ rule = rulefill = TtaGetMemory(size); if (rule != NULL) { /* copying rule */ while (sel2 < sel) *rulefill++ = *(sel2 ++); *rulefill++ = '{'; while (attr2 < attr) *rulefill++ = *attr2++; *rulefill++ = '}'; *rulefill++ = '\0'; #ifdef DEBUG_CSS fprintf (stderr, "CollapseRuleStrings: rule is [%s]\n", rule); #endif } else { TtaDisplaySimpleMessage (INFO, CssMsgTable, CSS_OUT_OF_MEMORY); #ifdef DEBUG_CSS fprintf (stderr, "CollapseRuleStrings: rule isn't made: no memory left\n"); #endif } return (rule); } /*---------------------------------------------------------------------- DeleteRule : deletes a rule from the sorted rules list of a CSSInfo, and "un-applies" it from the document. If the rule isn't in the list, simply removes it from memory. params : rule : ptr on the rule to delete css : the target CSSInfo doc : the document on which the rule is applied ----------------------------------------------------------------------*/ #ifdef __STDC__ void DeleteRule(CSSRulePtr rule, CSSInfoPtr css, Document doc) #else void DeleteRule(rule, css, doc) CSSRulePtr rule; CSSInfoPtr css; Document doc; #endif { CSSRulePtr prev, curr; if (rule == NULL) { #ifdef DEBUG_CSS fprintf (stderr, "DeleteRule: given rule is null\n"); #endif return; } #ifdef DEBUG_CSS else if (css == NULL) fprintf (stderr, "DeleteRule: given css is null\n"); else if (css->ruleslist == NULL) fprintf (stderr, "DeleteRule: given css's rules list is null\n"); #endif /* removing rule from list */ if ((css != NULL) && (css->ruleslist != NULL)) { if (rule == css->ruleslist) { curr = css->ruleslist; css->ruleslist = css->ruleslist->nextrule; } else { prev = curr = css->ruleslist; while ((curr != NULL) && (curr != rule)) { prev = curr; curr = curr->nextrule; } if (curr != NULL) prev->nextrule = curr->nextrule; } if (curr != NULL) { /* curr is the searched rule. "un-applying".*/ SetHTMLStyleParserDestructiveMode(TRUE); StyleParser(curr->rule, doc, FALSE, css); SetHTMLStyleParserDestructiveMode(FALSE); } #ifdef DEBUG_CSS else fprintf (stderr, "DeleteRule: given rule isn't in list\n"); #endif } /* removing rule from memory */ FreeRule(rule); } /*---------------------------------------------------------------------- FreeRule : removes the given rule from memory params : rule : ptr on the rule to remove ----------------------------------------------------------------------*/ #ifdef __STDC__ void FreeRule(CSSRulePtr rule) #else void FreeRule(rule) CSSRulePtr rule; #endif { if (rule != NULL) { if (rule->rule != NULL) TtaFreeMemory(rule->rule); TtaFreeMemory(rule); } #ifdef DEBUG_CSS else fprintf (stderr, "DeleteRule: given rule is null\n"); #endif } /*---------------------------------------------------------------------- InsertRule : inserts a rule in the sorted rules list of the given CSSInfo. params : rule : ptr on the rule to add css : the target CSSInfo ----------------------------------------------------------------------*/ #ifdef __STDC__ void InsertRule(CSSRulePtr rule, CSSInfoPtr css) #else void InsertRule(rule, css) CSSRulePtr rule; CSSInfoPtr css; #endif { CSSRulePtr prev, curr; if (rule == NULL) { #ifdef DEBUG_CSS fprintf (stderr, "InsertRule: given rule is null\n"); #endif return; } else if (rule->cssSSchema == NULL) { #ifdef DEBUG_CSS fprintf (stderr, "InsertRule: given rule's schema is null\n"); #endif return; } else if (css == NULL) { #ifdef DEBUG_CSS fprintf (stderr, "InsertRule: given css is null\n"); #endif return; } if (css->ruleslist == NULL) { css->ruleslist = rule; rule->nextrule = NULL; } else { prev = curr = css->ruleslist; while ((curr != NULL) && (curr->cssSSchema != rule->cssSSchema) && (curr != rule)) { prev = curr; curr = curr->nextrule; } while ((curr != NULL) && (curr->cssSSchema == rule->cssSSchema) && (curr->eltype <= rule->eltype) && (curr != rule)) { prev = curr; curr = curr->nextrule; } if (rule == curr) { #ifdef DEBUG_CSS fprintf (stderr, "InsertRule: rule already in list\n"); #endif } else if (curr == css->ruleslist) { /* must be placed ahead */ rule->nextrule = css->ruleslist; css->ruleslist = rule; } else { /* must be placed after prev */ rule->nextrule = prev->nextrule; prev->nextrule = rule; } } } /*---------------------------------------------------------------------- InsertBadRule : inserts a rule in the bad rules list of the given CSSInfo. params : rule : ptr on the rule to add css : the target CSSInfo ----------------------------------------------------------------------*/ #ifdef __STDC__ void InsertBadRule(CSSRulePtr rule, CSSInfoPtr css) #else void InsertBadRule(rule, css) CSSRulePtr rule; CSSInfoPtr css; #endif { CSSRulePtr curr; if (rule == NULL) { #ifdef DEBUG_CSS fprintf (stderr, "InsertRule: given rule is null\n"); #endif return; } else if (css == NULL) { #ifdef DEBUG_CSS fprintf (stderr, "InsertRule: given css is null\n"); #endif return; } if (css->badruleslist == NULL) { css->badruleslist = rule; rule->nextrule = NULL; } else { curr = css->badruleslist; while ((curr->nextrule != NULL) && (curr != rule)) curr = curr->nextrule; if (rule != curr) { curr->nextrule = rule; rule->nextrule = NULL; } #ifdef DEBUG_CSS else fprintf (stderr, "InsertRule: bad rule already in list\n"); #endif } } /*---------------------------------------------------------------------- NewRule : creates a new CSSRule. returns : a ptr on the CSSRule created ----------------------------------------------------------------------*/ #ifdef __STDC__ CSSRulePtr NewRule (void) #else CSSRulePtr NewRule () #endif { CSSRulePtr rule; rule = (CSSRulePtr) TtaGetMemory (sizeof (CSSRule)); /* inits */ rule->nextrule = NULL; rule->rule = NULL; rule->cssSSchema = NULL; rule->eltype = 0; return (rule); } /*---------------------------------------------------------------------- CopyRule : creates a copy of the given CSSRule. params : rule : the rule to duplicate. returns : a ptr on the CSSRule created NOTE : the rule isn't inserted in any rule list, so its nextrule pointer is left as NULL. ----------------------------------------------------------------------*/ #ifdef __STDC__ CSSRulePtr CopyRule (CSSRulePtr rule) #else CSSRulePtr CopyRule (rule) CSSRulePtr rule; #endif { CSSRulePtr newrule; newrule = (CSSRulePtr) TtaGetMemory (sizeof (CSSRule)); /* inits */ newrule->nextrule = NULL; newrule->rule = TtaStrdup(rule->rule); newrule->cssSSchema = rule->cssSSchema; newrule->eltype = rule->eltype; return (newrule); } /*---------------------------------------------------------------------- MakeRuleNamesList : recursive function that bulids the list of rules names params : rule : first rule of sub-list scan : ptr on built string (where to append names) nb : nb of names copied size : size of previous css names returns : built string, number of names is modified. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *MakeRuleNamesList(CSSRulePtr rule, char **scan, int *nb, int size) #else static char *MakeRuleNamesList(rule, scan, nb, size) CSSRulePtr rule; char *scan; int *nb; int size; #endif { char *names, *namescan, *myscan; if (rule->nextrule == NULL) { /* alloc memory */ myscan = names = TtaGetMemory(size + strlen(rule->rule) + 1); if (myscan == NULL) { TtaDisplaySimpleMessage (INFO, CssMsgTable, CSS_OUT_OF_MEMORY); *nb=0; return (NULL); } /* copy name*/ namescan = rule->rule; while ((*myscan++ = *namescan++)!= EOS); *nb=1; } else /* not last */ { names = MakeRuleNamesList(rule->nextrule, scan, nb, size + strlen(rule->rule) + 1); if (names == NULL) return (NULL); namescan = rule->rule; myscan = *scan; while ((*myscan++ = *namescan++)!= EOS); (*nb)++; } *scan = myscan; return names; } /*---------------------------------------------------------------------- GetRulesNames : collapse the name of every rules of a CSS in a string, using '\0' as separator, and return the number of names in the generated string. params : css : the document whose css names are listed. names : ptr on the string that will contain the names returns : number of names listed ----------------------------------------------------------------------*/ #ifdef __STDC__ int GetRulesNames(CSSInfoPtr css, char **names) #else int GetRulesNames(css, names) char **names; CSSInfoPtr css; #endif { int nbnames; char *scan; if (css == NULL) { #ifdef DEBUG_CSS fprintf (stderr, "GetRulesName: The css is null.\n"); #endif *names = NULL; return (0); } if (css->ruleslist == NULL) { #ifdef DEBUG_CSS fprintf (stderr, "GetRulesName: The list of rules is empty.\n"); #endif *names = NULL; return (0); } *names = MakeRuleNamesList(css->ruleslist, &scan, &nbnames, 0); return (nbnames); } /*---------------------------------------------------------------------- GetRuleFromName : search for a rule in the given CSS. params : text : string containing the declaration of the searched rule css : the CSS that may contain the rule. returns : a ptr on the rule, NULL if not found ----------------------------------------------------------------------*/ #ifdef __STDC__ CSSRulePtr GetRuleFromName(char *text, CSSInfoPtr css) #else CSSRulePtr GetRuleFromName(text, css) char *text; CSSInfoPtr css; #endif { CSSRulePtr rule=css->ruleslist; if (css == NULL) return NULL; if (text == NULL) return (NULL); while ((rule !=NULL) && (strcmp (rule->rule, text))) rule = rule->nextrule; return (rule); }