Skip to content

Commit

Permalink
Another Solution to the Emoji Problem: Hack transformResponse
Browse files Browse the repository at this point in the history
- Hack `angular.bootstrap` to configure `$httpProvider.defaults.transformResponse`.
- Lock emoji messages as image messages.
  • Loading branch information
arrowrowe committed Feb 25, 2016
1 parent 90bc87f commit 477830d
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 69 deletions.
2 changes: 1 addition & 1 deletion src/inject-onload.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,4 @@ injectBundle.loginCSS = `
}
`;

module.exports = injectBundle;
module.exports = injectBundle;
92 changes: 36 additions & 56 deletions src/inject-preload.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,45 @@
const ipcRenderer = require('electron').ipcRenderer;
const menu = require('./menu.js');

// Prevent Wechat from disabling `console.log`.
const consoleReal = window.console;
Object.defineProperty(window, 'console', {
get: () => consoleReal,
const lock = (object, key, value) => Object.defineProperty(object, key, {
get: () => value,
set: () => {}
});

lock(window, 'console', window.console);

let angular = window.angular = {};
let angularBootstrapReal;
Object.defineProperty(angular, 'bootstrap', {
get: () => angularBootstrapReal ? function (element, moduleNames) {
const moduleName = 'webwxApp';
if (moduleNames.indexOf(moduleName) >= 0) {
let constants;
angular.injector(['ng', 'Services']).invoke(['confFactory', (confFactory) => (constants = confFactory)]);
angular.module(moduleName).config([
'$httpProvider',
($httpProvider) => {
$httpProvider.defaults.transformResponse.push((value) => {
if (typeof value === 'object' && value !== null && value.AddMsgList instanceof Array) {
value.AddMsgList.forEach((msg) => {
const rec = msg.Content.match(/^<msg><emoji.+cdnurl = "(.+?)".+thumburl = "(.+?)"/);
if (rec !== null) {
lock(msg, 'MsgType', constants.MSGTYPE_IMAGE);
lock(msg, 'MMPreviewSrc', rec[1]);
lock(msg, 'MMThumbSrc', rec[2]);
}
});
}
return value;
});
}
]);
}
return angularBootstrapReal.apply(angular, arguments);
} : angularBootstrapReal,
set: (real) => (angularBootstrapReal = real)
});

window.injectBundle = {};
injectBundle.getBadgeJS = () => {
$(".chat_list.scroll-content").bind('DOMSubtreeModified', () => {
Expand All @@ -32,56 +64,4 @@ injectBundle.getProfileNameJS = () => {
$('.display_name').ready(updateName).change(updateName);
};

injectBundle._replaceEmojiMessageJS = (msgId, imageUrl) => {
setTimeout(()=> {
let $bubble = $(`div.js_message_bubble:regex("${msgId}")`);
if (!$bubble) return;

$bubble.css('background', `url('${imageUrl}') no-repeat`)
.css('background-size', '120px')
.css('height', '120px')
.css('width', '120px');
$bubble.addClass('no_arrow');
$bubble.find('pre').text('')
.css('width', '120px');
}, 0);
};


injectBundle.updateEmojiListJS = (newList)=> {
newList = JSON.parse(newList);
window.emojiList = $.extend(window.emojiList, newList);
for (let msgId in newList) {
injectBundle._replaceEmojiMessageJS(msgId, window.emojiList[msgId]);
}
setTimeout(()=> {
let $scrollContent = $(".chat_bd.scroll-content");
$scrollContent.scrollTop($scrollContent[0].scrollHeight);
}, 50);
};

injectBundle.initEmojiListJS = ()=> {
$.expr[':'].regex = (elem, index, match) => {
var regex = new RegExp(match[3]),
$elem = $(elem);
return regex.test($elem.attr('data-cm'));
};

window.emojiList = {};
$('a.title_name').on('DOMSubtreeModified', () => {
for (let msgId in window.emojiList) {
injectBundle._replaceEmojiMessageJS(msgId, window.emojiList[msgId]);
}
});
$('.chat_bd.scroll-content').on('DOMNodeInserted', (ev) => {
if (ev.timeStamp - injectBundle._timestamp > 50) {
injectBundle._timestamp = ev.timeStamp;
for (let msgId in window.emojiList) {
injectBundle._replaceEmojiMessageJS(msgId, window.emojiList[msgId]);
}
}
})
};

injectBundle._timestamp = 0;
menu.create();
12 changes: 0 additions & 12 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ const messageHandler = require('./message.js');
const WINDOW_TITLE = 'Electronic WeChat';

let browserWindow = null;
//let emojiList = {};

let createWindow = () => {
browserWindow = new BrowserWindow({
Expand Down Expand Up @@ -65,23 +64,12 @@ let createWindow = () => {
console.log("Debugger detached due to : ", reason);
});

browserWindow.webContents.debugger.on('message', (event, method, params) => {
if (method == "Network.responseReceived" && params.type == "XHR") {
let promise = messageHandler.handleEmojiMessage(params.response, params.requestId, browserWindow.webContents.debugger);
promise.then((emojiList)=> {
if (Object.keys(emojiList).length == 0) return;
browserWindow.webContents.executeJavaScript(`injectBundle.updateEmojiListJS('${JSON.stringify(emojiList)}')`);
});
}
});

browserWindow.webContents.debugger.sendCommand("Network.enable");

browserWindow.webContents.on('dom-ready', () => {
browserWindow.webContents.insertCSS(injectBundle.loginCSS);
browserWindow.webContents.insertCSS(injectBundle.wechatCSS);
browserWindow.webContents.executeJavaScript(`injectBundle.getBadgeJS()`);
browserWindow.webContents.executeJavaScript(`injectBundle.initEmojiListJS()`);
});

browserWindow.webContents.on('new-window', (event, url) => {
Expand Down

2 comments on commit 477830d

@arrowrowe
Copy link
Owner Author

Choose a reason for hiding this comment

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

好像应该先 msg.MsgType === constants.MSGTYPE_EMOTICON 判断一下再正则, 不过直接正则也影响不大~

UPD: 还是在 7d25ecc 加了这个预判.

@geeyan
Copy link

@geeyan geeyan commented on 477830d Mar 24, 2016

Choose a reason for hiding this comment

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

👍👍👍

Please sign in to comment.