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.head;
018
019import java.util.Collections;
020import java.util.List;
021import java.util.Objects;
022
023import org.apache.wicket.Application;
024import org.apache.wicket.core.util.string.JavaScriptUtils;
025import org.apache.wicket.request.Response;
026import org.apache.wicket.request.resource.ResourceReference;
027import org.apache.wicket.settings.JavaScriptLibrarySettings;
028import org.apache.wicket.util.string.Strings;
029import org.apache.wicket.util.value.AttributeMap;
030
031/**
032 * {@link HeaderItem} for scripts that need to be executed after the entire page is loaded.
033 *
034 * @author papegaaij
035 */
036public class OnLoadHeaderItem extends AbstractCspHeaderItem
037{
038        private static final long serialVersionUID = 1L;
039
040        /**
041         * Creates a {@link OnLoadHeaderItem} for the script.
042         *
043         * @param javaScript
044         *            The script to execute on the load event.
045         *
046         * @return A newly created {@link OnLoadHeaderItem}.
047         */
048        public static OnLoadHeaderItem forScript(CharSequence javaScript)
049        {
050                return new OnLoadHeaderItem(javaScript);
051        }
052
053        private final CharSequence javaScript;
054
055        /**
056         * Constructor.
057         *
058         * The JavaScript should be provided by overloaded #getJavaScript
059         */
060        public OnLoadHeaderItem()
061        {
062                this(null);
063        }
064
065        /**
066         * Construct.
067         *
068         * @param javaScript
069         */
070        public OnLoadHeaderItem(CharSequence javaScript)
071        {
072                this.javaScript = javaScript;
073        }
074
075        /**
076         * @return the script that gets executed after the entire is loaded.
077         */
078        public CharSequence getJavaScript()
079        {
080                return javaScript;
081        }
082
083
084        @Override
085        public void render(Response response)
086        {
087                CharSequence js = getJavaScript();
088                if (Strings.isEmpty(js) == false)
089                {
090                        AttributeMap attributes = new AttributeMap();
091                        attributes.putAttribute(JavaScriptUtils.ATTR_TYPE, "text/javascript");
092                        attributes.putAttribute(JavaScriptUtils.ATTR_CSP_NONCE, getNonce());
093                        JavaScriptUtils.writeInlineScript(response, "Wicket.Event.add(window, \"load\", " +
094                                        "function(event) { " + js + ";});", attributes);
095                }
096        }
097
098        @Override
099        public Iterable<?> getRenderTokens()
100        {
101                return Collections.singletonList("javascript-load-" + getJavaScript());
102        }
103
104        @Override
105        public String toString()
106        {
107                return "OnLoadHeaderItem('" + getJavaScript() + "')";
108        }
109
110        @Override
111        public boolean equals(Object o)
112        {
113                if (this == o) return true;
114                if (o == null || getClass() != o.getClass()) return false;
115                OnLoadHeaderItem that = (OnLoadHeaderItem) o;
116                return Objects.equals(javaScript, that.javaScript);
117        }
118
119        @Override
120        public int hashCode()
121        {
122                return Objects.hash(javaScript);
123        }
124
125        @Override
126        public List<HeaderItem> getDependencies()
127        {
128                JavaScriptLibrarySettings ajaxSettings = Application.get().getJavaScriptLibrarySettings();
129                ResourceReference wicketAjaxReference = ajaxSettings.getWicketAjaxReference();
130                List<HeaderItem> dependencies = super.getDependencies();
131                dependencies.add(JavaScriptHeaderItem.forReference(wicketAjaxReference));
132                return dependencies;
133        }
134}