#include "config.h"
#include "MediaQuery.h"
#include "MediaQueryExp.h"
#include <wtf/NonCopyingSort.h>
#include <wtf/text/StringBuilder.h>
namespace WebCore {
String MediaQuery::serialize() const
{
StringBuilder result;
if (!m_ignored) {
switch (m_restrictor) {
case MediaQuery::Only:
result.append("only ");
break;
case MediaQuery::Not:
result.append("not ");
break;
case MediaQuery::None:
break;
}
if (m_expressions->isEmpty()) {
result.append(m_mediaType);
return result.toString();
}
if (m_mediaType != "all" || m_restrictor != None) {
result.append(m_mediaType);
result.append(" and ");
}
result.append(m_expressions->at(0)->serialize());
for (size_t i = 1; i < m_expressions->size(); ++i) {
result.append(" and ");
result.append(m_expressions->at(i)->serialize());
}
} else {
result.append("not all");
}
return result.toString();
}
static bool expressionCompare(const OwnPtr<MediaQueryExp>& a, const OwnPtr<MediaQueryExp>& b)
{
return codePointCompare(a->serialize(), b->serialize()) < 0;
}
MediaQuery::MediaQuery(Restrictor r, const String& mediaType, PassOwnPtr<Vector<OwnPtr<MediaQueryExp> > > exprs)
: m_restrictor(r)
, m_mediaType(mediaType.lower())
, m_expressions(exprs)
, m_ignored(false)
{
if (!m_expressions) {
m_expressions = adoptPtr(new Vector<OwnPtr<MediaQueryExp> >);
return;
}
nonCopyingSort(m_expressions->begin(), m_expressions->end(), expressionCompare);
String key;
for (int i = m_expressions->size() - 1; i >= 0; --i) {
if (!m_ignored)
m_ignored = !m_expressions->at(i)->isValid();
if (m_expressions->at(i)->serialize() == key)
m_expressions->remove(i);
else
key = m_expressions->at(i)->serialize();
}
}
MediaQuery::MediaQuery(const MediaQuery& o)
: m_restrictor(o.m_restrictor)
, m_mediaType(o.m_mediaType)
, m_expressions(adoptPtr(new Vector<OwnPtr<MediaQueryExp> >(o.m_expressions->size())))
, m_ignored(o.m_ignored)
, m_serializationCache(o.m_serializationCache)
{
for (unsigned i = 0; i < m_expressions->size(); ++i)
(*m_expressions)[i] = o.m_expressions->at(i)->copy();
}
MediaQuery::~MediaQuery()
{
}
bool MediaQuery::operator==(const MediaQuery& other) const
{
return cssText() == other.cssText();
}
String MediaQuery::cssText() const
{
if (m_serializationCache.isNull())
const_cast<MediaQuery*>(this)->m_serializationCache = serialize();
return m_serializationCache;
}
}