1 /*
2 * Copyright (c) 2002-2025 Gargoyle Software Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 * https://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 package org.htmlunit.javascript.host;
16
17 import java.util.ArrayList;
18 import java.util.List;
19
20 import org.htmlunit.corejs.javascript.Scriptable;
21 import org.htmlunit.javascript.HtmlUnitScriptable;
22 import org.htmlunit.javascript.JavaScriptEngine;
23 import org.htmlunit.javascript.configuration.JsxClass;
24 import org.htmlunit.javascript.configuration.JsxConstructor;
25 import org.htmlunit.javascript.configuration.JsxFunction;
26 import org.htmlunit.javascript.configuration.JsxGetter;
27 import org.htmlunit.javascript.configuration.JsxSymbol;
28
29 /**
30 * A JavaScript object for {@code PluginArray}.
31 *
32 * @author Marc Guillemot
33 * @author Ahmed Ashour
34 * @author Ronald Brill
35 *
36 * @see <a href="https://developer.mozilla.org/en-US/docs/Web/API/PluginArray">PluginArray</a>
37 */
38 @JsxClass
39 public class PluginArray extends HtmlUnitScriptable {
40
41 private final List<Plugin> elements_ = new ArrayList<>();
42
43 /**
44 * JavaScript constructor.
45 */
46 @JsxConstructor
47 public void jsConstructor() {
48 // nothing to do
49 }
50
51 /**
52 * Returns the item at the given index.
53 * @param index the index
54 * @return the item at the given position
55 */
56 @JsxFunction
57 public Plugin item(final int index) {
58 if (index >= 0 && index < elements_.size()) {
59 return elements_.get(index);
60 }
61 return null;
62 }
63
64 /**
65 * {@inheritDoc}
66 */
67 @Override
68 protected Object getWithPreemption(final String name) {
69 final Plugin response = namedItem(name);
70 if (response != null) {
71 return response;
72 }
73 return NOT_FOUND;
74 }
75
76 /**
77 * {@inheritDoc}.
78 */
79 @Override
80 public boolean has(final String name, final Scriptable start) {
81 if (NOT_FOUND != getWithPreemption(name)) {
82 return true;
83 }
84
85 return super.has(name, start);
86 }
87
88 /**
89 * Returns the element at the specified index, or {@code null} if the index is invalid.
90 * {@inheritDoc}
91 */
92 @Override
93 public final Plugin get(final int index, final Scriptable start) {
94 final PluginArray array = (PluginArray) start;
95 final List<Plugin> elements = array.elements_;
96
97 if (index >= 0 && index < elements.size()) {
98 return elements.get(index);
99 }
100 return null;
101 }
102
103 /**
104 * Returns the item at the given index.
105 * @param name the item name
106 * @return the item with the given name
107 */
108 @JsxFunction
109 public Plugin namedItem(final String name) {
110 for (final Plugin element : elements_) {
111 if (name.equals(getItemName(element))) {
112 return element;
113 }
114 }
115 return null;
116 }
117
118 /**
119 * Gets the array size.
120 * @return the number elements
121 */
122 @JsxGetter
123 public int getLength() {
124 return elements_.size();
125 }
126
127 /**
128 * Current implementation does nothing.
129 * @param reloadDocuments reload yes / no
130 * @see <a href="http://www.xulplanet.com/references/objref/PluginArray.html#method_refresh">XUL Planet</a>
131 */
132 @JsxFunction
133 public void refresh(final boolean reloadDocuments) {
134 // nothing
135 }
136
137 /**
138 * Gets the name of the plugin.
139 * @param element a {@link Plugin}
140 * @return the name
141 */
142 protected String getItemName(final Object element) {
143 return ((Plugin) element).getName();
144 }
145
146 /**
147 * Adds an element.
148 * @param element the element to add
149 */
150 void add(final Plugin element) {
151 elements_.add(element);
152 }
153
154 /**
155 * @return the Iterator symbol
156 */
157 @JsxSymbol
158 public Scriptable iterator() {
159 return JavaScriptEngine.newArrayIteratorTypeValues(getParentScope(), this);
160 }
161 }