Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prepare Timimi for saving TiddlyWiki Classic in Chrome #44

Open
YakovL opened this issue Apr 30, 2020 · 15 comments
Open

Prepare Timimi for saving TiddlyWiki Classic in Chrome #44

YakovL opened this issue Apr 30, 2020 · 15 comments

Comments

@YakovL
Copy link
Contributor

YakovL commented Apr 30, 2020

Currently, saving in Chrome doesn't work for TWC. Here's a quick note from #32, I'll expand it at some point (additional research required):

mozillaLoadFile and mozillaSaveFile are js functions that are defined in TWC that were used when Firefox was able to save changes to file system by itself. Like in TiddlyFox, the adjustments in Timimi that I've proposed include overwriting these functions.

In Chrome, however, restrictions are stronger and extension code has no direct access to the page JS so the functions can not be modified this way. I have to re-read some stuff to tell confidently, but as far as I understand, saving TWC in Chrome can only be implemented after modifying its core.

@ibnishak
Copy link
Owner

Actually JavaScript code in content-script.js does have access to the page -exactly same as Firefox. So by logical reasoning, it ought to work in the same way in both browsers.

@YakovL
Copy link
Contributor Author

YakovL commented May 4, 2020

Here's the problem: in Firefox

  • content-script.js injects patch-classic-io.js into the page
  • patch-classic-io.js modifies window.mozillaLoadFile and others;

in Chrome patch-classic-io.js is injected, but it gets a sandboxed context and window is not the same as window, so the change that patch-classic-io.js introduces doesn't really affect window.mozillaLoadFile etc of the page itself. That answer at SO suggests a hack that can help though. I'll probably give it a try soon; this will make the code ugly though because the whole patch-classic-io.js should be put as a JS string inside content-script.js.

@ibnishak
Copy link
Owner

ibnishak commented May 4, 2020

What if we add the code in the patch to the content-script itself - as a function? Instead of inject, we can call it as a function, right?

@YakovL
Copy link
Contributor Author

YakovL commented May 7, 2020

Not sure, could you provide a sample code?

The following seems to work:

  1. change injectExtensionScript to this:

    function injectExtensionScript(text) {
      const scriptElement = document.createElement("script");
      scriptElement.innerHTML = text;
      document.head.appendChild(scriptElement);
      scriptElement.remove();
    }
    
  2. call it (instead of injectExtensionScript('patch-classic.io)) like this:

  injectExtensionScript(`
	window.mozillaLoadFile = function(path) {
	  try {
		// Just read the file synchronously
		var xhReq = new XMLHttpRequest();
		xhReq.open("GET", "file:///" + encodeURIComponent(path), false);
		xhReq.send(null);
		return xhReq.responseText;
	  } catch(ex) {
		return false;
	  }
	};

	window.mozillaSaveFile = function(path, content) {
	  var messageBox = document.getElementById("tiddlyfox-message-box");
	  if(!messageBox) return false;

	  // Create the message element and put it into the message box
	  var message = document.createElement("div");
	  message.setAttribute("data-tiddlyfox-path", path);
	  message.setAttribute("data-tiddlyfox-content", content);
	  messageBox.appendChild(message);

	  // Create and dispatch the custom event to the extension
	  var event = document.createEvent("Events");
	  event.initEvent("tiddlyfox-save-file", true, false);
	  message.dispatchEvent(event);

	  return true;
	};

	// expose the supported I/O events
	window.eventBasedIO = {
		save: {
			name: 'tiddlyfox-save-file'
		},
		saved: {
			name: 'tiddlyfox-have-saved-file'
		}
	};`);

(sorry for ugly formatting, github markup makes it a bit difficult)

However, while this injecting works in extension edited locally, it doesn't seem to find the Timimi backend, so I've only succeeded with saving when activated both current Timimi extension and my local version. Any idea how can I fix this?

@ibnishak
Copy link
Owner

ibnishak commented May 7, 2020

You mean you want to create a local environment for testing purposes?

@YakovL
Copy link
Contributor Author

YakovL commented May 7, 2020

Yes, that would be helpful (so that I can create PRs with more confidence)

@YakovL
Copy link
Contributor Author

YakovL commented May 7, 2020

Actually, that worked in Firefox: I loaded Timimi extension from cloned and edited repo on local file system and it interacted with Timimi backend just like the main extension. Not sure why this is not the case in Chrome (well, in Vivaldi, I haven't tested this in Chrome yet)

@ibnishak
Copy link
Owner

ibnishak commented May 7, 2020

Yeah. Chrome works a little differently. You need to edit the timimi.json for it to work with chrome in testing environment.

@ibnishak
Copy link
Owner

ibnishak commented May 7, 2020

Here is what you have to do.
Uninstall timimi that you may have installed from chrome webstore
Load the unpacked extension to Chrome.
In the extension page, timimi will have an extension id. Copy that.
Now go to timimi.json and replace the extension id in that with the value you copied

@YakovL
Copy link
Contributor Author

YakovL commented May 8, 2020

well, this doesn't seem to be working. To be sure, I've retested in Chrome (instead of Vivaldi), but it's the same:

  1. I have installed the unpacked extension
  2. copied the id, opened <user folder>\AppData\Roaming\Timimi-Chrome\Timimi.json (is it the one?), changed allowed_origins by substituting the id
  3. opened TWC 2.9.2, checked that the script is injected (mozillaSaveFile changed etc), added some changes, (unchecked saving backups,) called saving

A message (more likely browser than native, white one with Timimi icon) appeared saying "Timimi save FAILED Error on contacting Timimi host" and the changes are not saved. I'll probably create a PR in parallel (not sure where the changes should go though: they can be used for Firefox too and it's not nice if the code is duplicated anyway, since further changes should be remembered to be put into both)

@YakovL
Copy link
Contributor Author

YakovL commented May 16, 2020

Hi Riz, any comments on this? What do you think about merging #48 so that we can use this minimal implementation in the next release and improve it further if needed?

@ibnishak
Copy link
Owner

Merged. Now the only thing we have to see is if it passes the chrome store's security check.

@YakovL
Copy link
Contributor Author

YakovL commented May 17, 2020

Great, thanks! Yeah, the security check is indeed is an interesting question because such code injection may be considered "hacky".

By the way, do you have any plans to de-duplicate code for Firefox and Chrome extensions? Like generate one from another, so that it is enough to introduce new changes only in one place.

@ibnishak
Copy link
Owner

The plan is to make the code similar in both eventually.

@YakovL
Copy link
Contributor Author

YakovL commented May 24, 2020

Hi Riz,

we have to see is if it passes the chrome store's security check

any news on this? What's the usual time they take to review an updated version?

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

No branches or pull requests

2 participants