Skip to content

Commit

Permalink
Add target constants for Anchor to use with alternate setTarget method
Browse files Browse the repository at this point in the history
  • Loading branch information
jhult committed Nov 25, 2020
1 parent 62e1e26 commit 4714525
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
*/
package com.vaadin.flow.component.html;

import java.util.Objects;
import java.util.Optional;
import java.util.stream.Stream;

import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.Focusable;
Expand All @@ -39,7 +41,7 @@ public class Anchor extends HtmlContainer implements Focusable<Anchor> {
.attributeWithDefault("href", "", false);

private static final PropertyDescriptor<String, Optional<String>> targetDescriptor = PropertyDescriptors
.optionalAttributeWithDefault("target", "");
.optionalAttributeWithDefault("target", AnchorTarget.DEFAULT.getValue());

private static final String ROUTER_IGNORE_ATTRIBUTE = "router-ignore";

Expand All @@ -66,6 +68,26 @@ public Anchor(String href, String text) {
setText(text);
}

/**
* Creates an anchor component with the given target, text content and href.
*
* @see #setHref(String)
* @see #setText(String)
* @see #setTarget(AnchorTarget)
*
* @param href
* the href to set
* @param text
* the text content to set
* @param target
* the target window, tab or frame
*/
public Anchor(String href, String text, AnchorTarget target) {
setHref(href);
setText(text);
setTarget(target);
}

/**
* Creates an anchor component with the given text content and stream
* resource.
Expand Down Expand Up @@ -183,4 +205,47 @@ public Optional<String> getTarget() {
return get(targetDescriptor);
}

/**
* Sets the target window, tab or frame for this anchor. The target is one of these
* special values:
* <ul>
* <li><code>AnchorTarget.DEFAULT</code>: Removes the target value. This has the same effect as setting the target to <code>AnchorTarget.SELF</code>.
* <li><code>AnchorTarget.SELF</code>: Opens the link in the current context.
* <li><code>AnchorTarget.BLANK</code>: Opens the link in a new unnamed context.
* <li><code>AnchorTarget.PARENT</code>: Opens the link in the parent context, or the
* current context if there is no parent context.
* <li><code>AnchorTarget.TOP</code>: Opens the link in the top most grandparent
* context, or the current context if there is no parent context.
* </ul>
*
* @param target
* the target value, not null
*/
public void setTarget(AnchorTarget target) {
Objects.requireNonNull(target, "target cannot be null.");
setTarget(target.getValue());
}

/**
* Gets the target window, tab or frame value for this anchor.
*
* @see #setTarget(AnchorTarget)
*
* @return an optional target, or an empty optional if no target has been
* set
*/
public Optional<AnchorTarget> getTargetEnum() {
Optional<AnchorTarget> anchorTarget = Optional.empty();

Optional<String> strTarget = getTarget();

if (strTarget.isPresent()) {
String valueToFind = strTarget.get();
anchorTarget = Stream.of(AnchorTarget.values()).filter(type-> type.getValue().equals(valueToFind))
.findFirst();
}

return anchorTarget;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright 2000-2020 Vaadin Ltd.
*
* 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.
*/
package com.vaadin.flow.component.html;

/**
* Enum representing <code>target</code> attribute values for an <code>&lt;a&gt;</code> element.
*
* @author Vaadin Ltd
* @since
*/
public enum AnchorTarget {
/**
* Remove the target value. This has the same effect as <code>SELF</code>.
*/
DEFAULT(""),
/**
* Open a link in the current context.
*/
SELF("_self"),
/**
* Open a link in a new unnamed context.
*/
BLANK("_blank"),
/**
* Open a link in the parent context, or the current context if there is no
* parent context.
*/
PARENT("_parent"),
/**
* Open a link in the top most grandparent
* context, or the current context if there is no parent context.
*/
TOP("_top");

private final String value;

/**
* @param value the text value to use by an {@code <a>} (anchor) tag.
*/
AnchorTarget(String value) {
this.value = value;
}

/**
* @return
* value the text value to use by an {@code <a>} (anchor) tag.
*/
String getValue() {
return value;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import org.junit.Assert;
import org.junit.Test;

import java.util.Optional;

public class AnchorTest extends ComponentTest {

@Test
Expand All @@ -35,7 +37,24 @@ public void removeHref() {
public void createWithComponent() {
Anchor anchor = new Anchor("#", new Text("Home"));
Assert.assertEquals(anchor.getElement().getAttribute("href"), "#");
Assert.assertEquals(anchor.getHref(), "#");
Assert.assertEquals(anchor.getElement().getText(), "Home");
Assert.assertEquals(anchor.getText(), "Home");
}

@Test
public void createWithTarget() {
Anchor anchor = new Anchor("#", "Home");
Assert.assertEquals(anchor.getTargetEnum(), Optional.empty());
Assert.assertEquals(anchor.getTarget(), Optional.empty());

anchor.setTarget(AnchorTarget.BLANK);

Assert.assertEquals(anchor.getTargetEnum(), Optional.of(AnchorTarget.BLANK));
Assert.assertEquals(anchor.getTarget(), Optional.of(AnchorTarget.BLANK.getValue()));

Assert.assertEquals(anchor.getTargetEnum(), new Anchor("#", "Home", AnchorTarget.BLANK).getTargetEnum());
Assert.assertEquals(anchor.getTarget(), new Anchor("#", "Home", AnchorTarget.BLANK).getTarget());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public class HtmlComponentSmokeTest {
testValues.put(int.class, 42);
testValues.put(IFrame.ImportanceType.class, IFrame.ImportanceType.HIGH);
testValues.put(IFrame.SandboxType[].class, new IFrame.SandboxType[] { IFrame.SandboxType.ALLOW_POPUPS, IFrame.SandboxType.ALLOW_MODALS });
testValues.put(AnchorTarget.class, AnchorTarget.TOP);
}

// For classes registered here testStringConstructor will be ignored. This test checks whether the content of the
Expand Down Expand Up @@ -169,12 +170,20 @@ private static boolean isSetter(Method method) {
}

private static boolean isSpecialSetter(Method method) {
// Shorthand for Lablel.setFor(String)
// Shorthand for Label.setFor(String)
if (method.getDeclaringClass() == Label.class
&& method.getName().equals("setFor")
&& method.getParameterTypes()[0] == Component.class) {
return true;
}

// Anchor.setTarget(AnchorTarget) - https://github.com/vaadin/flow/issues/8346
if (method.getDeclaringClass() == Anchor.class
&& method.getName().equals("setTarget")
&& method.getParameterTypes()[0] == AnchorTarget.class) {
return true;
}

// setFoo(AbstractStreamResource) for resource URLs
if (method.getParameterCount() == 1 && AbstractStreamResource.class
.isAssignableFrom(method.getParameters()[0].getType())) {
Expand Down

0 comments on commit 4714525

Please sign in to comment.