On 1/20/20, 9:27 AM, "Harbs" <[email protected]> wrote:

    Yeah. I thought about subclassing HashChangeNotifierBead and the version 
with Title, but almost all the code would have needed to be overridden (i.e. 
I’m auto-stipping off the hash, etc.), so I decided to write it from scratch.
    
    The bead was not intended to be a lightweight PAYG bead. If someone wants 
very lightweight, they should use the Notifier beads. It’s meant to be as 
drop-in as possible to make it easier on the developer.
    
IMO, in that case, it should go in Express not, Basic.

-Alex

    > On Jan 20, 2020, at 6:41 PM, Alex Harui <[email protected]> wrote:
    > 
    > Nit-picky comments:
    > 
    > 1) there is already a bead that watches location.hash.  It might be worth 
using it to share code
    > 2) forward/backward/go/title doesn't seem PAYG to me.  I can imagine lots 
of users won't need it, or might use it independently of routing (especially 
Title).
    > 
    > My 2 cents,
    > -Alex
    > 
    > On 1/20/20, 4:11 AM, "[email protected] <mailto:[email protected]>" 
<[email protected] <mailto:[email protected]>> wrote:
    > 
    >    This is an automated email from the ASF dual-hosted git repository.
    > 
    >    harbs pushed a commit to branch develop
    >    in repository 
https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitbox.apache.org%2Frepos%2Fasf%2Froyale-asjs.git&amp;data=02%7C01%7Caharui%40adobe.com%7Cf932412ad0a24a40856a08d79dcdfa32%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637151380297043799&amp;sdata=UDJSMyIC%2FDXJZCm0M5xDb3GGNzXRyhMUe7bHu0anz%2Fc%3D&amp;reserved=0
 
<https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitbox.apache.org%2Frepos%2Fasf%2Froyale-asjs.git&amp;data=02%7C01%7Caharui%40adobe.com%7Cf932412ad0a24a40856a08d79dcdfa32%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637151380297043799&amp;sdata=UDJSMyIC%2FDXJZCm0M5xDb3GGNzXRyhMUe7bHu0anz%2Fc%3D&amp;reserved=0>
    > 
    > 
    >    The following commit(s) were added to refs/heads/develop by this push:
    >         new 6cbc555  Added Router
    >    6cbc555 is described below
    > 
    >    commit 6cbc5559bcc99bf2ceb3e033747ca3680b3b0d91
    >    Author: Harbs <[email protected] <mailto:[email protected]>>
    >    AuthorDate: Mon Jan 20 14:10:42 2020 +0200
    > 
    >        Added Router
    >    ---
    >     .../Basic/src/main/resources/basic-manifest.xml    |   2 +
    >     .../royale/org/apache/royale/routing/RouteState.as |  34 +++
    >     .../royale/org/apache/royale/routing/Router.as     | 274 
+++++++++++++++++++++
    >     3 files changed, 310 insertions(+)
    > 
    >    diff --git 
a/frameworks/projects/Basic/src/main/resources/basic-manifest.xml 
b/frameworks/projects/Basic/src/main/resources/basic-manifest.xml
    >    index 00e2325..3c30bed 100644
    >    --- a/frameworks/projects/Basic/src/main/resources/basic-manifest.xml
    >    +++ b/frameworks/projects/Basic/src/main/resources/basic-manifest.xml
    >    @@ -273,4 +273,6 @@
    >         <component id="ModalDisplay" 
class="org.apache.royale.html.beads.plugin.ModalDisplay"/>
    >         <component id="ModalOverlay" 
class="org.apache.royale.html.beads.plugin.ModalOverlay"/>
    > 
    >    +    <component id="Router" class="org.apache.royale.routing.Router"/>
    >    +
    >     </componentPackage>
    >    diff --git 
a/frameworks/projects/Basic/src/main/royale/org/apache/royale/routing/RouteState.as
 
b/frameworks/projects/Basic/src/main/royale/org/apache/royale/routing/RouteState.as
    >    new file mode 100644
    >    index 0000000..84fcc4c
    >    --- /dev/null
    >    +++ 
b/frameworks/projects/Basic/src/main/royale/org/apache/royale/routing/RouteState.as
    >    @@ -0,0 +1,34 @@
    >    
+////////////////////////////////////////////////////////////////////////////////
    >    +//
    >    +//  Licensed to the Apache Software Foundation (ASF) under one or more
    >    +//  contributor license agreements.  See the NOTICE file distributed 
with
    >    +//  this work for additional information regarding copyright 
ownership.
    >    +//  The ASF licenses this file to You 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
    >    +//
    >    +//      
https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.apache.org%2Flicenses%2FLICENSE-2.0&amp;data=02%7C01%7Caharui%40adobe.com%7Cf932412ad0a24a40856a08d79dcdfa32%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637151380297043799&amp;sdata=dS98z1bAFk5RE0uJ6WmdDTvkuXIMbrQIfyfy9aGNBEk%3D&amp;reserved=0
 
<https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.apache.org%2Flicenses%2FLICENSE-2.0&amp;data=02%7C01%7Caharui%40adobe.com%7Cf932412ad0a24a40856a08d79dcdfa32%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637151380297043799&amp;sdata=dS98z1bAFk5RE0uJ6WmdDTvkuXIMbrQIfyfy9aGNBEk%3D&amp;reserved=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 org.apache.royale.routing
    >    +{
    >    +  public class RouteState
    >    +  {
    >    +    public function RouteState(state:String="",title:String="")
    >    +    {
    >    +      this.state = state;
    >    +      this.title = title;
    >    +
    >    +    }
    >    +    public var state:String;
    >    +    public var title:String;
    >    +    public var parameters:Object;
    >    +    public var path:Array;
    >    +  }
    >    +}
    >    \ No newline at end of file
    >    diff --git 
a/frameworks/projects/Basic/src/main/royale/org/apache/royale/routing/Router.as 
b/frameworks/projects/Basic/src/main/royale/org/apache/royale/routing/Router.as
    >    new file mode 100644
    >    index 0000000..98b9fc6
    >    --- /dev/null
    >    +++ 
b/frameworks/projects/Basic/src/main/royale/org/apache/royale/routing/Router.as
    >    @@ -0,0 +1,274 @@
    >    
+////////////////////////////////////////////////////////////////////////////////
    >    +//
    >    +//  Licensed to the Apache Software Foundation (ASF) under one or more
    >    +//  contributor license agreements.  See the NOTICE file distributed 
with
    >    +//  this work for additional information regarding copyright 
ownership.
    >    +//  The ASF licenses this file to You 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
    >    +//
    >    +//      
https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.apache.org%2Flicenses%2FLICENSE-2.0&amp;data=02%7C01%7Caharui%40adobe.com%7Cf932412ad0a24a40856a08d79dcdfa32%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637151380297043799&amp;sdata=dS98z1bAFk5RE0uJ6WmdDTvkuXIMbrQIfyfy9aGNBEk%3D&amp;reserved=0
 
