Skip to content

Commit 3649c0a

Browse files
authored
Improve event synchronization (#4)
1 parent 3cabc58 commit 3649c0a

7 files changed

+38
-200
lines changed

src/WinWebDiffLib/DiffHighlighter.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -1148,10 +1148,10 @@ class Highlighter
11481148
{
11491149
wchar_t styleValue[256];
11501150
if (color == 0xFFFFFFFF)
1151-
swprintf_s(styleValue, L"background-color: #%02x%02x%02x;",
1151+
swprintf_s(styleValue, L"background-color: #%02x%02x%02x !important;",
11521152
GetRValue(backcolor), GetGValue(backcolor), GetBValue(backcolor));
11531153
else
1154-
swprintf_s(styleValue, L"color: #%02x%02x%02x; background-color: #%02x%02x%02x;",
1154+
swprintf_s(styleValue, L"color: #%02x%02x%02x; background-color: #%02x%02x%02x !important;",
11551155
GetRValue(color), GetGValue(color), GetBValue(color),
11561156
GetRValue(backcolor), GetGValue(backcolor), GetBValue(backcolor));
11571157
return styleValue;

src/WinWebDiffLib/Resource.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#define ID_STOP 103
99
#define IDD_DIALOGBAR 103
1010
#define IDC_DIFFMAP 112
11+
#define IDR_SCRIPT 130
1112
#define IDC_MENU 1021
1213
#define IDC_ZOOM 1022
1314
#define IDC_WIDTH 1023
@@ -19,7 +20,7 @@
1920
#ifdef APSTUDIO_INVOKED
2021
#ifndef APSTUDIO_READONLY_SYMBOLS
2122
#define _APS_NO_MFC 1
22-
#define _APS_NEXT_RESOURCE_VALUE 129
23+
#define _APS_NEXT_RESOURCE_VALUE 131
2324
#define _APS_NEXT_COMMAND_VALUE 32771
2425
#define _APS_NEXT_CONTROL_VALUE 1003
2526
#define _APS_NEXT_SYMED_VALUE 110

src/WinWebDiffLib/WebDiffWindow.hpp

+21-196
Original file line numberDiff line numberDiff line change
@@ -6,200 +6,6 @@
66
#include <shellapi.h>
77
#include <wil/win32_helpers.h>
88

9-
const wchar_t* scriptOnLoad =
10-
LR"(
11-
(function() {
12-
window.wdw = { "inClick": false/*, "inSubmit": false, "inKeydown": false*/ };
13-
function syncScroll(e) {
14-
var el = document.querySelector(e.selector);
15-
if (el && getWindowLocation() === e.window) {
16-
var sleft = Math.round((el.scrollWidth - el.clientWidth) * e.left);
17-
var stop = Math.round((el.scrollHeight - el.clientHeight) * e.top);
18-
clearTimeout(wdw.timeout);
19-
wdw.timeout = setTimeout(function() {
20-
if (el.scroll)
21-
{
22-
window.removeEventListener('scroll', onScroll, true);
23-
el.scroll(sleft, stop);
24-
setTimeout(function() { window.addEventListener('scroll', onScroll, true); }, 10);
25-
}
26-
}, 100);
27-
}
28-
}
29-
function syncClick(e) {
30-
var el = document.querySelector(e.selector);
31-
if (el && getWindowLocation() === e.window) {
32-
wdw.inClick = true;
33-
if (el.click)
34-
el.click();
35-
wdw.inClick = false;
36-
}
37-
}
38-
function syncInput(e) {
39-
var el = document.querySelector(e.selector);
40-
if (el && getWindowLocation() === e.window) {
41-
el.value = e.value;
42-
}
43-
}
44-
/*
45-
function syncSubmit(e) {
46-
var el = document.querySelector(e.selector);
47-
if (el && getWindowLocation() === e.window) {
48-
wdw.inSubmit = true;
49-
if (el.submit)
50-
el.submit();
51-
wdw.inSubmit = false;
52-
}
53-
}
54-
function syncKeydown(e) {
55-
var el = document.querySelector(e.selector);
56-
if (el && getWindowLocation() === e.window) {
57-
wdw.inKeydown = true;
58-
var ev = new KeyboardEvent("keydown", e);
59-
if (el.dispatchEvent)
60-
el.dispatchEvent(ev);
61-
wdw.inKeydown = false;
62-
}
63-
}
64-
*/
65-
function getWindowLocation() {
66-
let locationString = '';
67-
let currentWindow = window;
68-
69-
while (currentWindow !== window.top) {
70-
const frames = currentWindow.parent.frames;
71-
let index = -1;
72-
for (let i = 0; i < frames.length; i++) {
73-
if (frames[i] === currentWindow) {
74-
index = i;
75-
break;
76-
}
77-
}
78-
if (index !== -1) {
79-
locationString = `[${index}]` + locationString;
80-
} else {
81-
locationString = 'top' + locationString;
82-
}
83-
currentWindow = currentWindow.parent;
84-
}
85-
86-
return locationString;
87-
}
88-
function getElementSelector(element) {
89-
if (!(element instanceof Element)) {
90-
return null;
91-
}
92-
93-
const selectorList = [];
94-
while (element.parentNode) {
95-
let nodeName = element.nodeName.toLowerCase();
96-
if (element.id) {
97-
selectorList.unshift(`#${element.id}`);
98-
break;
99-
} else {
100-
let sibCount = 0;
101-
let sibIndex = 0;
102-
const siblings = element.parentNode.childNodes;
103-
for (let i = 0; i < siblings.length; i++) {
104-
const sibling = siblings[i];
105-
if (sibling.nodeType === 1) {
106-
if (sibling === element) {
107-
sibIndex = sibCount;
108-
}
109-
if (sibling.nodeName.toLowerCase() === nodeName) {
110-
sibCount++;
111-
}
112-
}
113-
}
114-
if (sibIndex > 0) {
115-
nodeName += `:nth-of-type(${sibIndex + 1})`;
116-
}
117-
selectorList.unshift(nodeName);
118-
element = element.parentNode;
119-
}
120-
}
121-
return selectorList.join(' > ');
122-
}
123-
function onScroll(e) {
124-
var el = ('scrollingElement' in e.target) ? e.target.scrollingElement : e.target;
125-
var sel = getElementSelector(el);
126-
var msg = {
127-
"event": "scroll",
128-
"window": getWindowLocation(),
129-
"selector": sel,
130-
"left": ((el.scrollWidth == el.clientWidth) ? 0 : (el.scrollLeft / (el.scrollWidth - el.clientWidth))),
131-
"top": ((el.scrollHeight == el.clientHeight) ? 0 : (el.scrollTop / (el.scrollHeight - el.clientHeight)))
132-
};
133-
window.chrome.webview.postMessage(JSON.stringify(msg));
134-
}
135-
function onClick(e) {
136-
if (wdw.inClick)
137-
return;
138-
var sel = getElementSelector(e.target);
139-
var msg = { "event": "click", "window": getWindowLocation(), "selector": sel };
140-
window.chrome.webview.postMessage(JSON.stringify(msg));
141-
}
142-
function onInput(e) {
143-
var sel = getElementSelector(e.target);
144-
var msg = { "event": "input", "window": getWindowLocation(), "selector": sel, "value": e.target.value };
145-
window.chrome.webview.postMessage(JSON.stringify(msg));
146-
}
147-
function onDblClick(e) {
148-
var el = e.target;
149-
var sel = getElementSelector(el);
150-
var wwdid = ('wwdid' in el.dataset) ? el.dataset['wwdid'] : (('wwdid' in el.parentElement.dataset) ? el.parentElement.dataset['wwdid'] : -1);
151-
var msg = { "event": "dblclick", "window": getWindowLocation(), "selector": sel, "wwdid": parseInt(wwdid) };
152-
window.chrome.webview.postMessage(JSON.stringify(msg));
153-
}
154-
function onMessage(arg) {
155-
var data = arg.data;
156-
switch (data.event) {
157-
case "scroll":
158-
syncScroll(data);
159-
break;
160-
case "click":
161-
syncClick(data);
162-
break;
163-
case "input":
164-
syncInput(data);
165-
break;
166-
/*
167-
case "submit":
168-
syncSubmit(data);
169-
break;
170-
case "keydown":
171-
syncKeydown(data);
172-
break;
173-
*/
174-
}
175-
}
176-
window.addEventListener('click', onClick, true);
177-
window.addEventListener('input', onInput, true);
178-
window.addEventListener('dblclick', onDblClick, true);
179-
window.addEventListener('scroll', onScroll, true);
180-
window.chrome.webview.addEventListener('message', onMessage);
181-
/*
182-
var forms = document.querySelectorAll('form');
183-
forms.forEach(function(form) {
184-
form.addEventListener('submit', function(e) {
185-
if (wdw.inSubmit)
186-
return;
187-
var sel = getElementSelector(e.target);
188-
var msg = { "event": "submit", "window": getWindowLocation(), "selector": sel };
189-
window.chrome.webview.postMessage(JSON.stringify(msg));
190-
});
191-
}, true);
192-
window.addEventListener('keydown', function(e) {
193-
if (wdw.inKeydown)
194-
return;
195-
var sel = getElementSelector(e.target);
196-
var msg = { "event": "keydown", "window": getWindowLocation(), "selector": sel, "altKey": e.altKey, "code": e.code, "ctrlKey": e.ctrlKey, "isComposing": e.isComposing, "key": e.key, "locale": e.locale, "location": e.location, "metaKey": e.metaKey, "repeat": e.repeat, "shiftKey": e.shiftKey };
197-
window.chrome.webview.postMessage(JSON.stringify(msg));
198-
}, true);
199-
*/
200-
})();
201-
)";
202-
2039
class CWebDiffWindow : public IWebDiffWindow
20410
{
20511
public:
@@ -359,6 +165,11 @@ class CWebDiffWindow : public IWebDiffWindow
359165
else if (event == WebDiffEvent::WebMessageReceived || event == WebDiffEvent::FrameWebMessageReceived)
360166
{
361167
std::wstring msg = m_webWindow[i].GetWebMessage();
168+
#ifdef _DEBUG
169+
wchar_t buf[4096];
170+
wsprintfW(buf, L"WebMessageReceived(pane:%d): %s\n", ev.pane, msg.c_str());
171+
OutputDebugString(buf);
172+
#endif
362173
WDocument doc;
363174
doc.Parse(msg.c_str());
364175
std::wstring event = doc.HasMember(L"event") ? doc[L"event"].GetString() : L"";
@@ -1009,7 +820,7 @@ class CWebDiffWindow : public IWebDiffWindow
1009820

1010821
HRESULT addEventListener(IUnknown* sender, int pane, IWebDiffCallback* callback)
1011822
{
1012-
return m_webWindow[pane].ExecuteScript(sender, scriptOnLoad, callback);
823+
return m_webWindow[pane].ExecuteScript(sender, GetScriptOnLoad(), callback);
1013824
}
1014825

1015826
HRESULT syncEvent(int srcPane, const std::wstring& json)
@@ -1629,6 +1440,21 @@ class CWebDiffWindow : public IWebDiffWindow
16291440
return fp != nullptr ? S_OK : (GetLastError() == 0 ? E_FAIL : HRESULT_FROM_WIN32(GetLastError()));
16301441
}
16311442

1443+
static wchar_t* GetScriptOnLoad()
1444+
{
1445+
LPVOID pData = nullptr;
1446+
HMODULE hModule = GetModuleHandle(L"WinWebDiffLib.dll");
1447+
HRSRC hResource = FindResource(hModule, MAKEINTRESOURCE(IDR_SCRIPT), RT_RCDATA);
1448+
if (hResource) {
1449+
HGLOBAL hLoadedResource = LoadResource(hModule, hResource);
1450+
if (hLoadedResource) {
1451+
pData = LockResource(hLoadedResource);
1452+
FreeResource(hLoadedResource);
1453+
}
1454+
}
1455+
return reinterpret_cast<wchar_t*>(pData) + 1/*bom*/;
1456+
}
1457+
16321458
int m_nPanes = 0;
16331459
HWND m_hWnd = nullptr;
16341460
HINSTANCE m_hInstance = nullptr;
@@ -1651,7 +1477,6 @@ class CWebDiffWindow : public IWebDiffWindow
16511477
bool m_bShowDifferences = true;
16521478
bool m_bShowWordDifferences = true;
16531479
bool m_bSynchronizeEvents = true;
1654-
bool m_bCompareCompleted = false;
16551480
unsigned m_eventSyncFlags = EVENT_SCROLL | EVENT_CLICK | EVENT_INPUT | EVENT_GOBACKFORWARD;
16561481
CompareState m_compareState = NOT_COMPARED;
16571482
IWebDiffWindow::ColorSettings m_colorSettings = {

src/WinWebDiffLib/WinWebDiffLib.js

23.3 KB
Binary file not shown.

src/WinWebDiffLib/WinWebDiffLib.rc

+9-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ BEGIN
105105
VALUE "FileDescription", "WinWebDiffLib"
106106
VALUE "FileVersion", STRFILEVER
107107
VALUE "InternalName", "WinWebDiffLib.dll"
108-
VALUE "LegalCopyright", "Copyright (C) 2022 [email protected]"
108+
VALUE "LegalCopyright", "Copyright (C) 2022-2023 [email protected]"
109109
VALUE "OriginalFilename", "WinWebDiffLib.dll"
110110
VALUE "ProductName", "WinWebDiffLib"
111111
VALUE "ProductVersion", STRPRODUCTVER
@@ -135,6 +135,14 @@ BEGIN
135135
PUSHBUTTON "Menu",IDC_MENU,6,0,61,12
136136
END
137137

138+
139+
/////////////////////////////////////////////////////////////////////////////
140+
//
141+
// SCRIPT
142+
//
143+
144+
IDR_SCRIPT RCDATA "WinWebDiffLib.js"
145+
138146
#endif // English (United States) resources
139147
/////////////////////////////////////////////////////////////////////////////
140148

src/WinWebDiffLib/WinWebDiffLib.vcxproj

+1
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@
288288
</ItemGroup>
289289
<ItemGroup>
290290
<None Include="packages.config" />
291+
<None Include="WinWebDiffLib.js" />
291292
<None Include="WinWebDiffLib.def" />
292293
</ItemGroup>
293294
<ItemGroup>

src/WinWebDiffLib/WinWebDiffLib.vcxproj.filters

+3
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@
5959
<None Include="WinWebDiffLib.def">
6060
<Filter>Source Files</Filter>
6161
</None>
62+
<None Include="WinWebDiffLib.js">
63+
<Filter>Resource Files</Filter>
64+
</None>
6265
</ItemGroup>
6366
<ItemGroup>
6467
<ResourceCompile Include="WinWebDiffLib.rc">

0 commit comments

Comments
 (0)