1
0
mirror of https://github.com/chylex/TweetDuck.git synced 2025-04-12 06:15:45 +02:00

Add more safety checks to code.js

This commit is contained in:
chylex 2018-07-05 09:05:20 +02:00
parent 41bbe7c51b
commit 20b1b3c895

View File

@ -1,4 +1,4 @@
(function($, $TD, $TDX, TD){
(function($TD, $TDX, $, TD){
//
// Variable: Current highlighted column jQuery & data objects.
//
@ -22,7 +22,7 @@
//
// Variable: DOM object containing the main app element.
//
const app = $(document.body).children(".js-app");
const app = typeof $ === "function" && $(document.body).children(".js-app");
//
// Constant: Column icon classes mapped to their titles.
@ -65,11 +65,12 @@
};
//
// Function: Returns true if an object has a specified property, otherwise returns false without throwing an error.
// Function: Returns true if an object has a specified property, otherwise returns false with a debug-only error message.
//
const ensurePropertyExists = function(obj, ...chain){
for(let index = 0; index < chain.length; index++){
if (!obj.hasOwnProperty(chain[index])){
debugger;
$TD.crashDebug("Missing property "+chain[index]+" in chain [obj]."+chain.join("."));
return false;
}
@ -80,6 +81,20 @@
return true;
};
//
// Function: Returns a jQuery object but also shows a debug-only error message if no elements are found.
//
const $$ = function(selector, context){
let result = $(selector, context);
if (!result.length){
debugger;
$TD.crashDebug("No elements were found for selector "+selector);
}
return result;
};
//
// Function: Retrieves a property of an element with a specified class.
//
@ -101,10 +116,10 @@
$(document).on("uiColumnRendered", function(e, data){
let icon = data.$column.find(".column-type-icon").first();
return if icon.length !== 1;
let name = Array.prototype.find.call(icon[0].classList, cls => cls.startsWith("icon-"));
return if !name;
data.$column.attr("data-td-icon", name);
data.column._tduck_icon = name;
});
@ -277,6 +292,11 @@
// Function: Shows tweet detail, used in notification context menu.
//
(function(){
return if !ensurePropertyExists(TD, "ui", "updates", "showDetailView");
return if !ensurePropertyExists(TD, "controller", "columnManager", "showColumn");
return if !ensurePropertyExists(TD, "controller", "columnManager", "getByApiid");
return if !ensurePropertyExists(TD, "controller", "clients", "getPreferredClient");
const showTweetDetailInternal = function(column, chirp){
TD.ui.updates.showDetailView(column, chirp, column.findChirp(chirp) || chirp);
TD.controller.columnManager.showColumn(column.model.privateState.key);
@ -393,7 +413,7 @@
// Block: Add TweetDuck buttons to the settings menu.
//
onAppReady.push(function(){
$("[data-action='settings-menu']").click(function(){
$$("[data-action='settings-menu']").click(function(){
setTimeout(function(){
let menu = $(".js-dropdown-content").children("ul").first();
return if menu.length === 0;
@ -627,6 +647,9 @@
// Block: Update highlighted column and tweet for context menu and other functionality.
//
(function(){
return if !ensurePropertyExists(TD, "controller", "columnManager", "get");
return if !ensurePropertyExists(TD, "services", "ChirpBase", "TWEET");
const updateHighlightedColumn = function(ele){
highlightedColumnEle = ele;
highlightedColumnObj = ele ? TD.controller.columnManager.get(ele.attr("data-column")) : null;
@ -877,22 +900,28 @@
//
// Block: Fix scheduled tweets not showing up sometimes.
//
$(document).on("dataTweetSent", function(e, data){
if (data.response.state && data.response.state === "scheduled"){
let column = Object.values(TD.controller.columnManager.getAll()).find(column => column.model.state.type === "scheduled");
(function(){
return if !ensurePropertyExists(TD, "controller", "columnManager", "getAll");
$(document).on("dataTweetSent", function(e, data){
if (data.response.state && data.response.state === "scheduled"){
let column = Object.values(TD.controller.columnManager.getAll()).find(column => column.model.state.type === "scheduled");
if (column){
setTimeout(function(){
column.reloadTweets();
}, 1000);
if (column){
setTimeout(function(){
column.reloadTweets();
}, 1000);
}
}
}
});
});
})();
//
// Block: Hold Shift to restore cleared column.
//
(function(){
return if !ensurePropertyExists(TD, "vo", "Column", "prototype", "clear");
var holdingShift = false;
const updateShiftState = (pressed) => {
@ -916,8 +945,6 @@
}
});
return if !ensurePropertyExists(TD, "vo", "Column", "prototype", "clear");
TD.vo.Column.prototype.clear = prependToFunction(TD.vo.Column.prototype.clear, function(){
window.setTimeout(resetActiveFocus, 0); // unfocuses the Clear button, otherwise it steals keyboard input
@ -933,11 +960,13 @@
// Block: Refocus the textbox after switching accounts.
//
onAppReady.push(function(){
const composeInput = $$(".js-compose-text", ".js-docked-compose");
const refocusInput = function(){
$(".js-compose-text", ".js-docked-compose").focus();
composeInput.focus();
};
$(".js-account-list", ".js-docked-compose").delegate(".js-account-item", "click", function(e){
$$(".js-account-list", ".js-docked-compose").delegate(".js-account-item", "click", function(e){
setTimeout(refocusInput, 0);
});
});
@ -1048,7 +1077,7 @@
default: throw "Invalid mustache injection operation. Only 'replace', 'append', 'prepend' are supported.";
}
let prev = TD.mustaches[name];
let prev = TD.mustaches && TD.mustaches[name];
if (!prev){
$TD.crashDebug("Mustache injection is referencing an invalid mustache: "+name);
@ -1141,9 +1170,9 @@
TD.mustaches["media/native_video.mustache"] = '<div class="js-media-gif-container media-item nbfc is-video" style="background-image:url({{imageSrc}})"><video class="js-media-gif media-item-gif full-width block {{#isPossiblySensitive}}is-invisible{{/isPossiblySensitive}}" loop src="{{videoUrl}}"></video><a class="js-gif-play pin-all is-actionable">{{> media/video_overlay}}</a></div>';
if (!ensurePropertyExists(TD, "components", "MediaGallery", "prototype", "_loadTweet") ||
!ensurePropertyExists(TD, "components", "BaseModal", "prototype", "setAndShowContainer") ||
!ensurePropertyExists(TD, "ui", "Column", "prototype", "playGifIfNotManuallyPaused"))return;
return if !ensurePropertyExists(TD, "components", "MediaGallery", "prototype", "_loadTweet");
return if !ensurePropertyExists(TD, "components", "BaseModal", "prototype", "setAndShowContainer");
return if !ensurePropertyExists(TD, "ui", "Column", "prototype", "playGifIfNotManuallyPaused");
var cancelModal = false;
@ -1172,10 +1201,10 @@
if (ensurePropertyExists(TD, "services", "TwitterMedia")){
let media = TD.services.TwitterMedia;
if (!ensurePropertyExists(media, "YOUTUBE_TINY_RE") ||
!ensurePropertyExists(media, "YOUTUBE_LONG_RE") ||
!ensurePropertyExists(media, "YOUTUBE_RE") ||
!ensurePropertyExists(media, "SERVICES", "youtube"))return;
return if !ensurePropertyExists(media, "YOUTUBE_TINY_RE");
return if !ensurePropertyExists(media, "YOUTUBE_LONG_RE");
return if !ensurePropertyExists(media, "YOUTUBE_RE");
return if !ensurePropertyExists(media, "SERVICES", "youtube");
media.YOUTUBE_TINY_RE = new RegExp(media.YOUTUBE_TINY_RE.source.replace("http:", "https?:"));
media.YOUTUBE_RE = new RegExp(media.YOUTUBE_LONG_RE.source+"|"+media.YOUTUBE_TINY_RE.source);
@ -1187,12 +1216,11 @@
//
onAppReady.push(function(){
let ele = $(`<svg id="td-compose-drawer-pin" viewBox="0 0 24 24" class="icon js-show-tip" data-original-title="Stay open" data-tooltip-position="left">
<path d="M9.884,16.959l3.272,0.001l-0.82,4.568l-1.635,0l-0.817,-4.569Z"/>
<rect x="8.694" y="7.208" width="5.652" height="7.445"/>
<path d="M16.877,17.448c0,-1.908 -1.549,-3.456 -3.456,-3.456l-3.802,0c-1.907,0 -3.456,1.548 -3.456,3.456l10.714,0Z"/>
<path d="M6.572,5.676l2.182,2.183l5.532,0l2.182,-2.183l0,-1.455l-9.896,0l0,1.455Z"/>
</svg>`
).appendTo(".js-docked-compose .js-compose-header");
<path d="M9.884,16.959l3.272,0.001l-0.82,4.568l-1.635,0l-0.817,-4.569Z"/>
<rect x="8.694" y="7.208" width="5.652" height="7.445"/>
<path d="M16.877,17.448c0,-1.908 -1.549,-3.456 -3.456,-3.456l-3.802,0c-1.907,0 -3.456,1.548 -3.456,3.456l10.714,0Z"/>
<path d="M6.572,5.676l2.182,2.183l5.532,0l2.182,-2.183l0,-1.455l-9.896,0l0,1.455Z"/>
</svg>`).appendTo(".js-docked-compose .js-compose-header");
ele.click(function(){
if (TD.settings.getComposeStayOpen()){
@ -1213,26 +1241,31 @@
//
// Block: Make temporary search column appear as the first one and clear the input box.
//
$(document).on("uiSearchNoTemporaryColumn", function(e, data){
if (data.query && data.searchScope !== "users" && !data.columnKey){
if ($TDX.openSearchInFirstColumn){
let order = TD.controller.columnManager._columnOrder;
if (order.length > 1){
let columnKey = order[order.length-1];
order.splice(order.length-1, 1);
order.splice(1, 0, columnKey);
TD.controller.columnManager.move(columnKey, "left");
(function(){
return if !ensurePropertyExists(TD, "controller", "columnManager", "_columnOrder");
return if !ensurePropertyExists(TD, "controller", "columnManager", "move");
$(document).on("uiSearchNoTemporaryColumn", function(e, data){
if (data.query && data.searchScope !== "users" && !data.columnKey){
if ($TDX.openSearchInFirstColumn){
let order = TD.controller.columnManager._columnOrder;
if (order.length > 1){
let columnKey = order[order.length-1];
order.splice(order.length-1, 1);
order.splice(1, 0, columnKey);
TD.controller.columnManager.move(columnKey, "left");
}
}
if (!("tweetduck" in data)){
$(".js-app-search-input").val("");
$(".js-perform-search").blur();
}
}
if (!("tweetduck" in data)){
$(".js-app-search-input").val("");
$(".js-perform-search").blur();
}
}
});
});
})();
//
// Block: Setup global function to add a search column with the specified query.
@ -1250,9 +1283,9 @@
//
onAppReady.push(function(){
let container = $(".js-search-in-popover");
let hashtags = $(".js-typeahead-topic-list", container);
let hashtags = $$(".js-typeahead-topic-list", container);
$(".js-typeahead-user-list", container).insertBefore(hashtags);
$$(".js-typeahead-user-list", container).insertBefore(hashtags);
hashtags.addClass("list-divider");
});
@ -1269,17 +1302,17 @@
app.click(); // unfocus everything
};
$(".js-app-search-input").keydown(function(e){
$$(".js-app-search-input").keydown(function(e){
(e.ctrlKey && e.keyCode === 13) && openSearchExternally(e, $(this)); // enter
});
$(".js-perform-search").on("click auxclick", function(e){
$$(".js-perform-search").on("click auxclick", function(e){
(e.ctrlKey || e.button === 1) && openSearchExternally(e, $(".js-app-search-input:visible"));
}).each(function(){
window.TDGF_prioritizeNewestEvent($(this)[0], "click");
});
$("[data-action='show-search']").on("click auxclick", function(e){
$$("[data-action='show-search']").on("click auxclick", function(e){
(e.ctrlKey || e.button === 1) && openSearchExternally(e, $());
});
});
@ -1460,14 +1493,19 @@
// Block: Custom reload function with memory cleanup.
//
window.TDGF_reload = function(){
let session = TD.storage.feedController.getAll()
.filter(feed => !!feed.getTopSortIndex())
.reduce((obj, feed) => (obj[feed.privateState.key] = feed.getTopSortIndex(), obj), {});
$TD.setSessionData("gc", JSON.stringify(session)).then(() => {
window.gc && window.gc();
try{
let session = TD.storage.feedController.getAll()
.filter(feed => !!feed.getTopSortIndex())
.reduce((obj, feed) => (obj[feed.privateState.key] = feed.getTopSortIndex(), obj), {});
$TD.setSessionData("gc", JSON.stringify(session)).then(() => {
window.gc && window.gc();
window.location.reload();
});
}catch(err){
$TD.crashDebug("Error saving session during a reload");
window.location.reload();
});
}
window.TDGF_reload = function(){}; // redefine to prevent reloading multiple times
};
@ -1482,7 +1520,7 @@
state = {};
}
var showMissedNotifications = function(){
const showMissedNotifications = function(){
let tweets = [];
let columns = {};
@ -1510,18 +1548,20 @@
}
};
$(document).one("dataColumnsLoaded", function(){
let columns = Object.values(TD.controller.columnManager.getAll());
let remaining = columns.length;
if (ensurePropertyExists(TD, "controller", "columnManager", "getAll")){
$(document).one("dataColumnsLoaded", function(){
let columns = Object.values(TD.controller.columnManager.getAll());
let remaining = columns.length;
for(let column of columns){
column.ui.getChirpContainer().one("dataColumnFeedUpdated", () => {
if (--remaining === 0){
setTimeout(showMissedNotifications, 1);
}
});
}
});
for(let column of columns){
column.ui.getChirpContainer().one("dataColumnFeedUpdated", () => {
if (--remaining === 0){
setTimeout(showMissedNotifications, 1);
}
});
}
});
}
}
//
@ -1571,4 +1611,4 @@
location.href = "https://twitter.com/login?hide_message=true&redirect_after_login=https%3A%2F%2Ftweetdeck.twitter.com%2F%3Fvia_twitter_login%3Dtrue";
};
}
})($, $TD, $TDX, TD);
})($TD, $TDX, window.$, window.TD || {});