-
Notifications
You must be signed in to change notification settings - Fork 81
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Force Google Docs to use HTML mode instead of canvas mode
Google Docs new canvas mode hides all text/dom from rikaikun and thus for rikaikun to work Google has provided a workaround. Fixes #593
- Loading branch information
Showing
6 changed files
with
174 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
function forceHtml(force: boolean) { | ||
if (!force) { | ||
return; | ||
} | ||
console.log( | ||
'rikaikun is forcing Docs to use HTML instead of canvas for rendering.' | ||
); | ||
const injectedCode = `(function() {window['_docs_force_html_by_ext'] = '${chrome.runtime.id}';})();`; | ||
|
||
const script = document.createElement('script'); | ||
|
||
script.textContent = injectedCode; | ||
|
||
// Usually, `document.head` isn't guaranteed to be present when content_scripts run but in this case | ||
// we're running inside a callback so it should be 100% safe. | ||
document.head.appendChild(script); | ||
} | ||
|
||
// This check allows the user to get newer Docs Canvas without disabling rikaikun. | ||
// This delays when the forcing code is injected but it seems to be early enough in practice. | ||
chrome.runtime.sendMessage({ type: 'forceDocsHtml?' }, forceHtml); | ||
|
||
export { forceHtml as TestOnlyForceHtml }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import { RcxMain } from '../rikaichan'; | ||
import { expect, use } from '@esm-bundle/chai'; | ||
import chrome from 'sinon-chrome'; | ||
import sinon from 'sinon'; | ||
import sinonChai from 'sinon-chai'; | ||
|
||
use(sinonChai); | ||
|
||
let rcxMain: RcxMain; | ||
|
||
describe('background.ts', () => { | ||
before(async () => { | ||
// Resolve config fetch with minimal config object. | ||
chrome.storage.sync.get.yields({ kanjiInfo: [] }); | ||
// Imports only run once so run in `before` to make it deterministic. | ||
rcxMain = await (await import('../background')).TestOnlyRxcMainPromise; | ||
}); | ||
|
||
beforeEach(() => { | ||
// Only reset the spies we're using since we need to preserve | ||
// the state of `chrome.runtime.onMessage.addListener` for invoking | ||
// the core functionality of background.ts. | ||
chrome.tabs.sendMessage.reset(); | ||
}); | ||
|
||
describe('when sent "forceDocsHtml?" message', () => { | ||
it('should not call response callback when rikaikun disabled', async () => { | ||
rcxMain.enabled = 0; | ||
const responseCallback = sinon.spy(); | ||
|
||
await sendMessageToBackground({ | ||
type: 'forceDocsHtml?', | ||
responseCallback: responseCallback, | ||
}); | ||
|
||
expect(responseCallback).to.have.not.been.called; | ||
}); | ||
|
||
it('should not send "showPopup" message when rikaikun disabled', async () => { | ||
rcxMain.enabled = 0; | ||
|
||
await sendMessageToBackground({ | ||
type: 'forceDocsHtml?', | ||
}); | ||
|
||
expect(chrome.tabs.sendMessage).to.have.not.been.called; | ||
}); | ||
|
||
it('should pass true to response callback when rikaikun enabled', async () => { | ||
rcxMain.enabled = 1; | ||
const responseCallback = sinon.spy(); | ||
|
||
await sendMessageToBackground({ | ||
type: 'forceDocsHtml?', | ||
responseCallback: responseCallback, | ||
}); | ||
|
||
expect(responseCallback).to.have.been.calledOnceWith(true); | ||
}); | ||
|
||
it('should send "showPopup" message when rikaikun enabled', async () => { | ||
rcxMain.enabled = 1; | ||
|
||
await sendMessageToBackground({ | ||
type: 'forceDocsHtml?', | ||
}); | ||
|
||
expect(chrome.tabs.sendMessage).to.have.been.calledWith( | ||
/* tabId= */ sinon.match.any, | ||
sinon.match({ type: 'showPopup' }) | ||
); | ||
}); | ||
}); | ||
}); | ||
|
||
async function sendMessageToBackground({ | ||
type, | ||
responseCallback = () => {}, | ||
}: { | ||
type: string; | ||
responseCallback?: Function; | ||
}): Promise<void> { | ||
return await chrome.runtime.onMessage.addListener.yield( | ||
{ type: type }, | ||
{ tab: { id: 0 } }, | ||
responseCallback | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
//import '../background'; | ||
import { expect, use } from '@esm-bundle/chai'; | ||
import chrome from 'sinon-chrome'; | ||
|
||
declare global { | ||
interface Window { | ||
_docs_force_html_by_ext?: string; | ||
} | ||
} | ||
|
||
let forceHtmlCallback: (force: boolean) => void; | ||
|
||
describe('docs-html-fallback.ts after sending `forceDocsHtml?` message', () => { | ||
before(async () => { | ||
await import('../docs-html-fallback'); | ||
forceHtmlCallback = chrome.runtime.sendMessage.args[0][1]; | ||
}); | ||
|
||
beforeEach(() => { | ||
chrome.reset(); | ||
window._docs_force_html_by_ext = undefined; | ||
}); | ||
|
||
describe('when `forceHtml` callback is called with `false`', () => { | ||
it('should not add special property to window object', async () => { | ||
forceHtmlCallback(false); | ||
|
||
expect(window._docs_force_html_by_ext).to.be.undefined; | ||
}); | ||
}); | ||
|
||
describe('when `forceHtml` callback is called with `true`', () => { | ||
it('should set special property to rikaikun extension ID', async () => { | ||
chrome.runtime.id = 'test_special_id'; | ||
|
||
forceHtmlCallback(true); | ||
|
||
expect(window._docs_force_html_by_ext).to.equal(chrome.runtime.id); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters