blob: 594570b035b6a5799cae0e68e22bcf54c08f3cff [file] [log] [blame]
/*
* Copyright 2011 Google Inc.
*
* Licensed 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.
*/
// Author: morlovich@google.com (Maksim Orlovich)
#include "net/instaweb/rewriter/public/css_resource_slot.h"
#include <cstddef>
#include <set>
#include <utility>
#include <vector>
#include "base/logging.h"
#include "net/instaweb/rewriter/public/resource.h"
#include "net/instaweb/rewriter/public/rewrite_options.h"
#include "net/instaweb/rewriter/public/server_context.h"
#include "net/instaweb/rewriter/public/url_left_trim_filter.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/kernel/http/google_url.h"
#include "util/utf8/public/unicodetext.h"
#include "webutil/css/value.h"
namespace net_instaweb {
CssResourceSlot::CssResourceSlot(const ResourcePtr& resource,
const GoogleUrl& trim_url,
const RewriteOptions* options,
Css::Values* values,
size_t value_index)
: ResourceSlot(resource),
values_(values),
value_index_(value_index),
url_relativity_(GoogleUrl::FindRelativity(UnicodeTextToUTF8(
values->at(value_index)->GetStringValue()))),
options_(options) {
trim_url_.Reset(trim_url);
}
CssResourceSlot::~CssResourceSlot() {
}
void CssResourceSlot::Render() {
if (disable_rendering() || preserve_urls()) {
return; // nothing done here.
} else {
GoogleString url = resource()->url();
#ifndef NDEBUG
// Check that it's an absolute URL.
GoogleUrl gurl(url);
DCHECK(gurl.IsWebValid());
#endif // NDEBUG
// TODO(sligocki): Remove URL trimming code from CSS path?
GoogleString trimmed_url;
if (options_->trim_urls_in_css() &&
options_->Enabled(RewriteOptions::kLeftTrimUrls) &&
UrlLeftTrimFilter::Trim(
trim_url_, url, &trimmed_url,
resource()->server_context()->message_handler())) {
// TODO(sligocki): Make sure this is the correct (final) URL of the CSS.
DirectSetUrl(trimmed_url);
} else {
DirectSetUrl(RelativizeOrPassthrough(options_, url, url_relativity_,
trim_url_));
}
}
}
void CssResourceSlot::Finished() {
// We always want to Render CssResourceSlots (even if the sub-resource was
// not optimizable), because the URLs need to be absolutified.
Render();
}
GoogleString CssResourceSlot::LocationString() const {
// TODO(morlovich): Improve quality of this diagnostic.
return "Inside CSS";
}
bool CssResourceSlot::DirectSetUrl(const StringPiece& url) {
// We should never try to render unauthorized resource URLs as is.
if (!resource()->is_authorized_domain()) {
return false;
}
delete (*values_)[value_index_];
(*values_)[value_index_] =
new Css::Value(Css::Value::URI,
UTF8ToUnicodeText(url.data(), url.size()));
return true;
}
bool CssResourceSlotFactory::SlotComparator::operator()(
const CssResourceSlotPtr& p, const CssResourceSlotPtr& q) const {
return (std::make_pair(p->values(), p->value_index()) <
std::make_pair(q->values(), q->value_index()));
}
CssResourceSlotFactory::~CssResourceSlotFactory() {
}
CssResourceSlotPtr CssResourceSlotFactory::GetSlot(
const ResourcePtr& resource, const GoogleUrl& trim_url,
const RewriteOptions* options, Css::Values* values, size_t value_index) {
CssResourceSlot* slot_obj =
new CssResourceSlot(resource, trim_url, options, values, value_index);
CssResourceSlotPtr slot(slot_obj);
return UniquifySlot(slot);
}
CssResourceSlotPtr CssResourceSlotFactory::UniquifySlot(
CssResourceSlotPtr slot) {
std::pair<SlotSet::iterator, bool> iter_found = slots_.insert(slot);
if (!iter_found.second) {
// The slot was already in the set. Release the one we just
// allocated and use the one already in.
SlotSet::iterator iter = iter_found.first;
slot.reset(*iter);
}
return slot;
}
} // namespace net_instaweb