htmltag.cpp

来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 534 行 · 第 1/2 页

CPP
534
字号
    if (source[i-1] != wxT('>'))
    {
        #define IS_WHITE(c) (c == wxT(' ') || c == wxT('\r') || \
                             c == wxT('\n') || c == wxT('\t'))
        wxString pname, pvalue;
        wxChar quote;
        enum
        {
            ST_BEFORE_NAME = 1,
            ST_NAME,
            ST_BEFORE_EQ,
            ST_BEFORE_VALUE,
            ST_VALUE
        } state;

        quote = 0;
        state = ST_BEFORE_NAME;
        while (i < end_pos)
        {
            c = source[i++];

            if (c == wxT('>') && !(state == ST_VALUE && quote != 0))
            {
                if (state == ST_BEFORE_EQ || state == ST_NAME)
                {
                    m_ParamNames.Add(pname);
                    m_ParamValues.Add(wxEmptyString);
                }
                else if (state == ST_VALUE && quote == 0)
                {
                    m_ParamNames.Add(pname);
                    if (entParser)
                        m_ParamValues.Add(entParser->Parse(pvalue));
                    else
                        m_ParamValues.Add(pvalue);
                }
                break;
            }
            switch (state)
            {
                case ST_BEFORE_NAME:
                    if (!IS_WHITE(c))
                    {
                        pname = c;
                        state = ST_NAME;
                    }
                    break;
                case ST_NAME:
                    if (IS_WHITE(c))
                        state = ST_BEFORE_EQ;
                    else if (c == wxT('='))
                        state = ST_BEFORE_VALUE;
                    else
                        pname << c;
                    break;
                case ST_BEFORE_EQ:
                    if (c == wxT('='))
                        state = ST_BEFORE_VALUE;
                    else if (!IS_WHITE(c))
                    {
                        m_ParamNames.Add(pname);
                        m_ParamValues.Add(wxEmptyString);
                        pname = c;
                        state = ST_NAME;
                    }
                    break;
                case ST_BEFORE_VALUE:
                    if (!IS_WHITE(c))
                    {
                        if (c == wxT('"') || c == wxT('\''))
                            quote = c, pvalue = wxEmptyString;
                        else
                            quote = 0, pvalue = c;
                        state = ST_VALUE;
                    }
                    break;
                case ST_VALUE:
                    if ((quote != 0 && c == quote) ||
                        (quote == 0 && IS_WHITE(c)))
                    {
                        m_ParamNames.Add(pname);
                        if (quote == 0)
                        {
                            // VS: backward compatibility, no real reason,
                            //     but wxHTML code relies on this... :(
                            pvalue.MakeUpper();
                        }
                        if (entParser)
                            m_ParamValues.Add(entParser->Parse(pvalue));
                        else
                            m_ParamValues.Add(pvalue);
                        state = ST_BEFORE_NAME;
                    }
                    else
                        pvalue << c;
                    break;
            }
        }

        #undef IS_WHITE
    }
    m_Begin = i;

    cache->QueryTag(pos, &m_End1, &m_End2);
    if (m_End1 > end_pos) m_End1 = end_pos;
    if (m_End2 > end_pos) m_End2 = end_pos;
}

wxHtmlTag::~wxHtmlTag()
{
    wxHtmlTag *t1, *t2;
    t1 = m_FirstChild;
    while (t1)
    {
        t2 = t1->GetNextSibling();
        delete t1;
        t1 = t2;
    }
}

bool wxHtmlTag::HasParam(const wxString& par) const
{
    return (m_ParamNames.Index(par, false) != wxNOT_FOUND);
}

wxString wxHtmlTag::GetParam(const wxString& par, bool with_commas) const
{
    int index = m_ParamNames.Index(par, false);
    if (index == wxNOT_FOUND)
        return wxEmptyString;
    if (with_commas)
    {
        // VS: backward compatibility, seems to be never used by wxHTML...
        wxString s;
        s << wxT('"') << m_ParamValues[index] << wxT('"');
        return s;
    }
    else
        return m_ParamValues[index];
}

int wxHtmlTag::ScanParam(const wxString& par,
                         const wxChar *format,
                         void *param) const
{
    wxString parval = GetParam(par);
    return wxSscanf(parval, format, param);
}

