blob: ec17e3e3a555094eb7b956f69dfc2305a6876e19 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#include "DFPlatform.h"
#include "CSSSelector.h"
#include "DFNameMap.h"
#include "DFString.h"
#include "DFDOM.h"
#include "DFCommon.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// StyleFamily //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////
StyleFamily StyleFamilyFromHTMLTag(Tag tag)
{
switch (tag) {
case HTML_H1:
case HTML_H2:
case HTML_H3:
case HTML_H4:
case HTML_H5:
case HTML_H6:
case HTML_P:
case HTML_DIV:
case HTML_BLOCKQUOTE:
case HTML_PRE:
return StyleFamilyParagraph;
case HTML_SPAN:
return StyleFamilyCharacter;
case HTML_TABLE:
return StyleFamilyTable;
case HTML_BODY:
case HTML_FIGURE:
case HTML_FIGCAPTION:
case HTML_CAPTION:
return StyleFamilySpecial;
default:
return StyleFamilyUnknown;
}
}
char *CSSMakeSelector(const char *elementName, const char *className)
{
assert(elementName != NULL);
if (className != NULL)
return DFFormatString("%s.%s",elementName,className);
else
return xstrdup(elementName);
}
char *CSSMakeTagSelector(Tag tag, const char *className)
{
const TagDecl *decl = DFBuiltinMapNameForTag(tag);
assert(decl != NULL);
return CSSMakeSelector(decl->localName,className);
}
char *CSSMakeNodeSelector(DFNode *node)
{
const char *elementName = DFTagName(node->doc,node->tag);
const char *className = DFGetAttribute(node,HTML_CLASS);
return CSSMakeSelector(elementName,className);
}
Tag CSSSelectorGetTag(const char *selector)
{
if (selector == NULL)
return 0;
char *elementName = CSSSelectorCopyElementName(selector);
Tag tag = DFBuiltinMapTagForName("http://www.w3.org/1999/xhtml",elementName);
free(elementName);
return tag;
}
static int findDotPos(const char *str)
{
for (int pos = 0; str[pos]; pos++) {
if (str[pos] == '.')
return pos;
}
return -1;
}
int CSSSelectorHasClassName(const char *selector)
{
if (selector == NULL)
return 0;
return (findDotPos(selector) >= 0);
}
char *CSSSelectorCopyElementName(const char *selector)
{
if (selector == NULL)
return NULL;
int dotPos = findDotPos(selector);
if (dotPos < 0)
return xstrdup(selector);
char *result = (char *)xmalloc(dotPos+1);
memcpy(result,selector,dotPos);
result[dotPos] = '\0';
return result;
}
char *CSSSelectorCopyClassName(const char *selector)
{
if (selector == NULL)
return NULL;
int dotPos = findDotPos(selector);
if (dotPos < 0)
return NULL;
int start = dotPos + 1;
int len = (int)strlen(selector) - start;
char *result = (char *)xmalloc(len+1);
memcpy(result,&selector[start],len);
result[len] = '\0';
return result;
}
int CSSSelectorHeadingLevel(const char *selector)
{
switch (CSSSelectorGetTag(selector)) {
case HTML_H1: return 1;
case HTML_H2: return 2;
case HTML_H3: return 3;
case HTML_H4: return 4;
case HTML_H5: return 5;
case HTML_H6: return 6;
default: return 0;
}
}
int CSSSelectorIsHeading(const char *selector)
{
switch (CSSSelectorGetTag(selector)) {
case HTML_H1:
case HTML_H2:
case HTML_H3:
case HTML_H4:
case HTML_H5:
case HTML_H6:
return 1;
default:
return 0;
}
}
StyleFamily CSSSelectorFamily(const char *selector)
{
if (selector == NULL)
return StyleFamilyUnknown;
return StyleFamilyFromHTMLTag(CSSSelectorGetTag(selector));
}