001package gwt.material.design.client.base;
002
003/*
004 * #%L
005 * GwtMaterial
006 * %%
007 * Copyright (C) 2015 GwtMaterialDesign
008 * %%
009 * Licensed under the Apache License, Version 2.0 (the "License");
010 * you may not use this file except in compliance with the License.
011 * You may obtain a copy of the License at
012 * 
013 *      http://www.apache.org/licenses/LICENSE-2.0
014 * 
015 * Unless required by applicable law or agreed to in writing, software
016 * distributed under the License is distributed on an "AS IS" BASIS,
017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018 * See the License for the specific language governing permissions and
019 * limitations under the License.
020 * #L%
021 */
022
023import com.google.gwt.core.client.JavaScriptObject;
024import com.google.gwt.dom.client.Element;
025import com.google.gwt.event.shared.GwtEvent;
026import com.google.gwt.event.shared.HasHandlers;
027import com.google.gwt.user.client.ui.Widget;
028import com.google.web.bindery.event.shared.HandlerRegistration;
029import gwt.material.design.client.events.ObservedEvent;
030import gwt.material.design.client.events.ObservedEvent.ObservedHandler;
031
032public abstract class AttributeObserver implements HasHandlers {
033
034    Widget widget;
035    JavaScriptObject observer;
036    
037    public AttributeObserver(Widget widget) {
038        this.widget = widget;
039    }
040
041    protected abstract JavaScriptObject createMutationObject();
042
043    public void fireObserved(String old, String newValue) {
044        ObservedEvent.fire(this, old, newValue);
045    }
046
047    @Override
048    public void fireEvent(GwtEvent<?> event) {
049        widget.fireEvent(event);
050    }
051
052    public <H extends ObservedHandler> HandlerRegistration addObservedHandler(H handler) {
053        return widget.addHandler(handler, ObservedEvent.TYPE);
054    }
055
056    public <H extends ObservedHandler> HandlerRegistration addObservedHandler(H handler, GwtEvent.Type<H> type) {
057        return widget.addHandler(handler, type);
058    }
059
060    protected native JavaScriptObject getMutationFunction(String attr1, String attr2) /*-{
061        var that = this;
062        return function(mutations) {
063            mutations.forEach(function(mutation) {
064                var old = mutation.oldValue;
065                var value = mutation.target[attr1][attr2];
066
067                if(mutation.attributeName == attr1 && old !== null && old.slice(0, attr2.length) == attr2) {
068                    that.@gwt.material.design.client.base.AttributeObserver::fireObserved(Ljava/lang/String;Ljava/lang/String;)(
069                        old, value);
070                }
071            });
072        }
073    }-*/;
074    
075    protected static native JavaScriptObject getObserver(JavaScriptObject func) /*-{
076       return new MutationObserver(func);
077    }-*/;
078
079    public void observe(Element e, String attr) {
080        if(observer == null) {
081            observer = getObserver(createMutationObject());
082        }
083        nativeObserve(e, attr);
084    }
085
086    public native void nativeObserve(Element e, String attr) /*-{
087        this.@gwt.material.design.client.base.AttributeObserver::observer.observe(e, {
088            attributes: true,
089            attributeOldValue: true,
090            attributeFilter: [attr]
091        });
092    }-*/;
093}