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

#7276 Live Preview highlight customization #12949

Merged
Merged
2 changes: 1 addition & 1 deletion src/LiveDevelopment/Agents/RemoteAgent.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ define(function RemoteAgent(require, exports, module) {
_stopKeepAliveInterval();

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

Inspector.Runtime.evaluate(command, function onEvaluate(response) {
if (response.error || response.wasThrown) {
Expand Down
189 changes: 169 additions & 20 deletions src/LiveDevelopment/Agents/RemoteFunctions.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,29 @@
* modules should define a single function that returns an object of all
* exported functions.
*/
function RemoteFunctions(experimental, remoteWSPort) {
function RemoteFunctions(config, remoteWSPort) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we can pass remoteWSPort as part of config only, something like config.remoteWSPort.
Then instead of checking for remoteWSPort in https://github.com/adobe/brackets/pull/12949/files#diff-a40df952af8fd1808c321dab548ae11aR1032, we can check for !experimental flag as we create websocket only when we are not using experimental live preview.
But I think you can leave this for later as you might have to make changes which are not relevant for this feature, once this is merged I can make the above changes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi, you're right. Unfortunetely I won't be accessible for a while, so I guess we could close this one and open new PRs as necessary, if that's OK.

"use strict";

var experimental;
if (!config) {
experimental = false;
} else {
experimental = config.experimental;
}
var lastKeepAliveTime = Date.now();
var req, timeout;
var animateHighlight = function (time) {
if(req) {
window.cancelAnimationFrame(req);
window.clearTimeout(timeout);
}
req = window.requestAnimationFrame(redrawHighlights);

timeout = setTimeout(function () {
window.cancelAnimationFrame(req);
req = null;
}, time * 1000);
};

/**
* @type {DOMEditHandler}
Expand Down Expand Up @@ -250,17 +269,147 @@ function RemoteFunctions(experimental, remoteWSPort) {
}
return false;
},

_makeHighlightDiv: function (element, doAnimation) {
var elementBounds = element.getBoundingClientRect(),
highlight = window.document.createElement("div"),
styles = window.getComputedStyle(element);
elementStyling = window.getComputedStyle(element),
transitionDuration = parseFloat(elementStyling.getPropertyValue('transition-duration')),
animationDuration = parseFloat(elementStyling.getPropertyValue('animation-duration'));

if (transitionDuration) {
animateHighlight(transitionDuration);
}

if (animationDuration) {
animateHighlight(animationDuration);
}

// Don't highlight elements with 0 width & height
if (elementBounds.width === 0 && elementBounds.height === 0) {
return;
}

var realElBorder = {
right: elementStyling.getPropertyValue('border-right-width'),
left: elementStyling.getPropertyValue('border-left-width'),
top: elementStyling.getPropertyValue('border-top-width'),
bottom: elementStyling.getPropertyValue('border-bottom-width')
};

var innerWidth = elementBounds.width - parseInt(realElBorder.left) - parseInt(realElBorder.right);
var innerHeight = elementBounds.height - parseInt(realElBorder.top) - parseInt(realElBorder.bottom);

var visualisations = {
horizontal: "left, right",
vertical: "top, bottom"
};

var drawPaddingRect = function(side) {
var elStyling = {};

if (visualisations.horizontal.indexOf(side) >= 0) {
elStyling['width'] = elementStyling.getPropertyValue('padding-' + side);
elStyling['height'] = innerHeight + "px";
elStyling['top'] = realElBorder.top;

} else {
elStyling['height'] = elementStyling.getPropertyValue('padding-' + side);
elStyling['width'] = innerWidth + "px";
elStyling['left'] = realElBorder.left;
}

elStyling[side] = realElBorder[side];
elStyling['position'] = 'absolute';

return elStyling;
};

var drawMarginRect = function(side) {
var elStyling = {};

var margin = [];
margin['right'] = parseInt(elementStyling.getPropertyValue('margin-right'));
margin['top'] = parseInt(elementStyling.getPropertyValue('margin-top'));
margin['bottom'] = parseInt(elementStyling.getPropertyValue('margin-bottom'));
margin['left'] = parseInt(elementStyling.getPropertyValue('margin-left'));


if(visualisations['horizontal'].indexOf(side) >= 0) {
elStyling['width'] = elementStyling.getPropertyValue('margin-' + side);
elStyling['height'] = elementBounds.height + margin['top'] + margin['bottom'] + "px";
elStyling['top'] = "-" + margin['top'] + "px";

} else {
elStyling['height'] = elementStyling.getPropertyValue('margin-' + side);
elStyling['width'] = elementBounds.width + "px";
elStyling['left'] = 0;
}

elStyling[side] = "-" + margin[side] + "px";
elStyling['position'] = 'absolute';

return elStyling;
};

var setVisibility = function (el) {
if (
!config.remoteHighlight.showPaddingMargin ||
parseInt(el.height, 10) <= 0 ||
parseInt(el.width, 10) <= 0
) {
el.display = 'none';
} else {
el.display = 'block';
}
};

var mainBoxStyles = config.remoteHighlight.stylesToSet;
mainBoxStyles['border'] = 'none';

var paddingVisualisations = [
drawPaddingRect('top'),
drawPaddingRect('right'),
drawPaddingRect('bottom'),
drawPaddingRect('left')
];

var marginVisualisations = [
drawMarginRect('top'),
drawMarginRect('right'),
drawMarginRect('bottom'),
drawMarginRect('left')
];

var setupVisualisations = function (arr, config) {
var i;
for (i = 0; i < arr.length; i++) {
setVisibility(arr[i]);

// Applies to every visualisationElement (padding or margin div)
arr[i]["box-sizing"] = "border-box";
arr[i]["transform"] = "none";
var el = window.document.createElement("div"),
styles = Object.assign(
{},
config,
arr[i]
);

_setStyleValues(styles, el.style);

highlight.appendChild(el);
}
};

setupVisualisations(
marginVisualisations,
config.remoteHighlight.marginStyling
);
setupVisualisations(
paddingVisualisations,
config.remoteHighlight.paddingStyling
);

highlight.className = HIGHLIGHT_CLASSNAME;

var offset = _screenOffset(element);
Expand All @@ -275,31 +424,25 @@ function RemoteFunctions(experimental, remoteWSPort) {
"padding": 0,
"position": "absolute",
"pointer-events": "none",
"border-top-left-radius": styles.borderTopLeftRadius,
"border-top-right-radius": styles.borderTopRightRadius,
"border-bottom-left-radius": styles.borderBottomLeftRadius,
"border-bottom-right-radius": styles.borderBottomRightRadius,
"border-top-left-radius": elementStyling.borderTopLeftRadius,
"border-top-right-radius": elementStyling.borderTopRightRadius,
"border-bottom-left-radius": elementStyling.borderBottomLeftRadius,
"border-bottom-right-radius": elementStyling.borderBottomRightRadius,
"border-style": "solid",
"border-width": "1px",
"border-color": "#00a2ff",
"box-shadow": "0 0 1px #fff",
"box-sizing": "border-box"
};

var mergedStyles = Object.assign({}, stylesToSet, config.remoteHighlight.stylesToSet);
Copy link
Collaborator

@ficristo ficristo Nov 29, 2016

Choose a reason for hiding this comment

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

I think Object.assign is not available on Linux (which uses Chrome 29). You could try to use lodash assign or extend instead.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Argh, you are right @ficristo. The age old Linux version is starting to become the IE8 of Brackets 😭

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Those are remote functions, so I cannot use _.assign there I guess until i inject it to the browser. Am I right?

I've left it as Object.assign, just for now - until I know what exactly am I supposed to do.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Actually as they are remote functions that are run on the browser, we can just use Object.assign right?

Copy link
Collaborator

Choose a reason for hiding this comment

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

You mean a real browser and not Brackets itself, right? (Not much familiar with LivePreview)
Then I suppose we can use Object.assign. Sorry for the noise...

Copy link
Contributor Author

@Worie Worie Nov 30, 2016

Choose a reason for hiding this comment

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

I cant test it on Linux, but it works well on OSX. Edit: Yeah, those are run in real browser.


var animateStartValues = {
"background-color": "rgba(0, 162, 255, 0.5)",
"opacity": 0
};
var animateStartValues = config.remoteHighlight.animateStartValue;

var animateEndValues = {
"background-color": "rgba(0, 162, 255, 0)",
"opacity": 1
};
var animateEndValues = config.remoteHighlight.animateEndValue;

var transitionValues = {
"-webkit-transition-property": "opacity, background-color",
"-webkit-transition-duration": "300ms, 2.3s",
"transition-property": "opacity, background-color",
"transition-property": "opacity, background-color, transform",
"transition-duration": "300ms, 2.3s"
};

Expand All @@ -311,7 +454,7 @@ function RemoteFunctions(experimental, remoteWSPort) {
}
}

_setStyleValues(stylesToSet, highlight.style);
_setStyleValues(mergedStyles, highlight.style);
_setStyleValues(
doAnimation ? animateStartValues : animateEndValues,
highlight.style
Expand Down Expand Up @@ -842,6 +985,11 @@ function RemoteFunctions(experimental, remoteWSPort) {
function getSimpleDOM() {
return JSON.stringify(_domElementToJSON(window.document.documentElement));
}

function updateConfig(newConfig) {
config = JSON.parse(newConfig);
return JSON.stringify(config);
}

// init
_editHandler = new DOMEditHandler(window.document);
Expand Down Expand Up @@ -894,6 +1042,7 @@ function RemoteFunctions(experimental, remoteWSPort) {
"highlightRule" : highlightRule,
"redrawHighlights" : redrawHighlights,
"applyDOMEdits" : applyDOMEdits,
"getSimpleDOM" : getSimpleDOM
"getSimpleDOM" : getSimpleDOM,
"updateConfig" : updateConfig
};
}
37 changes: 37 additions & 0 deletions src/LiveDevelopment/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,33 @@ define(function main(require, exports, module) {
description: Strings.DESCRIPTION_LIVE_DEV_MULTIBROWSER
});

// "livedev.remoteHighlight" preference
var PREF_REMOTEHIGHLIGHT = "remoteHighlight";
var remoteHighlightPref = prefs.definePreference(PREF_REMOTEHIGHLIGHT, "object", {
animateStartValue: {
"background-color": "rgba(0, 162, 255, 0.5)",
"opacity": 0
},
animateEndValue: {
"background-color": "rgba(0, 162, 255, 0)",
"opacity": 0.6
},
"paddingStyling": {
"border-width": "1px",
"border-style": "dashed",
"border-color": "rgba(0, 162, 255, 0.5)"
},
"marginStyling": {
"background-color": "rgba(21, 165, 255, 0.58)"
},
"stylesToSet": {
"border-width": "1px"
},
"showPaddingMargin": true
}, {
description: "LivePreview highlight settings"
});

/** Toggles or sets the preference **/
function _togglePref(key, value) {
var val,
Expand Down Expand Up @@ -302,6 +329,7 @@ define(function main(require, exports, module) {
/** Initialize LiveDevelopment */
AppInit.appReady(function () {
params.parse();
config.remoteHighlight = prefs.get(PREF_REMOTEHIGHLIGHT);

Inspector.init(config);
LiveDevelopment.init(config);
Expand Down Expand Up @@ -353,6 +381,15 @@ define(function main(require, exports, module) {
_setImplementation(prefs.get(PREF_MULTIBROWSER));
}
});

remoteHighlightPref
.on("change", function () {
config.remoteHighlight = prefs.get(PREF_REMOTEHIGHLIGHT);

if (LiveDevImpl && LiveDevImpl.status >= LiveDevImpl.STATUS_ACTIVE) {
LiveDevImpl.agents.remote.call("updateConfig",JSON.stringify(config));
}
});

});

Expand Down