bool wxHtmlTag::GetParamAsColour(const wxString& par, wxColour *clr) const
{
    wxString str = GetParam(par);

    if (str.empty()) return false;
    if (str.GetChar(0) == wxT('#'))
    {
        unsigned long tmp;
        if (ScanParam(par, wxT("#%lX"), &tmp) != 1)
            return false;
        *clr = wxColour((unsigned char)((tmp & 0xFF0000) >> 16),
                        (unsigned char)((tmp & 0x00FF00) >> 8),
                        (unsigned char)(tmp & 0x0000FF));
        return true;
    }
    else
    {
        // Handle colours defined in HTML 4.0:
        #define HTML_COLOUR(name,r,g,b)                 \
            if (str.IsSameAs(wxT(name), false))         \
                { *clr = wxColour(r,g,b); return true; }
        HTML_COLOUR("black",   0x00,0x00,0x00)
        HTML_COLOUR("silver",  0xC0,0xC0,0xC0)
        HTML_COLOUR("gray",    0x80,0x80,0x80)
        HTML_COLOUR("white",   0xFF,0xFF,0xFF)
        HTML_COLOUR("maroon",  0x80,0x00,0x00)
        HTML_COLOUR("red",     0xFF,0x00,0x00)
        HTML_COLOUR("purple",  0x80,0x00,0x80)
        HTML_COLOUR("fuchsia", 0xFF,0x00,0xFF)
        HTML_COLOUR("green",   0x00,0x80,0x00)
        HTML_COLOUR("lime",    0x00,0xFF,0x00)
        HTML_COLOUR("olive",   0x80,0x80,0x00)
        HTML_COLOUR("yellow",  0xFF,0xFF,0x00)
        HTML_COLOUR("navy",    0x00,0x00,0x80)
        HTML_COLOUR("blue",    0x00,0x00,0xFF)
        HTML_COLOUR("teal",    0x00,0x80,0x80)
        HTML_COLOUR("aqua",    0x00,0xFF,0xFF)
        #undef HTML_COLOUR
    }

    return false;
}

bool wxHtmlTag::GetParamAsInt(const wxString& par, int *clr) const
{
    if (!HasParam(par)) return false;
    long i;
    bool succ = GetParam(par).ToLong(&i);
    *clr = (int)i;
    return succ;
}

wxString wxHtmlTag::GetAllParams() const
{
    // VS: this function is for backward compatibility only,
    //     never used by wxHTML
    wxString s;
    size_t cnt = m_ParamNames.GetCount();
    for (size_t i = 0; i < cnt; i++)
    {
        s << m_ParamNames[i];
        s << wxT('=');
        if (m_ParamValues[i].Find(wxT('"')) != wxNOT_FOUND)
            s << wxT('\'') << m_ParamValues[i] << wxT('\'');
        else
            s << wxT('"') << m_ParamValues[i] << wxT('"');
    }
    return s;
}

wxHtmlTag *wxHtmlTag::GetFirstSibling() const
{
    if (m_Parent)
        return m_Parent->m_FirstChild;
    else
    {
        wxHtmlTag *cur = (wxHtmlTag*)this;
        while (cur->m_Prev)
            cur = cur->m_Prev;
        return cur;
    }
}

wxHtmlTag *wxHtmlTag::GetLastSibling() const
{
    if (m_Parent)
        return m_Parent->m_LastChild;
    else
    {
        wxHtmlTag *cur = (wxHtmlTag*)this;
        while (cur->m_Next)
            cur = cur->m_Next;
        return cur;
    }
}

wxHtmlTag *wxHtmlTag::GetNextTag() const
{
    if (m_FirstChild) return m_FirstChild;
    if (m_Next) return m_Next;
    wxHtmlTag *cur = m_Parent;
    if (!cur) return NULL;
    while (cur->m_Parent && !cur->m_Next)
        cur = cur->m_Parent;
    return cur->m_Next;
}

#if WXWIN_COMPATIBILITY_2_2

bool wxHtmlTag::IsEnding() const
{
    return false;
}

#endif // WXWIN_COMPATIBILITY_2_2

#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?