| /* |
| * 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: pulkitg@google.com (Pulkit Goyal) |
| |
| #include "net/instaweb/rewriter/public/defer_iframe_filter.h" |
| |
| #include "net/instaweb/rewriter/public/request_properties.h" |
| #include "net/instaweb/rewriter/public/rewrite_driver.h" |
| #include "net/instaweb/rewriter/public/rewrite_options.h" |
| #include "net/instaweb/rewriter/public/server_context.h" |
| #include "net/instaweb/rewriter/public/static_asset_manager.h" |
| #include "pagespeed/kernel/base/string.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 net_instaweb { |
| |
| const char DeferIframeFilter::kDeferIframeInit[] = |
| "pagespeed.deferIframeInit();"; |
| const char DeferIframeFilter::kDeferIframeIframeJs[] = |
| "\npagespeed.deferIframe.convertToIframe();"; |
| |
| DeferIframeFilter::DeferIframeFilter(RewriteDriver* driver) |
| : CommonFilter(driver), |
| static_asset_manager_( |
| driver->server_context()->static_asset_manager()), |
| script_inserted_(false) {} |
| |
| DeferIframeFilter::~DeferIframeFilter() { |
| } |
| |
| void DeferIframeFilter::DetermineEnabled(GoogleString* disabled_reason) { |
| set_is_enabled(driver()->request_properties()->SupportsJsDefer( |
| driver()->options()->enable_aggressive_rewriters_for_mobile())); |
| } |
| |
| void DeferIframeFilter::StartDocumentImpl() { |
| script_inserted_ = false; |
| } |
| |
| void DeferIframeFilter::StartElementImpl(HtmlElement* element) { |
| if (noscript_element() != NULL) { |
| return; |
| } |
| if (element->keyword() == HtmlName::kIframe) { |
| if (!script_inserted_) { |
| HtmlElement* script = driver()->NewElement(element->parent(), |
| HtmlName::kScript); |
| driver()->InsertNodeBeforeNode(element, script); |
| |
| GoogleString js = StrCat( |
| static_asset_manager_->GetAsset( |
| StaticAssetEnum::DEFER_IFRAME, driver()->options()), |
| kDeferIframeInit); |
| AddJsToElement(js, script); |
| script_inserted_ = true; |
| } |
| element->set_name(driver()->MakeName(HtmlName::kPagespeedIframe)); |
| } |
| } |
| |
| void DeferIframeFilter::EndElementImpl(HtmlElement* element) { |
| if (noscript_element() != NULL) { |
| return; |
| } |
| if (element->keyword() == HtmlName::kPagespeedIframe) { |
| HtmlElement* script = driver()->NewElement(element, HtmlName::kScript); |
| driver()->AddAttribute(script, HtmlName::kType, "text/javascript"); |
| HtmlCharactersNode* script_content = driver()->NewCharactersNode( |
| script, kDeferIframeIframeJs); |
| driver()->AppendChild(element, script); |
| driver()->AppendChild(script, script_content); |
| } |
| } |
| |
| } // namespace net_instaweb |