Skip to content

Instantly share code, notes, and snippets.

@XP1
Created April 26, 2013 11:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save XP1/5466945 to your computer and use it in GitHub Desktop.
Save XP1/5466945 to your computer and use it in GitHub Desktop.
Fix Yahoo! comments: Fixes Yahoo! comments in Opera 12.1x by constructing a multipart response manually.
// ==UserScript==
// @name Fix Yahoo! comments
// @version 1.00
// @description Fixes Yahoo! comments in Opera 12.1x by constructing a multipart response manually.
// @namespace https://gist.github.com/XP1/5466945/
// @copyright 2013
// @author XP1
// @homepage https://github.com/XP1/
// @license Apache License, Version 2.0; http://www.apache.org/licenses/LICENSE-2.0
// @include http*://news.yahoo.*/*
// @include http*://*.news.yahoo.*/*
// ==/UserScript==
/*
* Copyright 2013 XP1
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*jslint browser: true, vars: true, maxerr: 50, indent: 4 */
(function (window, Object, XMLHttpRequest) {
"use strict";
var before = function before(searchValue, fromIndex) {
return (this.substring(0, this.indexOf(searchValue, fromIndex)));
};
var beforeInclusive = function beforeInclusive(searchValue, fromIndex) {
return (this.substring(0, this.indexOf(searchValue, fromIndex) + searchValue.length));
};
var after = function after(searchValue, fromIndex) {
return (this.substring(this.indexOf(searchValue, fromIndex) + searchValue.length));
};
function getPairs(uri) {
return after.call(uri, "?").split("&");
}
function containsMultipart(uri) {
return (getPairs(uri).indexOf("m_mode=multipart") !== -1);
}
function getFragmentUri(uri) {
var change = {
m_mode: "fragment",
y_map_urn: null,
_sig: null
};
var pairs = getPairs(uri);
var fragmentPairs = [];
var i = null;
var length = pairs.length;
for (i = 0; i < length; i += 1) {
var singletons = pairs[i].split("=");
var name = singletons[0];
var value = singletons[1];
var changeValue = change[name];
var isExclusion = (changeValue === null);
if (!isExclusion) {
var needsChange = change.hasOwnProperty(name);
fragmentPairs.push(name + "=" + (needsChange ? encodeURIComponent(changeValue) : value));
}
}
return (beforeInclusive.call(uri, "?") + fragmentPairs.join("&"));
}
function constructMultipartResponse(request) {
var response = [];
// For each part, there is a split separator that looks like "--dali-response-split".
// It should match the regex `/^--dali-response-split(?:-[a-z0-9]+)?/gm`.
// Construct the text parts.
var blob = request.getResponseHeader("X-Maple-Embed-Blob");
var parts = blob.split(/,\s*/g);
var p = null;
var numberOfParts = parts.length;
for (p = 0; p < numberOfParts; p += 1) {
var sections = parts[p].split(/;\s*/g);
var numberOfSections = sections.length;
if (numberOfSections >= 2) {
var header = sections[0].trim();
response.push("");
response.push("--dali-response-split");
response.push("Content-Type: text/plain; charset=utf-8");
response.push("RMP-Embed-Location: " + after.call(header, "location="));
var s = null;
for (s = 1; s < numberOfSections; s += 1) {
var body = decodeURIComponent(sections[s].trim().replace(/\+/g, " "));
response.push("");
response.push(body);
}
}
}
// Construct the HTML part.
response.push("");
response.push("--dali-response-split");
response.push("Content-Type: text/html; charset=utf-8");
response.push("");
response.push(request.responseText);
// End multipart response.
response.push("--dali-response-split");
response.push("");
return response.join("\r\n");
}
function handleMultipartRequests() {
var XMLHttpRequestPrototype = XMLHttpRequest.prototype;
function logMultipartRequests() {
var realOpen = XMLHttpRequestPrototype.open;
XMLHttpRequestPrototype.open = function open(method, url, async, user, password) {
var isMultipart = containsMultipart(url);
if (isMultipart) {
if (!this.hasOwnProperty("storage")) {
Object.defineProperty(this, "storage", {value: {}});
}
var storage = this.storage;
// Add propositions.
if (!storage.hasOwnProperty("proposition")) {
storage.proposition = {};
}
storage.proposition.isMultipart = isMultipart;
// Add parameters.
if (!storage.hasOwnProperty("parameter")) {
storage.parameter = {};
}
var parameter = storage.parameter;
if (!parameter.hasOwnProperty("open")) {
parameter.open = {};
}
parameter.open.method = method;
parameter.open.url = url;
parameter.open.async = async;
parameter.open.user = user;
parameter.open.password = password;
}
return realOpen.call(this, method, url, async, user, password);
};
}
function replaceMultipartRequests() {
var realSend = XMLHttpRequestPrototype.send;
XMLHttpRequestPrototype.send = function send(data) {
var storage = this.storage;
var isMultipart = (this.hasOwnProperty("storage") && storage.proposition.isMultipart);
if (!isMultipart) {
return realSend.call(this, data);
}
var openParameter = storage.parameter.open;
var request = new XMLHttpRequest();
request.open(openParameter.method, getFragmentUri(openParameter.url), false, openParameter.user, openParameter.password);
var fragmentResult = realSend.call(request, data);
realSend.call(this, data); // Send the multipart request to trigger status and event changes.
// Construct multipart response.
var multipartResponse = constructMultipartResponse(request);
Object.defineProperties(this, {
response: {value: multipartResponse},
responseText: {value: multipartResponse}
});
return fragmentResult;
};
}
logMultipartRequests();
replaceMultipartRequests();
}
handleMultipartRequests();
}(this, this.Object, this.XMLHttpRequest));
@XP1
Copy link
Author

XP1 commented Apr 26, 2013

I posted this user JS in this thread:

can't see yahoo comments:
http://my.opera.com/community/forums/topic.dml?id=1640352

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment