Skip to content

Commit

Permalink
Issue #775 Drop Frameback
Browse files Browse the repository at this point in the history
  • Loading branch information
Jason Zhou committed Feb 14, 2017
1 parent 9611f41 commit 65e0d7a
Show file tree
Hide file tree
Showing 12 changed files with 28 additions and 560 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const logger = logging.getLogger(__LOGGER__);
const NetworkCard = ({id, name, location, company}) => {
logger.info(`rendering card for network ${name}`);
return (
<div><Link path={`/network?network=${id}`} frameback>{name}</Link> in {location.city}, {location.country}, run by {company}</div>
<div><Link path={`/network?network=${id}`}>{name}</Link> in {location.city}, {location.country}, run by {company}</div>
);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
.pick-pointer {
width: 16px;
cursor: pointer;
}

.not-available {
text-decoration: line-through;
}
}
33 changes: 0 additions & 33 deletions packages/react-server-test-pages/pages/navigation/playground.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,32 +82,6 @@ const CT = ({row}) => <Link path={LINK(row)}>CT</Link>
const RD = ({row}) => <Link reuseDom={true} path={LINK(row)}>CT/RD</Link>
const BD = ({row}) => <Link bundleData={true} path={LINK(row)}>CT/BD</Link>
const BDRD = ({row}) => <Link bundleData={true} reuseDom={true} path={LINK(row)}>CT/BD/RD</Link>
const FB = (props) => <FBL {...props}></FBL>
const FBCT = (props) => <FBL {...props} link={{reuseFrame:true}}>CT</FBL>
const FBCTBD = (props) => <FBL {...props} link={{reuseFrame:true, bundleData:true}}>CT/BD</FBL>
const FBCTRD = (props) => <FBL {...props} link={{reuseFrame:true, reuseDom:true}}>CT/RD</FBL>
const FBCTBDRD = (props) => <FBL {...props} link={{reuseFrame:true, bundleData:true, reuseDom:true}}>CT/BD/RD</FBL>

// Frameback Link.
class FBL extends React.Component {
constructor(props){
super(props);
this.state = {available: true};
}
componentDidMount() {
if (window.__reactServerIsFrame) {
this.setState({available: false});
}
}
render() {
return <Link path={LINK(this.props.row)} frameback={true} {...this.props.link}>
<span className={this.state.available?'available':'not-available'}>FB</span>{
this.props.children?['/',...React.Children.toArray(this.props.children)]:[]
}
</Link>
}
}