<https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.apache.org%2Flicenses%2FLICENSE-2.0&amp;data=02%7C01%7Caharui%40adobe.com%7Cf932412ad0a24a40856a08d79dcdfa32%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637151380297053790&amp;sdata=NY4972Z6X3a%2BHWhuAA9r2ViKiWpNJQIzaCcQlkH4TLI%3D&amp;reserved=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 org.apache.royale.routing
    >    +{
    >    +  import org.apache.royale.core.DispatcherBead;
    >    +  import org.apache.royale.core.IStrand;
    >    +  import org.apache.royale.debugging.assert;
    >    +  import org.apache.royale.core.IStatesObject;
    >    +  import org.apache.royale.events.Event;
    >    +  import org.apache.royale.core.IInitialViewApplication;
    >    +    /**
    >    +     *  Dispatched when the state is changed.
    >    +     *
    >    +     *  @langversion 3.0
    >    +     *  @playerversion Flash 10.2
    >    +     *  @playerversion AIR 2.6
    >    +     *  @productversion Royale 0.9.7
    >    +     */
    >    +    [Event(name="stateChange", type="org.apache.royale.events.Event")]
    >    +
    >    +    /**
    >    +     * Router is a bead which automatically handles browsing history.
    >    +     * It could be attached to any strand, but typically it would be 
attached to Application or View
    >    +     * Listen to stateChange events to handle changes to browsing 
history and use setState and renderState for modifying the history.
    >    +     * The state of the router can be modified before committing the 
state changes.
    >    +     *  @langversion 3.0
    >    +     *  @playerversion Flash 10.2
    >    +     *  @playerversion AIR 2.6
    >    +     *  @productversion Royale 0.9.7
    >    +     */
    >    +  public class Router extends DispatcherBead
    >    +  {
    >    +    public function Router()
    >    +    {
    >    +      
    >    +    }
    >    +    /**
    >    +     * Use this to automatically sync the state of the strand.
    >    +     * This only works for the state property of the RouterState.
    >    +     * It also assumes that the strand is an IStatesObject.
    >    +     * For this to work correctly, it's usually assumed that the bead 
is attached to the application View
    >    +     *  @langversion 3.0
    >    +     *  @playerversion Flash 10.2
    >    +     *  @playerversion AIR 2.6
    >    +     *  @productversion Royale 0.9.7
    >    +     */
    >    +    public var syncState:Boolean;
    >    +              override public function set strand(value:IStrand):void
    >    +              {       
    >    +                      _strand = value;
    >    +                      COMPILE::JS
    >    +                      {
    >    +                              window.addEventListener("hashchange", 
hashChangeHandler);
    >    +        initialTitle = document.title;
    >    +                      }
    >    +      // If it's an Application, listen to applicationComplete
    >    +      if(_strand is IInitialViewApplication)
    >    +        listenOnStrand("applicationComplete",onInit);
    >    +      //Otherwise listen to initComplete
    >    +      else
    >    +        listenOnStrand("initComplete",onInit);
    >    +              }
    >    +    private function onInit(event:Event):void
    >    +    {
    >    +      COMPILE::JS
    >    +      {
    >    +        if(location.hash)
    >    +        {
    >    +          hashChangeHandler();
    >    +        }
    >    +      }
    >    +    }
    >    +    private var initialTitle:String;
    >    +              private function hashChangeHandler():void
    >    +              {
    >    +      parseHash();
    >    +      if(syncState)
    >    +      {
    >    +        assert(_strand is IStatesObject,"syncState can only be used 
on IStatesObjects");
    >    +        (_strand as IStatesObject).currentState = _routeState.state;
    >    +      }
    >    +                      dispatchEvent(new Event("stateChange"));
    >    +              }
    >    +    private function parseHash():void
    >    +    {
    >    +      //TODO SWF implementation
    >    +      COMPILE::JS
    >    +      {
    >    +        var hash:String = location.hash;
    >    +        var index:int = 0;
    >    +        if(hash.indexOf("!")==1){
    >    +          index = 1;
    >    +        }
    >    +        hash = hash.slice(index+1);
    >    +        var paths:Array = hash.split("/");
    >    +        var statePart:String = paths.pop();
    >    +        var splitParts:Array = statePart.split("?");
    >    +        statePart = splitParts[0];
    >    +        _routeState = new RouteState(statePart,document.title);
    >    +        _routeState.path = paths;
    >    +        _routeState.parameters = parseParameters(splitParts[1]);
    >    +      }
    >    +    }
    >    +    private function parseParameters(query:String):Object
    >    +    {
    >    +      var urlVars:Object;
    >    +      if(query){
    >    +        var vars:Array = query.split("&");
    >    +        if(vars.length){
    >    +          urlVars = {};
    >    +        }
    >    +        for (var i:int=0;i<vars.length;i++) {
    >    +            var pair:Array = vars[i].split("=");
    >    +            urlVars[pair[0]] = pair[1] == undefined ? undefined : 
decodeURIComponent(pair[1]);
    >    +        }
    >    +      }
    >    +      return urlVars;
    >    +    }
    >    +
    >    +    private function buildHash():String
    >    +    {
    >    +      var hash:String = "#!";
    >    +      if(_routeState.path && routeState.path.length){
    >    +        hash += (_routeState.path.join("/") + "/");
    >    +      }
    >    +      if(_routeState.state){
    >    +        hash += _routeState.state;
    >    +      }
    >    +      hash+= buildParameterString();
    >    +      return hash;
    >    +    }
    >    +    private function buildParameterString():String{
    >    +      var retVal:String = "";
    >    +      if(_routeState.parameters){
    >    +        retVal += "?";
    >    +        for(var x:String in _routeState.parameters){
    >    +          retVal += x;
    >    +          if(_routeState.parameters[x] != undefined){
    >    +            retVal += "=" + 
encodeURIComponent(_routeState.parameters[x]);
    >    +            retVal += "&";
    >    +          }
    >    +        }
    >    +        //remove trailing &
    >    +        retVal = retVal.slice(0, -1);
    >    +      }
    >    +
    >    +      return retVal;
    >    +    }
    >    +
    >    +    private var _routeState:RouteState;
    >    +
    >    +    public function get routeState():RouteState
    >    +    {
    >    +      if(!_routeState){
    >    +        _routeState = new RouteState();
    >    +      }
    >    +      return _routeState;
    >    +    }
    >    +
    >    +    public function set routeState(value:RouteState):void
    >    +    {
    >    +      _routeState = value;
    >    +    }
    >    +    /**
    >    +     * Commits the current state to the browsing history
    >    +     *  @langversion 3.0
    >    +     *  @playerversion Flash 10.2
    >    +     *  @playerversion AIR 2.6
    >    +     *  @productversion Royale 0.9.7
    >    +     */
    >    +    public function setState():void
    >    +    {
    >    +      COMPILE::JS
    >    +      {
    >    +        
window.history.pushState({"title":_routeState.title},_routeState.title,buildHash());
    >    +        if(_routeState.title)
    >    +        {
    >    +          document.title = _routeState.title;
    >    +        }
    >    +      }
    >    +    }
    >    +    /**
    >    +     * Same as setState, but also notifies of the state change 
    >    +     *  @langversion 3.0
    >    +     *  @playerversion Flash 10.2
    >    +     *  @playerversion AIR 2.6
    >    +     *  @productversion Royale 0.9.7
    >    +     */
    >    +    public function renderState():void
    >    +    {
    >    +      setState();
    >    +      if(syncState)
    >    +      {
    >    +        assert(_strand is IStatesObject,"syncState can only be used 
on IStatesObjects");
    >    +        (_strand as IStatesObject).currentState = _routeState.state;
    >    +      }
    >    +      dispatchEvent(new Event("stateChange"));
    >    +    }
    >    +    private function setTitle():void
    >    +    {
    >    +      COMPILE::JS
    >    +      {
    >    +        if(window.history.state){
    >    +          document.title = window.history.state["title"];
    >    +        } else {
    >    +          document.title = initialTitle;
    >    +        }
    >    +      }
    >    +    }
    >    +    /**
    >    +     * Goes forward in the history
    >    +     *  @langversion 3.0
    >    +     *  @playerversion Flash 10.2
    >    +     *  @playerversion AIR 2.6
    >    +     *  @productversion Royale 0.9.7
    >    +     */
    >    +    public function forward():void{
    >    +      COMPILE::JS
    >    +      {
    >    +         window.history.forward();
    >    +         setTitle();
    >    +         parseHash();
    >    +      }
    >    +    }
    >    +    /**
    >    +     * Goes backwards in the history
    >    +     *  @langversion 3.0
    >    +     *  @playerversion Flash 10.2
    >    +     *  @playerversion AIR 2.6
    >    +     *  @productversion Royale 0.9.7
    >    +     */
    >    +    public function back():void{
    >    +      COMPILE::JS
    >    +      {
    >    +         window.history.back();
    >    +         setTitle();
    >    +         parseHash();
    >    +      }
    >    +    }
    >    +
    >    +    /**
    >    +     * Moved the specified number of steps (forward or backwards) in 
the history
    >    +     * calling it with 0 or no value will reload the page.
    >    +     *  @langversion 3.0
    >    +     *  @playerversion Flash 10.2
    >    +     *  @playerversion AIR 2.6
    >    +     *  @productversion Royale 0.9.7
    >    +     */
    >    +    public function go(steps:int=0):void{
    >    +      COMPILE::JS
    >    +      {
    >    +         window.history.go(steps);
    >    +         parseHash();
    >    +      }
    >    +    }
    >    +
    >    +  }
    >    +}
    >    \ No newline at end of file
    
    

Reply via email to