Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 24 additions & 4 deletions src/LiveDevelopment/LiveDevMultiBrowser.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ define(function (require, exports, module) {
LiveDevProtocol = require("LiveDevelopment/MultiBrowserImpl/protocol/LiveDevProtocol"),
Metrics = require("utils/Metrics"),
WorkspaceManager = require("view/WorkspaceManager"),
FileSystem = require("filesystem/FileSystem"),
PageLoaderWorkerScript = require("text!LiveDevelopment/BrowserScripts/pageLoaderWorker.js");

// Documents
Expand Down Expand Up @@ -538,15 +539,34 @@ define(function (require, exports, module) {
}
}

let _lastPreviewedHTMLFilePath;
async function _resolveLivePreviewDocument() {
let activeDocument = DocumentManager.getCurrentDocument();
if(livePreviewUrlPinned){
return jsPromise(DocumentManager.getDocumentForPath(currentPreviewFilePath));
}
if (activeDocument && activeDocument.getLanguage().getId() === "html") {
_lastPreviewedHTMLFilePath = activeDocument.file.fullPath;
return activeDocument;
}
// if a css/js/non html file is active, we fall back to the last previewed HTML file
let fileExists = await FileSystem.existsAsync(_lastPreviewedHTMLFilePath);
if(!fileExists){
// the last previewed file may have been deleted
return activeDocument; // can be null
}
return jsPromise(DocumentManager.getDocumentForPath(_lastPreviewedHTMLFilePath));
}

ProjectManager.on(ProjectManager.EVENT_PROJECT_OPEN, ()=>{
_lastPreviewedHTMLFilePath = null;
});

/**
* Open a live preview on the current docuemnt.
*/
async function open() {
let doc = DocumentManager.getCurrentDocument();
if(livePreviewUrlPinned){
doc = await jsPromise(DocumentManager.getDocumentForPath(currentPreviewFilePath));
}
let doc = await _resolveLivePreviewDocument();

// wait for server (StaticServer, Base URL or file:)
_prepareServer(doc)
Expand Down
11 changes: 7 additions & 4 deletions src/document/DocumentCommandHandlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ define(function (require, exports, module) {
NewFileContentManager = require("features/NewFileContentManager"),
NodeConnector = require("NodeConnector"),
NodeUtils = require("utils/NodeUtils"),
ChangeHelper = require("editor/EditorHelper/ChangeHelper"),
_ = require("thirdparty/lodash");

const KernalModeTrust = window.KernalModeTrust;
Expand Down Expand Up @@ -1243,11 +1244,13 @@ define(function (require, exports, module) {
* USER_CANCELED object).
*/
function handleFileSave(commandData) {
// todo save interceptor
var activeEditor = EditorManager.getActiveEditor(),
const activeEditor = EditorManager.getActiveEditor(),
activeDoc = activeEditor && activeEditor.document,
doc = (commandData && commandData.doc) || activeDoc,
settings;
doc = (commandData && commandData.doc) || activeDoc;
let settings;
if(ChangeHelper._onBeforeSave(doc)){
return $.Deferred().reject().promise();
}

if (doc && !doc.isSaving) {
if (doc.isUntitled()) {
Expand Down
69 changes: 61 additions & 8 deletions src/editor/EditorHelper/ChangeHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
*
*/

/*global logger*/

/**
* Editor instance helpers change handling. Only to be used from Editor.js.
*/
Expand Down Expand Up @@ -175,9 +177,15 @@ define(function (require, exports, module) {

// Redispatch these CodeMirror key events as Editor events
function _onKeyEvent(instance, event) {
if(_keyEventInterceptor && _keyEventInterceptor(self, self._codeMirror, event)){
// the interceptor processed it, so don't pass it along to CodeMirror'
return;
if(_keyEventInterceptor){
try {
if(_keyEventInterceptor(self, self._codeMirror, event)){
// the interceptor processed it, so don't pass it along to CodeMirror'
return;
}
} catch (e) {
logger.reportError(e, "Error in key event interceptor");
}
}
self.trigger("keyEvent", self, event); // deprecated
self.trigger(event.type, self, event);
Expand Down Expand Up @@ -254,23 +262,35 @@ define(function (require, exports, module) {
self._codeMirror.on("cut", function(cm, e) {
// Let interceptor decide what to do with the event (including preventDefault)
if (_cutInterceptor) {
return _cutInterceptor(self, cm, e);
try {
return _cutInterceptor(self, cm, e);
} catch (e) {
logger.reportError(e, "Error in cut interceptor");
}
}
// Otherwise allow normal cut behavior
});

self._codeMirror.on("copy", function(cm, e) {
// Let interceptor decide what to do with the event (including preventDefault)
if (_copyInterceptor) {
return _copyInterceptor(self, cm, e);
try {
return _copyInterceptor(self, cm, e);
} catch (e) {
logger.reportError(e, "Error in copy interceptor");
}
}
// Otherwise allow normal copy behavior
});

self._codeMirror.on("paste", function(cm, e) {
// Let interceptor decide what to do with the event (including preventDefault)
if (_pasteInterceptor) {
return _pasteInterceptor(self, cm, e);
try {
return _pasteInterceptor(self, cm, e);
} catch (e) {
logger.reportError(e, "Error in paste interceptor");
}
}
// Otherwise allow normal paste behavior
});
Expand Down Expand Up @@ -316,19 +336,42 @@ define(function (require, exports, module) {

let _undoInterceptor = null;
let _redoInterceptor = null;
let _saveInterceptor = null;

function _onBeforeSave(docBeingSaved) {
if(!_saveInterceptor){
return false;
}
try{
return _saveInterceptor(docBeingSaved);
} catch (e) {
logger.reportError(e, "Error in save interceptor");
return false;
}
}

function _onBeforeUndo(editor, codeMirror, event) {
if(!_undoInterceptor){
return false;
}
return _undoInterceptor(editor, codeMirror, event);
try {
return _undoInterceptor(editor, codeMirror, event);
} catch (e) {
logger.reportError(e, "Error in undo interceptor");
return false;
}
}

function _onBeforeRedo(editor, codeMirror, event) {
if(!_redoInterceptor){
return false;
}
return _redoInterceptor(editor, codeMirror, event);
try {
return _redoInterceptor(editor, codeMirror, event);
} catch (e) {
logger.reportError(e, "Error in redo interceptor");
return false;
}
}

/**
Expand Down Expand Up @@ -379,9 +422,18 @@ define(function (require, exports, module) {
_keyEventInterceptor = interceptor;
}

/**
* Sets the key down/up/press interceptor function in codemirror
* @param {Function} interceptor - Function(editor, cm, event) that returns true to preventDefault
*/
function setSaveInterceptor(interceptor) {
_saveInterceptor = interceptor;
}

// private exports
exports._onBeforeUndo =_onBeforeUndo;
exports._onBeforeRedo = _onBeforeRedo;
exports._onBeforeSave = _onBeforeSave;

// public exports
exports.addHelpers = addHelpers;
Expand All @@ -391,4 +443,5 @@ define(function (require, exports, module) {
exports.setCopyInterceptor = setCopyInterceptor;
exports.setPasteInterceptor = setPasteInterceptor;
exports.setKeyEventInterceptor = setKeyEventInterceptor;
exports.setSaveInterceptor = setSaveInterceptor;
});
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ define(function (require, exports, module) {
return Phoenix.isNativeApp || !(Phoenix.browser.desktop.isSafari || Phoenix.browser.mobile.isIos);
}

let _lastPreviewedFilePath;

/**
* Finds out a {URL,filePath} to live preview from the project. Will return and empty object if the current
* file is not previewable.
Expand Down Expand Up @@ -179,33 +181,24 @@ define(function (require, exports, module) {
});
return;
} else if(utils.isPreviewableFile(fullPath)){
const filePath = httpFilePath || path.relative(projectRoot, fullPath);
// this is the case where the user has html/svg/any previewable file as the active document
_lastPreviewedFilePath = fullPath;
}
let fileExists = await FileSystem.existsAsync(_lastPreviewedFilePath);
if(_lastPreviewedFilePath && fileExists){
// user either has active document as a previewable file or this is the case where
// user switched to a css/js/other file that is not previewable, but we have on old previewable
// file we will just take the _lastPreviewedFilePath as active
const filePath = httpFilePath || path.relative(projectRoot, _lastPreviewedFilePath);
let URL = httpFilePath || `${projectRootUrl}${filePath}`;
resolve({
URL,
filePath: filePath,
fullPath: fullPath,
isMarkdownFile: utils.isMarkdownFile(fullPath),
isHTMLFile: utils.isHTMLFile(fullPath)
fullPath: _lastPreviewedFilePath,
isMarkdownFile: utils.isMarkdownFile(_lastPreviewedFilePath),
isHTMLFile: utils.isHTMLFile(_lastPreviewedFilePath)
});
return;
} else {
const currentLivePreviewDetails = LiveDevelopment.getLivePreviewDetails();
if(currentLivePreviewDetails && currentLivePreviewDetails.liveDocument
&& currentLivePreviewDetails.liveDocument.isRelated
&& currentLivePreviewDetails.liveDocument.isRelated(fullPath)){
fullPath = currentLivePreviewDetails.liveDocument.doc.file.fullPath;
const filePath = path.relative(projectRoot, fullPath);
let URL = `${projectRootUrl}${filePath}`;
resolve({
URL,
filePath: filePath,
fullPath: fullPath,
isMarkdownFile: utils.isMarkdownFile(fullPath),
isHTMLFile: utils.isHTMLFile(fullPath)
});
return;
}
}
}
resolve({
Expand Down Expand Up @@ -588,14 +581,16 @@ define(function (require, exports, module) {
if(!url.startsWith(_staticServerInstance.getBaseUrl())) {
return Promise.reject("Not serving content as url belongs to another phcode instance: " + url);
}
if(utils.isMarkdownFile(path) && currentFile && currentFile.fullPath === path){
const shouldServeRendered = ((path === _lastPreviewedFilePath)
|| (currentFile && currentFile.fullPath === path));
if(utils.isMarkdownFile(path) && shouldServeRendered){
return _getMarkdown(path);
}
if(_staticServerInstance){
return _staticServerInstance._getInstrumentedContent(path, url);
}
return Promise.reject("Cannot get content");
};
}

/**
* See BaseServer#start. Starts listenting to StaticServerDomain events.
Expand Down Expand Up @@ -712,6 +707,7 @@ define(function (require, exports, module) {
}

function _projectOpened(_evt, projectRoot) {
_lastPreviewedFilePath = null;
navigatorChannel.postMessage({
type: 'PROJECT_SWITCH',
projectRoot: projectRoot.fullPath
Expand Down
42 changes: 19 additions & 23 deletions src/extensionsIntegrated/Phoenix-live-preview/NodeStaticServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,9 @@ define(function (require, exports, module) {
return Promise.reject("Not serving content as url invalid: " + url);
}
const filePath = _staticServerInstance.urlToPath(url);
if(utils.isMarkdownFile(filePath) && currentFile && currentFile.fullPath === filePath){
const shouldServeRendered = ((filePath === _lastPreviewedFilePath)
|| (currentFile && currentFile.fullPath === path));
if(utils.isMarkdownFile(filePath) && shouldServeRendered){
return _getMarkdown(filePath);
}
if(_staticServerInstance){
Expand Down Expand Up @@ -580,6 +582,7 @@ define(function (require, exports, module) {
}

function _projectOpened(_evt, projectRoot) {
_lastPreviewedFilePath = null;
liveServerConnector.execPeer('navMessageProjectOpened', {
type: 'PROJECT_SWITCH',
projectRoot: projectRoot.fullPath
Expand Down Expand Up @@ -635,6 +638,8 @@ define(function (require, exports, module) {
return livePreviewTabs.size > 0;
}

let _lastPreviewedFilePath;

/**
* Finds out a {URL,filePath} to live preview from the project. Will return and empty object if the current
* file is not previewable.
Expand Down Expand Up @@ -703,33 +708,24 @@ define(function (require, exports, module) {
});
return;
} else if(utils.isPreviewableFile(fullPath)){
const relativeFilePath = httpFilePath || path.relative(projectRoot, fullPath);
let URL = httpFilePath || decodeURI(_staticServerInstance.pathToUrl(fullPath));
// this is the case where the user has html/svg/any previewable file as the active document
_lastPreviewedFilePath = fullPath;
}
let fileExists = await FileSystem.existsAsync(_lastPreviewedFilePath);
if(_lastPreviewedFilePath && fileExists){
// user either has active document as a previewable file or this is the case where
// user switched to a css/js/other file that is not previewable, but we have on old previewable
// file we will just take the _lastPreviewedFilePath as active
const relativeFilePath = httpFilePath || path.relative(projectRoot, _lastPreviewedFilePath);
let URL = httpFilePath || decodeURI(_staticServerInstance.pathToUrl(_lastPreviewedFilePath));
resolve({
URL,
filePath: relativeFilePath,
fullPath: fullPath,
isMarkdownFile: utils.isMarkdownFile(fullPath),
isHTMLFile: utils.isHTMLFile(fullPath)
fullPath: _lastPreviewedFilePath,
isMarkdownFile: utils.isMarkdownFile(_lastPreviewedFilePath),
isHTMLFile: utils.isHTMLFile(_lastPreviewedFilePath)
});
return;
} else {
const currentLivePreviewDetails = LiveDevelopment.getLivePreviewDetails();
if(currentLivePreviewDetails && currentLivePreviewDetails.liveDocument
&& currentLivePreviewDetails.liveDocument.isRelated
&& currentLivePreviewDetails.liveDocument.isRelated(fullPath)){
fullPath = currentLivePreviewDetails.liveDocument.doc.file.fullPath;
const relativeFilePath = httpFilePath || path.relative(projectRoot, fullPath);
let URL = httpFilePath || decodeURI(_staticServerInstance.pathToUrl(fullPath));
resolve({
URL,
filePath: relativeFilePath,
fullPath: fullPath,
isMarkdownFile: utils.isMarkdownFile(fullPath),
isHTMLFile: utils.isHTMLFile(fullPath)
});
return;
}
}
resolve({
URL: getNoPreviewURL(),
Expand Down
12 changes: 1 addition & 11 deletions src/extensionsIntegrated/Phoenix-live-preview/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -823,13 +823,7 @@ define(function (require, exports, module) {
currentLivePreviewURL = newSrc;
currentPreviewFile = previewDetails.fullPath;
}
const existingPreviewFile = $iframe && $iframe.attr('data-original-path');
const existingPreviewURL = $iframe && $iframe.attr('data-original-src');
if(isReload && previewDetails.isNoPreview && existingPreviewURL &&
existingPreviewFile && ProjectManager.isWithinProject(existingPreviewFile)) {
currentLivePreviewURL = existingPreviewURL;
currentPreviewFile = existingPreviewFile;
} else if(isReload){
if(isReload && previewDetails.isHTMLFile){
LiveDevelopment.openLivePreview();
}
let relativeOrFullPath= ProjectManager.makeProjectRelativeIfPossible(currentPreviewFile);
Expand All @@ -852,10 +846,6 @@ define(function (require, exports, module) {
$iframe = newIframe;
if(_isProjectPreviewTrusted()){
$iframe.attr('src', currentLivePreviewURL);
// we have to save src as the iframe src attribute may have redirected, and we cannot read it as its
// a third party domain once its redirected.
$iframe.attr('data-original-src', currentLivePreviewURL);
$iframe.attr('data-original-path', currentPreviewFile);
if(Phoenix.isTestWindow) {
window._livePreviewIntegTest.currentLivePreviewURL = currentLivePreviewURL;
window._livePreviewIntegTest.urlLoadCount++;
Expand Down
Loading
Loading