001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.wicket.markup.html; 018 019import org.apache.wicket.MarkupContainer; 020import org.apache.wicket.Page; 021import org.apache.wicket.WicketRuntimeException; 022import org.apache.wicket.markup.ComponentTag; 023import org.apache.wicket.markup.IMarkupFragment; 024import org.apache.wicket.markup.MarkupResourceStream; 025import org.apache.wicket.markup.MarkupStream; 026import org.apache.wicket.markup.WicketTag; 027import org.apache.wicket.util.lang.Args; 028import org.apache.wicket.util.visit.IVisit; 029import org.apache.wicket.util.visit.IVisitor; 030 031/** 032 * HTML5 helper 033 * 034 * @author Juergen Donnerstag 035 */ 036public class MarkupUtil 037{ 038 /** 039 * 040 * @param container 041 * @return True if the Page and all it's Panels, Borders etc. have HTML5 compliant markup. HTML5 042 * markup is identified by <DOCTYPE html> 043 */ 044 public static boolean isMarkupHtml5Compliant(final MarkupContainer container) 045 { 046 Args.notNull(container, "container"); 047 048 Page page = container.getPage(); 049 050 final boolean rtn[] = new boolean[] { true }; 051 page.visitChildren(MarkupContainer.class, new IVisitor<MarkupContainer, Void>() 052 { 053 @Override 054 public void component(final MarkupContainer comp, final IVisit<Void> visit) 055 { 056 IMarkupFragment associatedMarkup = comp.getAssociatedMarkup(); 057 if (associatedMarkup != null) 058 { 059 MarkupResourceStream rs = associatedMarkup.getMarkupResourceStream(); 060 if (rs.isHtml5() == false) 061 { 062 rtn[0] = false; 063 visit.stop(); 064 } 065 } 066 } 067 }); 068 069 return rtn[0]; 070 } 071 072 /** 073 * Searches for {@code tagName} in the given {@code markup}. 074 * 075 * @param markup 076 * @param tagName 077 * @return The {@link IMarkupFragment} corresponding to {@code tagName}. Null, if such {@code tagName} is not found 078 */ 079 public static IMarkupFragment findStartTag(final IMarkupFragment markup, final String tagName) 080 { 081 MarkupStream stream = new MarkupStream(markup); 082 083 while (stream.skipUntil(WicketTag.class)) 084 { 085 ComponentTag tag = stream.getTag(); 086 if (tag.isOpen() || tag.isOpenClose()) 087 { 088 WicketTag wtag = (WicketTag)tag; 089 if (tagName.equalsIgnoreCase(wtag.getName())) 090 { 091 return stream.getMarkupFragment(); 092 } 093 094 stream.skipToMatchingCloseTag(tag); 095 } 096 097 stream.next(); 098 } 099 100 return null; 101 } 102}