Option changed callback now implemented.
This commit is contained in:
parent
b91c728c81
commit
314690ad7f
96
src/config.c
96
src/config.c
|
@ -314,6 +314,7 @@ void TY_(InitConfig)( TidyDocImpl* doc )
|
||||||
|
|
||||||
void TY_(FreeConfig)( TidyDocImpl* doc )
|
void TY_(FreeConfig)( TidyDocImpl* doc )
|
||||||
{
|
{
|
||||||
|
doc->pConfigChangeCallback = NULL;
|
||||||
TY_(ResetConfigToDefault)( doc );
|
TY_(ResetConfigToDefault)( doc );
|
||||||
TY_(TakeConfigSnapshot)( doc );
|
TY_(TakeConfigSnapshot)( doc );
|
||||||
}
|
}
|
||||||
|
@ -348,6 +349,29 @@ const Bool TY_(getOptionIsList)( TidyOptionId optId )
|
||||||
return option->parser == ParseList;
|
return option->parser == ParseList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Bool OptionChangedValuesDiffer( ctmbstr a, ctmbstr b )
|
||||||
|
{
|
||||||
|
if ( a != b )
|
||||||
|
{
|
||||||
|
if ( a == NULL || b == NULL ) /* can't both be null at this point. */
|
||||||
|
return yes;
|
||||||
|
else
|
||||||
|
return TY_(tmbstrcmp)( a, b ) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return no;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PerformOptionChangedCallback( TidyDocImpl* doc, const TidyOptionImpl* option )
|
||||||
|
{
|
||||||
|
if ( doc->pConfigChangeCallback )
|
||||||
|
{
|
||||||
|
TidyDoc tdoc = tidyImplToDoc( doc );
|
||||||
|
TidyOption opt = tidyImplToOption( option );
|
||||||
|
doc->pConfigChangeCallback( tdoc, opt );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void FreeOptionValue( TidyDocImpl* doc, const TidyOptionImpl* option, TidyOptionValue* value )
|
static void FreeOptionValue( TidyDocImpl* doc, const TidyOptionImpl* option, TidyOptionValue* value )
|
||||||
{
|
{
|
||||||
if ( option->type == TidyString && value->p && value->p != option->pdflt )
|
if ( option->type == TidyString && value->p && value->p != option->pdflt )
|
||||||
|
@ -358,7 +382,18 @@ static void FreeOptionValue( TidyDocImpl* doc, const TidyOptionImpl* option, Tid
|
||||||
static void CopyOptionValue( TidyDocImpl* doc, const TidyOptionImpl* option,
|
static void CopyOptionValue( TidyDocImpl* doc, const TidyOptionImpl* option,
|
||||||
TidyOptionValue* oldval, const TidyOptionValue* newval )
|
TidyOptionValue* oldval, const TidyOptionValue* newval )
|
||||||
{
|
{
|
||||||
|
Bool fire_callback = no;
|
||||||
assert( oldval != NULL );
|
assert( oldval != NULL );
|
||||||
|
|
||||||
|
/* Compare the old and new values. */
|
||||||
|
if ( doc->pConfigChangeCallback )
|
||||||
|
{
|
||||||
|
if ( option->type == TidyString )
|
||||||
|
fire_callback = OptionChangedValuesDiffer( oldval->p, newval->p );
|
||||||
|
else
|
||||||
|
fire_callback = oldval->v != newval->v;
|
||||||
|
}
|
||||||
|
|
||||||
FreeOptionValue( doc, option, oldval );
|
FreeOptionValue( doc, option, oldval );
|
||||||
|
|
||||||
if ( option->type == TidyString )
|
if ( option->type == TidyString )
|
||||||
|
@ -370,22 +405,39 @@ static void CopyOptionValue( TidyDocImpl* doc, const TidyOptionImpl* option,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
oldval->v = newval->v;
|
oldval->v = newval->v;
|
||||||
|
|
||||||
|
if ( fire_callback )
|
||||||
|
PerformOptionChangedCallback( doc, option );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Bool SetOptionValue( TidyDocImpl* doc, TidyOptionId optId, ctmbstr val )
|
static Bool SetOptionValue( TidyDocImpl* doc, TidyOptionId optId, ctmbstr val )
|
||||||
{
|
{
|
||||||
const TidyOptionImpl* option = &option_defs[ optId ];
|
const TidyOptionImpl* option = &option_defs[ optId ];
|
||||||
|
Bool fire_callback = no;
|
||||||
Bool status = ( optId < N_TIDY_OPTIONS );
|
Bool status = ( optId < N_TIDY_OPTIONS );
|
||||||
|
|
||||||
if ( status )
|
if ( status )
|
||||||
{
|
{
|
||||||
assert( option->id == optId && option->type == TidyString );
|
assert( option->id == optId && option->type == TidyString );
|
||||||
|
|
||||||
|
/* Compare the old and new values. */
|
||||||
|
if ( doc->pConfigChangeCallback )
|
||||||
|
{
|
||||||
|
TidyOptionValue* oldval = &(doc->config.value[ optId ]);
|
||||||
|
fire_callback = OptionChangedValuesDiffer( oldval->p, val );
|
||||||
|
}
|
||||||
|
|
||||||
FreeOptionValue( doc, option, &doc->config.value[ optId ] );
|
FreeOptionValue( doc, option, &doc->config.value[ optId ] );
|
||||||
if ( TY_(tmbstrlen)(val)) /* Issue #218 - ONLY if it has LENGTH! */
|
if ( TY_(tmbstrlen)(val)) /* Issue #218 - ONLY if it has LENGTH! */
|
||||||
doc->config.value[ optId ].p = TY_(tmbstrdup)( doc->allocator, val );
|
doc->config.value[ optId ].p = TY_(tmbstrdup)( doc->allocator, val );
|
||||||
else
|
else
|
||||||
doc->config.value[ optId ].p = 0; /* should already be zero, but to be sure... */
|
doc->config.value[ optId ].p = 0; /* should already be zero, but to be sure... */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( fire_callback )
|
||||||
|
PerformOptionChangedCallback( doc, option );
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,13 +464,25 @@ ctmbstr TY_(GetPickListLabelForPick)( TidyOptionId optId, uint pick )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void SetOptionInteger( TidyDocImpl* doc, TidyOptionId optId, ulong val )
|
||||||
|
{
|
||||||
|
const TidyOptionImpl* option = &option_defs[ optId ];
|
||||||
|
ulong* optVal = &(doc->config.value[ optId ].v);
|
||||||
|
Bool fire_callback = doc->pConfigChangeCallback && *optVal != val;
|
||||||
|
|
||||||
|
*optVal = val;
|
||||||
|
|
||||||
|
if ( fire_callback )
|
||||||
|
PerformOptionChangedCallback( doc, option );
|
||||||
|
}
|
||||||
|
|
||||||
Bool TY_(SetOptionInt)( TidyDocImpl* doc, TidyOptionId optId, ulong val )
|
Bool TY_(SetOptionInt)( TidyDocImpl* doc, TidyOptionId optId, ulong val )
|
||||||
{
|
{
|
||||||
Bool status = ( optId < N_TIDY_OPTIONS );
|
Bool status = ( optId < N_TIDY_OPTIONS );
|
||||||
if ( status )
|
if ( status )
|
||||||
{
|
{
|
||||||
assert( option_defs[ optId ].type == TidyInteger );
|
assert( option_defs[ optId ].type == TidyInteger );
|
||||||
doc->config.value[ optId ].v = val;
|
SetOptionInteger( doc, optId, val );
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -430,7 +494,7 @@ Bool TY_(SetOptionBool)( TidyDocImpl* doc, TidyOptionId optId, Bool val )
|
||||||
if ( status )
|
if ( status )
|
||||||
{
|
{
|
||||||
assert( option_defs[ optId ].type == TidyBoolean );
|
assert( option_defs[ optId ].type == TidyBoolean );
|
||||||
doc->config.value[ optId ].v = val;
|
SetOptionInteger( doc, optId, (ulong)val );
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -1247,6 +1311,18 @@ Bool ParseList( TidyDocImpl* doc, const TidyOptionImpl* option )
|
||||||
tmbchar buf[1024];
|
tmbchar buf[1024];
|
||||||
uint i = 0, nItems = 0;
|
uint i = 0, nItems = 0;
|
||||||
uint c;
|
uint c;
|
||||||
|
TidyConfigChangeCallback callback = doc->pConfigChangeCallback;
|
||||||
|
tmbstr oldbuff = NULL;
|
||||||
|
|
||||||
|
/* Handle comparing before and after for the config change callback.
|
||||||
|
We have do handle this manually, because otherwise TY_(DeclareListItem)
|
||||||
|
would fire a callback for EVERY list item being added. */
|
||||||
|
doc->pConfigChangeCallback = NULL;
|
||||||
|
if ( callback )
|
||||||
|
{
|
||||||
|
TidyOptionValue* oldval = &(doc->config.value[ option->id ]);
|
||||||
|
oldbuff = TY_(tmbstrdup)( doc->allocator, oldval->p );
|
||||||
|
}
|
||||||
|
|
||||||
SetOptionValue( doc, option->id, NULL );
|
SetOptionValue( doc, option->id, NULL );
|
||||||
|
|
||||||
|
@ -1302,6 +1378,22 @@ Bool ParseList( TidyDocImpl* doc, const TidyOptionImpl* option )
|
||||||
if ( i > 0 )
|
if ( i > 0 )
|
||||||
TY_(DeclareListItem)( doc, option, buf );
|
TY_(DeclareListItem)( doc, option, buf );
|
||||||
|
|
||||||
|
/* If there's a callback, compare the old and new values, and fire
|
||||||
|
the callback appropriately. */
|
||||||
|
if ( callback )
|
||||||
|
{
|
||||||
|
TidyOptionValue* val = &(doc->config.value[ option->id ]);
|
||||||
|
Bool fire_callback = OptionChangedValuesDiffer( val->p, oldbuff);
|
||||||
|
|
||||||
|
doc->pConfigChangeCallback = callback;
|
||||||
|
|
||||||
|
if ( oldbuff )
|
||||||
|
TidyFree( doc->allocator, oldbuff );
|
||||||
|
|
||||||
|
if ( fire_callback )
|
||||||
|
PerformOptionChangedCallback( doc, option );
|
||||||
|
}
|
||||||
|
|
||||||
return ( nItems > 0 );
|
return ( nItems > 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1434,6 +1434,9 @@ static ctmbstr integrity = "\nPanic - tree has lost its integrity\n";
|
||||||
int TY_(DocParseStream)( TidyDocImpl* doc, StreamIn* in )
|
int TY_(DocParseStream)( TidyDocImpl* doc, StreamIn* in )
|
||||||
{
|
{
|
||||||
Bool xmlIn = cfgBool( doc, TidyXmlTags );
|
Bool xmlIn = cfgBool( doc, TidyXmlTags );
|
||||||
|
TidyConfigChangeCallback callback = doc->pConfigChangeCallback;
|
||||||
|
|
||||||
|
doc->pConfigChangeCallback = NULL;
|
||||||
int bomEnc;
|
int bomEnc;
|
||||||
|
|
||||||
assert( doc != NULL && in != NULL );
|
assert( doc != NULL && in != NULL );
|
||||||
|
@ -1488,6 +1491,8 @@ int TY_(DocParseStream)( TidyDocImpl* doc, StreamIn* in )
|
||||||
}
|
}
|
||||||
|
|
||||||
doc->docIn = NULL;
|
doc->docIn = NULL;
|
||||||
|
doc->pConfigChangeCallback = callback;
|
||||||
|
|
||||||
return tidyDocStatus( doc );
|
return tidyDocStatus( doc );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2022,13 +2027,18 @@ int tidyDocCleanAndRepair( TidyDocImpl* doc )
|
||||||
Bool wantNameAttr = cfgBool( doc, TidyAnchorAsName );
|
Bool wantNameAttr = cfgBool( doc, TidyAnchorAsName );
|
||||||
Bool mergeEmphasis = cfgBool( doc, TidyMergeEmphasis );
|
Bool mergeEmphasis = cfgBool( doc, TidyMergeEmphasis );
|
||||||
Node* node;
|
Node* node;
|
||||||
|
TidyConfigChangeCallback callback = doc->pConfigChangeCallback;
|
||||||
|
doc->pConfigChangeCallback = NULL;
|
||||||
|
|
||||||
#if defined(ENABLE_DEBUG_LOG)
|
#if defined(ENABLE_DEBUG_LOG)
|
||||||
SPRTF("All nodes BEFORE clean and repair\n");
|
SPRTF("All nodes BEFORE clean and repair\n");
|
||||||
dbg_show_all_nodes( doc, &doc->root, 0 );
|
dbg_show_all_nodes( doc, &doc->root, 0 );
|
||||||
#endif
|
#endif
|
||||||
if (tidyXmlTags)
|
if (tidyXmlTags)
|
||||||
|
{
|
||||||
|
doc->pConfigChangeCallback = callback;
|
||||||
return tidyDocStatus( doc );
|
return tidyDocStatus( doc );
|
||||||
|
}
|
||||||
|
|
||||||
/* Issue #567 - move style elements from body to head */
|
/* Issue #567 - move style elements from body to head */
|
||||||
TY_(CleanStyle)(doc, &doc->root);
|
TY_(CleanStyle)(doc, &doc->root);
|
||||||
|
@ -2145,6 +2155,8 @@ int tidyDocCleanAndRepair( TidyDocImpl* doc )
|
||||||
SPRTF("All nodes AFTER clean and repair\n");
|
SPRTF("All nodes AFTER clean and repair\n");
|
||||||
dbg_show_all_nodes( doc, &doc->root, 0 );
|
dbg_show_all_nodes( doc, &doc->root, 0 );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
doc->pConfigChangeCallback = callback;
|
||||||
return tidyDocStatus( doc );
|
return tidyDocStatus( doc );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2185,6 +2197,8 @@ int tidyDocSaveStream( TidyDocImpl* doc, StreamOut* out )
|
||||||
Bool escapeCDATA = cfgBool(doc, TidyEscapeCdata);
|
Bool escapeCDATA = cfgBool(doc, TidyEscapeCdata);
|
||||||
Bool ppWithTabs = cfgBool(doc, TidyPPrintTabs);
|
Bool ppWithTabs = cfgBool(doc, TidyPPrintTabs);
|
||||||
TidyAttrSortStrategy sortAttrStrat = cfg(doc, TidySortAttributes);
|
TidyAttrSortStrategy sortAttrStrat = cfg(doc, TidySortAttributes);
|
||||||
|
TidyConfigChangeCallback callback = doc->pConfigChangeCallback;
|
||||||
|
doc->pConfigChangeCallback = NULL;
|
||||||
|
|
||||||
if (ppWithTabs)
|
if (ppWithTabs)
|
||||||
TY_(PPrintTabs)();
|
TY_(PPrintTabs)();
|
||||||
|
@ -2241,6 +2255,8 @@ int tidyDocSaveStream( TidyDocImpl* doc, StreamOut* out )
|
||||||
}
|
}
|
||||||
|
|
||||||
TY_(ResetConfigToSnapshot)( doc );
|
TY_(ResetConfigToSnapshot)( doc );
|
||||||
|
doc->pConfigChangeCallback = callback;
|
||||||
|
|
||||||
return tidyDocStatus( doc );
|
return tidyDocStatus( doc );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue