Skip to content
This repository has been archived by the owner on Sep 6, 2021. It is now read-only.

Added Reverse Inspect in Live Preview using WebSockets, and now forwa… #13044

Merged
merged 7 commits into from
Feb 14, 2017

Conversation

saurabh95
Copy link
Contributor

@saurabh95 saurabh95 commented Jan 17, 2017

Now you can click on any element in Live Preview and then corresponding HTML element will be highlighted and the cursor in code view will shift to the corresponding HTML element.

Features that need to be incorporated in this PR

  • Get Socket Port Number from preferences.
  • Add commands to create and destroy server and create server should be called only when user clicks on Live Preview button.

I am currently working on these. Will update the PR soon.

…rd inspect brings the html element in focus to the viewport in Live Preview
…eview and also now port is read from preferences file
Copy link
Collaborator

@ficristo ficristo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to have broken MultiBrowserLivePreview. At least using Firefox does throw some errors.
Also I thought that standard LivePreview was sort of deprecated and we should not add features to it.

@@ -130,7 +131,7 @@ define(function RemoteAgent(require, exports, module) {
_stopKeepAliveInterval();

// inject RemoteFunctions
var command = "window._LD=" + RemoteFunctions + "(" + LiveDevelopment.config.experimental + ");";
var command = "window._LD=" + RemoteFunctions + "(" + LiveDevelopment.config.experimental + "," + PreferencesManager.get("livedev.wsPort") + ");";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#12949 will change this to pass a config object, maybe you can already change it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have run all tests related to Live Preview, and now MultiBrowserPreview is also working fine.
Regarding passing of config object, once #12949 is merged, I will do the respective changes.

@@ -319,6 +319,10 @@ function RemoteFunctions(experimental) {
if (this.trigger) {
_trigger(element, "highlight", 1);
}

if (!window.event) {
element.scrollIntoViewIfNeeded();
Copy link
Collaborator

@ficristo ficristo Jan 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the current version of MDN, this function is supported only in Chrome, Opera and Safari.
I'm not familiar with LivePreview but this file is injected only in case of LivePreview with Chrome, or it is also used with MultiBrowserLivePreview?
In the second case, is it possible to change it to use scrollIntoView instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This script is injected in case of MultiBrowserLivePreview, for now the reverse-inspect doesn't work with the multibrowser, I will take up this task once this PR is merged.(I tried a hacky solution to make it work for multibrowser and it was working. I will raise another PR once I am done with proper solution)
Now, I am using window.scrollTo instead of scrollIntoViewIfNeeded.
I didn't use scrollIntoView because it aligns the element either to top or bottom, but I wanted to align it to center, so I have now used window.scrollTo which is supported by all browsers.


_ws.onmessage = function (evt) {
var received_msg = evt.data;
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you don't use it, remove it?


PreferencesManager.definePreference("livedev.wsPort", "number", 8125, {
description: Strings.DESCRIPTION_LIVEDEV_WEBSOCKET_PORT
});
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you are doing for LiveDevelopment, maybe you should do the same for MultiBrowserLivePreview too. See also #11957

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah once this is completed, I will try to do the same for multibrowser also.

// This transport provides a WebSocket connection between Brackets and a live browser preview.
// This is just a thin wrapper around the Node extension (WebSocketTransportDomain) that actually
// provides the WebSocket server and handles the communication. We also rely on an injected script in
// the browser for the other end of the transport.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably should be a JSDoc.

false, // this command is synchronous in Node
"Creates the WS server",
[
{name: "port", type: "number", description: "Port on which server needs to listen"}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put every param on its own line.

{
"name": "brackets-livedev-server",
"dependencies": {
"ws": "~0.4.31"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can put it on the root package.json and update the shrinkwrap file.
Right now, I don't think this works.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, right now we have to run npm install inside the node directory, to run this.
I am trying to figure out a way to move this to root package.json as suggested by you.

var marks = editor._codeMirror.getAllMarks(),
i,
markFound,
position;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

position is not used.

markFound,
position;

for (i = 0; i < marks.length; i++) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can replace this for with lodash

}
if (markFound) {
return markFound.find().from;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If markFound can be false maybe you should add a return value, otherwise add a console.error or something.

@ficristo
Copy link
Collaborator

I'm not really familiar with LivePreview to judge the approach. However I left some comments.

{name: "port", type: "number", description: "Port on which server needs to listen"}
],
[]
);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIt: newline here

function onDocumentClick(event) {
var element = event.target,
currentDataId,
newDataId;
Copy link
Collaborator

@petetnt petetnt Jan 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: newline here

@@ -1362,6 +1369,7 @@ define(function LiveDevelopment(require, exports, module) {
// wait for server (StaticServer, Base URL or file:)
prepareServerPromise
.done(function () {
WebSocketTransport.createWebSocketServer(PreferencesManager.get("livedev.wsPort"));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See @ficristo's comment above about the MultiBrowserLivePreview 👍

[
{name: "msg", type: "string", description: "JSON message from client page"}
]
);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Newline here

_domainManager = domainManager;
if (!domainManager.hasDomain("webSocketTransport")) {
domainManager.registerDomain("webSocketTransport", {major: 0, minor: 1});
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Newline here

@petetnt
Copy link
Collaborator

petetnt commented Jan 17, 2017

Left some small comments too, looking good so far 👍

if (element && element.hasAttribute('data-brackets-id')) {
_ws.send(JSON.stringify({
type: "message",
message: element.getAttribute('data-brackets-id')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The message is just the element id, correct? When sending messages in other direction (from Brackets to browser), the message has the format:

{ method: method, id: id, params: params }

It would be nice to do the same here so that's it's easier to add any new messages in the future.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually in multi-browser also we are sending the message from browser to brackets in the same format(NodeSocketTransportRemote.js), that's why I also used the same format, so that in future when we implement the same thing for multi-browser, we can have the same message to interpret in the brackets side.

@@ -0,0 +1,64 @@
/*
* Copyright (c) 2014 - present Adobe Systems Incorporated. All rights reserved.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copyright date for new files should be year that file was added (2017).

…ViewIfNeeded, added a check for port number in RemoteFunctions and some minor changes
@saurabh95
Copy link
Contributor Author

I have fixed some issues related to MultiBrowserLivePreview as RemoteFunctions.js was also included in MultiBrowserLivePreview. I have run the tests also, on both Firefox and Chrome.

@@ -22,15 +22,15 @@
*/

/*jslint forin: true */
/*global Node */
/*global Node, document */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use window.document instead of adding it as a global.


window.document.addEventListener("click", onDocumentClick);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is better to move this call in the onopen callback below and
add a removeEventListener in the onclose callback.
Otherwise the handler will be called also when the LivePreview is terminated.

@ficristo
Copy link
Collaborator

There are still a couple of unanswered comments.
Also in HTMLInstrumentation.js can you use lodash instead of the for.
_.find seems what you need.
Finally, you should check the tests and maybe add one?

@saurabh95
Copy link
Contributor Author

saurabh95 commented Jan 21, 2017

@ficristo, I just uploaded new changes, regarding the testing part, I was thinking of writing tests once I am done with MultiBrowserLivePreview as well(I am almost done with it), then I will write tests for both of them.
I have run the current LivePreview tests, and all are passing.

@petetnt @zaggino @marcelgerber @abose Please review

…h instead of for loop in HTMLInstrumentation.js
@saurabh95 saurabh95 force-pushed the saurabh95/ReverseInspect branch from 54e1e83 to aae3943 Compare January 21, 2017 18:30
@ficristo
Copy link
Collaborator

This does not work on distribution.
To verify

  • run grunt build
  • open Brackets with the Shift keyword pressed
  • select the index.html under dist/ folder

You have to adjust the copy task in Gruntfile.js

@saurabh95
Copy link
Contributor Author

Thanks @ficristo for pointing out. I have fixed this and also updated the PR :)

@ficristo
Copy link
Collaborator

I looked enough at this so approving but I see some failures on Live Preview tests, so please take a look.

@saurabh95
Copy link
Contributor Author

@ficristo Actually there is some problem with the timeout of the Live Preview tests, I increased the timeout and all the Live Preview tests are passing.

@saurabh95 saurabh95 added this to the Release 1.9 milestone Feb 3, 2017
@ficristo
Copy link
Collaborator

@saurabh95 the increase of timeout should be part of this PR?

@saurabh95
Copy link
Contributor Author

saurabh95 commented Feb 10, 2017

@ficristo Actually without my changes also some LivePreview tests(the same ones) were failing and on increasing timeout they were passing, so I thought we can take change it in some other set of changes, as it is independent of this change?
Anyway I will be taking up the task to write tests for my changes, we can then incorporate the changes related to timeout there itself.

Copy link
Collaborator

@petetnt petetnt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with few comments

@@ -319,6 +336,14 @@ function RemoteFunctions(experimental) {
if (this.trigger) {
_trigger(element, "highlight", 1);
}

if (!window.event && !isInViewport(element)) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: not sure why the window.event check is needed here? Something to do with legacy IE's?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am checking if there is any window event (mostly click event) is there on the LivePreview instance, then we don't need to bring the element in viewport, as it is already present in the viewport.

@@ -38,7 +38,8 @@
"dependencies": {
"anymatch": "1.3.0",
"chokidar": "1.6.0",
"lodash": "4.15.0"
"lodash": "4.15.0",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lodash has 4.17.4 out now, but feel free to left as is

Copy link
Collaborator

@swmitra swmitra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to be merged.

@swmitra
Copy link
Collaborator

swmitra commented Feb 14, 2017

Great work @saurabh95. This is indeed a great addition, keep more coming 👍

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants