blob: c67d8ef0b71fbcab27353281b24c9789ff14a918 [file] [log] [blame]
/*
* Copyright 2012 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: sriharis@google.com (Srihari Sukumaran)
#include "net/instaweb/rewriter/public/handle_noscript_redirect_filter.h"
#include "net/instaweb/public/global_constants.h"
#include "net/instaweb/rewriter/public/rewrite_driver.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/kernel/html/html_element.h"
#include "pagespeed/kernel/html/html_name.h"
#include "pagespeed/kernel/html/html_node.h"
namespace {
const char kCanonical[] = "canonical";
} // namespace
namespace net_instaweb {
HandleNoscriptRedirectFilter::HandleNoscriptRedirectFilter(
RewriteDriver* rewrite_driver) : rewrite_driver_(rewrite_driver) {
Init();
}
HandleNoscriptRedirectFilter::~HandleNoscriptRedirectFilter() {
}
void HandleNoscriptRedirectFilter::Init() {
canonical_present_ = false;
canonical_inserted_ = false;
}
void HandleNoscriptRedirectFilter::StartDocument() {
Init();
}
void HandleNoscriptRedirectFilter::StartElement(HtmlElement* element) {
if (!canonical_inserted_ && !canonical_present_ &&
element->keyword() == HtmlName::kLink) {
// Checks if a <link rel=canonical href=...> is present.
HtmlElement::Attribute* rel_attr = element->FindAttribute(HtmlName::kRel);
HtmlElement::Attribute* href_attr = element->FindAttribute(HtmlName::kHref);
canonical_present_ = (rel_attr != NULL && href_attr != NULL &&
StringCaseEqual(rel_attr->DecodedValueOrNull(),
kCanonical));
}
}
void HandleNoscriptRedirectFilter::EndElement(HtmlElement* element) {
if (!canonical_inserted_ && !canonical_present_ &&
element->keyword() == HtmlName::kHead) {
// We insert the <link rel=canonical href=original_url> at the end of the
// first head, if the first head did not already contain a
// <link rel=canonical href=...>
// TODO(sriharis): Get the query param stripped in driver in apache.
// TODO(sriharis): Should we check all heads for
// <link rel=canonical href=...> ? If we want to do this then if there is
// no such element, to insert our link element we might need to add a head
// (since all heads might have been flushed already).
HtmlCharactersNode* link_node = rewrite_driver_->NewCharactersNode(
element, StringPrintf(kLinkRelCanonicalFormatter,
rewrite_driver_->url()));
rewrite_driver_->AppendChild(element, link_node);
canonical_inserted_ = true;
}
}
} // namespace net_instaweb