export default class NavigationPlaygroundPage {
handleRoute(next) {
Expand All @@ -131,8 +105,6 @@ export default class NavigationPlaygroundPage {
<li>CT: Client Transition</li>
<li>RD: Reuse DOM</li>
<li>BD: Bundle Data</li>
<li>FB: Frameback</li>
<li><span className='not-available'>FB</span>: Frameback disabled (already in a frame)</li>
</ul>
</RootContainer>,
...this.data.map(promise => <RootContainer when={promise} className="row">
Expand All @@ -146,11 +118,6 @@ export default class NavigationPlaygroundPage {
<RD />
<BD />
<BDRD />
<FB />
<FBCT />
<FBCTBD />
<FBCTRD />
<FBCTBDRD />
</RootContainer>),
]
}
Expand Down
132 changes: 22 additions & 110 deletions packages/react-server/core/ClientController.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ var React = require('react'),
History = require('./components/History'),
PageUtil = require("./util/PageUtil"),
ReactServerAgent = require('./ReactServerAgent'),
FramebackController = require('./FramebackController'),
{getRootElementAttributes} = require('./components/RootElement'),
{PAGE_LINK_NODE_ID, PAGE_CONTAINER_NODE_ID} = require('./constants');

Expand Down Expand Up @@ -106,82 +105,18 @@ class ClientController extends EventEmitter {
:new Date; // There's no naviagation. We're it.

const url = request.getUrl();
const FC = this.context.framebackController;
const isPush = type === History.events.PUSHSTATE;
const shouldEnterFrame = request.getFrameback() && (
// A push to a frame, or a pop _from_ a previous push.
isPush || ((this._lastState||{}).reactServerFrame||{})._framebackExit
);

// This is who we're going to listen to regarding when navigation is
// complete for timing purposes. By default it's our navigator, but
// if we're going to do a frameback navigation we'll listen to the
// frameback controller instead.

// This is the navigator we're going to listen to regarding when navigation
// is complete for timing purposes.
let navigationTimingAuthority = this.context.navigator;

this._reuseDom = request.getReuseDom();

// If we're _entering_ a frame or we're _already in_ a frame
// then we'll delegate navigation to the frameback controller,
// which will tell the client controller within the frame what
// to do.
if (shouldEnterFrame || FC.isActive()) {

// Tell the navigator we got this one.
this.context.navigator.ignoreCurrentNavigation();

// This only happens on a popstate.
if (request.getOpts()._framebackExit) {

// That was fun!
FC.navigateBack();
setTimeout(() => {

// Need to do this in a new time slice
// to get order of events right in
// external subscribers.
this.context.navigator.finishRoute();
});

} else {

// We're going to let the navigator unlock navigation (via
// back button) as soon as our frame starts loading. This is
// nice from an interactivity perspective. But we still want
// to know how long it actually took to load the content in
// the frame. For that we'll listen to the frameback
// controller.
navigationTimingAuthority = FC;

// Here we go...
FC.navigate(request).then(() => {
this.context.navigator.finishRoute();
});
}

} else if (this._previouslyRendered) {

// If we're supposed to exit a frame, and we don't
// have one open, then we need to do a full browser
// navigation. There's no provision for client
// transitions between the outer page and the frame.
if (request.getOpts()._framebackExit) {

// This is just so the navigator doesn't try
// to proceed with an ordinary navigation.
// This whole window is toast.
this.context.navigator.ignoreCurrentNavigation();

// Start from scratch with current URL (we've
// just popped).
document.location.reload();
if (this._previouslyRendered) {

// That's all, folks.
return;
}

// If this is a secondary request (client transition)
// within a session, then we'll get a fresh
// This is a secondary request (client transition)
// within a session, so we'll get a fresh
// RequestLocalStorage container.
RequestLocalStorage.startRequest();

Expand All @@ -197,15 +132,14 @@ class ClientController extends EventEmitter {
}

// If this is a History.events.PUSHSTATE navigation,
// and we have control of the navigation bar (we're
// not in a frameback frame) we should change the URL
// in the location bar before rendering.
// and we have control of the navigation bar we should
// change the URL in the location bar before rendering.
//
// Note that for browsers that do not have pushState,
// this will result in a window.location change and
// full browser load.
//
if (this._history && this._history.hasControl()) {
if (this._history) {

if (isPush) {

Expand All @@ -231,20 +165,10 @@ class ClientController extends EventEmitter {
}

this._setHistoryRequestOpts({

// If we're entering a frame, then
// when we get back here we need to
// exit.
_framebackExit: request.getFrameback(),

// If we're reusing the DOM on the way
// forward, then we can also reuse on
// the way back.
reuseDom: request.getReuseDom(),

// The same reasoning as for
// `reuseDom` also applies here.
reuseFrame: request.getReuseFrame(),
});

this._history.pushState(
Expand Down Expand Up @@ -283,34 +207,24 @@ class ClientController extends EventEmitter {
reuseDom: true,
});
}
} else if (this._history) {

// We're in a frameback frame, but we want to make sure that the
// frame's `document.location` stays up to date.
window.history.replaceState(null, null, url);
}

// If we've got control of the URL bar we'll also take responsibility
// for logging how long the request took in a variety of ways:
// logging how long the request took in a variety of ways:
// - Request type (pageload, pushstate, popstate)
// - Request options (reuseDom, bundleData, etc)
if (!window.__reactServerIsFrame) {
navigationTimingAuthority.once('loadComplete', () => {
const bas = `handleRequest`;
const typ = `type.${type||'PAGELOAD'}`;
logTimingData(`${bas}.all`, t0);
logTimingData(`${bas}.${typ}.all`, t0);
_.forEach(request.getOpts(), (val, key) => {
if (val) {
const opt = `opt.${key}`;
logTimingData(`${bas}.${opt}`, t0);
logTimingData(`${bas}.${typ}.${opt}`, t0);
}
});
navigationTimingAuthority.once('loadComplete', () => {
const bas = `handleRequest`;
const typ = `type.${type||'PAGELOAD'}`;
logTimingData(`${bas}.all`, t0);
logTimingData(`${bas}.${typ}.all`, t0);
_.forEach(request.getOpts(), (val, key) => {
if (val) {
const opt = `opt.${key}`;
logTimingData(`${bas}.${opt}`, t0);
logTimingData(`${bas}.${typ}.${opt}`, t0);
}
});
}


});

this._lastState = history.state;
}
Expand Down Expand Up @@ -937,8 +851,6 @@ function buildContext(routes) {

context.setMobileDetect(new MobileDetect(navigator.userAgent));

context.setFramebackController(new FramebackController());

return context;
}

Expand Down
19 changes: 0 additions & 19 deletions packages/react-server/core/ClientRequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,12 @@ class ClientRequest {

constructor(url, {
bundleData,
frameback,
reuseDom,
reuseFrame,

// These are for internal statekeeping. Don't use them yourself.
_framebackExit,
_fromOuterFrame,
}={}) {
this._url = url;
this._opts = {
bundleData,
frameback,
reuseDom,
reuseFrame,
_framebackExit,
_fromOuterFrame,
}
}

Expand All @@ -39,18 +29,10 @@ class ClientRequest {
return this._opts;
}

getFrameback() {
return this._opts.frameback;
}

getReuseDom() {
return this._opts.reuseDom;
}

getReuseFrame() {
return this._opts.reuseFrame;
}

getBundleData() {
return this._opts.bundleData;
}
Expand Down Expand Up @@ -120,7 +102,6 @@ class ClientRequest {
console.error("ClientRequest.getBody not implemented.");
}


}

module.exports = ClientRequest;
Loading

0 comments on commit 65e0d7a

Please sign in to comment.