001package arez.dom; 002 003import akasha.Document; 004import akasha.WindowGlobal; 005import arez.Disposable; 006import java.util.Objects; 007import javax.annotation.Nonnull; 008 009/** 010 * Exposes {@code document.visibilityState} as an observable property for specified documents. 011 * 012 * <p>A very simple example</p> 013 * <pre>{@code 014 * import arez.Arez; 015 * import arez.dom.DocumentVisibility; 016 * import com.google.gwt.core.client.EntryPoint; 017 * import akasha.Console; 018 * 019 * public class DocumentVisibilityExample 020 * implements EntryPoint 021 * { 022 * public void onModuleLoad() 023 * { 024 * final DocumentVisibility v = DocumentVisibility.create(); 025 * Arez.context().observer( () -> Console.log( "Document Visibility: " + v.getVisibility() ) ); 026 * } 027 * } 028 * }</pre> 029 */ 030public final class DocumentVisibility 031 implements Disposable 032{ 033 /** 034 * The visibility state of the document. 035 */ 036 public enum Visibility 037 { 038 /** 039 * The page content may be at least partially visible. In practice this means that the page is the foreground tab of a non-minimized window. 040 */ 041 VISIBLE, 042 /** 043 * The page content is not visible to the user. In practice this means that the document is either a background tab or part of a minimized window, or the OS screen lock is active. 044 */ 045 HIDDEN, 046 /** 047 * The page content is being prerendered and is not visible to the user (considered hidden for purposes of document.hidden). The document may start in this state, but will never transition to it from another value. Note: browser support is optional. 048 */ 049 PRERENDER 050 } 051 052 /** 053 * The underlying component performing the monitoring. 054 */ 055 private final EventDrivenValue<Document, String> _value; 056 057 /** 058 * Create component monitoring the default document. 059 * 060 * @return the new component. 061 */ 062 @Nonnull 063 public static DocumentVisibility create() 064 { 065 return create( WindowGlobal.document() ); 066 } 067 068 /** 069 * Create component monitoring specific document. 070 * 071 * @param document the document. 072 * @return the new component. 073 */ 074 @Nonnull 075 public static DocumentVisibility create( @Nonnull final Document document ) 076 { 077 return new DocumentVisibility( Objects.requireNonNull( document ) ); 078 } 079 080 private DocumentVisibility( @Nonnull final Document document ) 081 { 082 _value = EventDrivenValue.create( document, "visibilitychange", Document::visibilityState ); 083 } 084 085 /** 086 * Return the document that monitoring visibility state. 087 * 088 * @return the document. 089 */ 090 @Nonnull 091 public Document getDocument() 092 { 093 return _value.getSource(); 094 } 095 096 /** 097 * Change the document that is having visibility state monitored. 098 * 099 * @param document the new document. 100 */ 101 public void setDocument( @Nonnull final Document document ) 102 { 103 _value.setSource( document ); 104 } 105 106 /** 107 * Return the visibility state of the document as an enum. 108 * 109 * @return the visibility state as an enum. 110 */ 111 @Nonnull 112 public Visibility getVisibility() 113 { 114 return asVisibility( getVisibilityState() ); 115 } 116 117 /** 118 * Return the visibility state of the document as a string. 119 * 120 * @return the visibility state as a string. 121 */ 122 @Nonnull 123 public String getVisibilityState() 124 { 125 return _value.getValue(); 126 } 127 128 /** 129 * Return true if visibility state is "visible". 130 * 131 * @return true if visibility state is "visible". 132 */ 133 public boolean isVisible() 134 { 135 return "visible".equals( getVisibilityState() ); 136 } 137 138 /** 139 * Return true if visibility state is "hidden". 140 * 141 * @return true if visibility state is "hidden". 142 */ 143 public boolean isHidden() 144 { 145 return "hidden".equals( getVisibilityState() ); 146 } 147 148 @Override 149 public void dispose() 150 { 151 Disposable.dispose( _value ); 152 } 153 154 @Override 155 public boolean isDisposed() 156 { 157 return Disposable.isDisposed( _value ); 158 } 159 160 /** 161 * Convert the visibility state as an enum. 162 * 163 * @param state the state. 164 * @return the visibility enum. 165 */ 166 @Nonnull 167 private Visibility asVisibility( @Nonnull final String state ) 168 { 169 if ( "visible".equals( state ) ) 170 { 171 return Visibility.VISIBLE; 172 } 173 else if ( "hidden".equals( state ) ) 174 { 175 return Visibility.HIDDEN; 176 } 177 else 178 { 179 assert "prerender".equals( state ); 180 return Visibility.PRERENDER; 181 } 182 } 183}