mirror of
https://github.com/chylex/TweetDuck.git
synced 2025-05-05 02:34:07 +02:00
Add more safety checks to code.js
This commit is contained in:
parent
41bbe7c51b
commit
20b1b3c895
@ -1,4 +1,4 @@
|
|||||||
(function($, $TD, $TDX, TD){
|
(function($TD, $TDX, $, TD){
|
||||||
//
|
//
|
||||||
// Variable: Current highlighted column jQuery & data objects.
|
// Variable: Current highlighted column jQuery & data objects.
|
||||||
//
|
//
|
||||||
@ -22,7 +22,7 @@
|
|||||||
//
|
//
|
||||||
// Variable: DOM object containing the main app element.
|
// 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.
|
// 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){
|
const ensurePropertyExists = function(obj, ...chain){
|
||||||
for(let index = 0; index < chain.length; index++){
|
for(let index = 0; index < chain.length; index++){
|
||||||
if (!obj.hasOwnProperty(chain[index])){
|
if (!obj.hasOwnProperty(chain[index])){
|
||||||
|
debugger;
|
||||||
$TD.crashDebug("Missing property "+chain[index]+" in chain [obj]."+chain.join("."));
|
$TD.crashDebug("Missing property "+chain[index]+" in chain [obj]."+chain.join("."));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -80,6 +81,20 @@
|
|||||||
return true;
|
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.
|
// Function: Retrieves a property of an element with a specified class.
|
||||||
//
|
//
|
||||||
@ -101,10 +116,10 @@
|
|||||||
$(document).on("uiColumnRendered", function(e, data){
|
$(document).on("uiColumnRendered", function(e, data){
|
||||||
let icon = data.$column.find(".column-type-icon").first();
|
let icon = data.$column.find(".column-type-icon").first();
|
||||||
return if icon.length !== 1;
|
return if icon.length !== 1;
|
||||||
|
|
||||||
let name = Array.prototype.find.call(icon[0].classList, cls => cls.startsWith("icon-"));
|
let name = Array.prototype.find.call(icon[0].classList, cls => cls.startsWith("icon-"));
|
||||||
return if !name;
|
return if !name;
|
||||||
|
|
||||||
data.$column.attr("data-td-icon", name);
|
data.$column.attr("data-td-icon", name);
|
||||||
data.column._tduck_icon = name;
|
data.column._tduck_icon = name;
|
||||||
});
|
});
|
||||||
@ -277,6 +292,11 @@
|
|||||||
// Function: Shows tweet detail, used in notification context menu.
|
// Function: Shows tweet detail, used in notification context menu.
|
||||||
//
|
//
|
||||||
(function(){
|
(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){
|
const showTweetDetailInternal = function(column, chirp){
|
||||||
TD.ui.updates.showDetailView(column, chirp, column.findChirp(chirp) || chirp);
|
TD.ui.updates.showDetailView(column, chirp, column.findChirp(chirp) || chirp);
|
||||||
TD.controller.columnManager.showColumn(column.model.privateState.key);
|
TD.controller.columnManager.showColumn(column.model.privateState.key);
|
||||||
@ -393,7 +413,7 @@
|
|||||||
// Block: Add TweetDuck buttons to the settings menu.
|
// Block: Add TweetDuck buttons to the settings menu.
|
||||||
//
|
//
|
||||||
onAppReady.push(function(){
|
onAppReady.push(function(){
|
||||||
$("[data-action='settings-menu']").click(function(){
|
$$("[data-action='settings-menu']").click(function(){
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
let menu = $(".js-dropdown-content").children("ul").first();
|
let menu = $(".js-dropdown-content").children("ul").first();
|
||||||
return if menu.length === 0;
|
return if menu.length === 0;
|
||||||
@ -627,6 +647,9 @@
|
|||||||
// Block: Update highlighted column and tweet for context menu and other functionality.
|
// Block: Update highlighted column and tweet for context menu and other functionality.
|
||||||
//
|
//
|
||||||
(function(){
|
(function(){
|
||||||
|
return if !ensurePropertyExists(TD, "controller", "columnManager", "get");
|
||||||
|
return if !ensurePropertyExists(TD, "services", "ChirpBase", "TWEET");
|
||||||
|
|
||||||
const updateHighlightedColumn = function(ele){
|
const updateHighlightedColumn = function(ele){
|
||||||
highlightedColumnEle = ele;
|
highlightedColumnEle = ele;
|
||||||
highlightedColumnObj = ele ? TD.controller.columnManager.get(ele.attr("data-column")) : null;
|
highlightedColumnObj = ele ? TD.controller.columnManager.get(ele.attr("data-column")) : null;
|
||||||
@ -877,22 +900,28 @@
|
|||||||
//
|
//
|
||||||
// Block: Fix scheduled tweets not showing up sometimes.
|
// Block: Fix scheduled tweets not showing up sometimes.
|
||||||
//
|
//
|
||||||
$(document).on("dataTweetSent", function(e, data){
|
(function(){
|
||||||
if (data.response.state && data.response.state === "scheduled"){
|
return if !ensurePropertyExists(TD, "controller", "columnManager", "getAll");
|
||||||
let column = Object.values(TD.controller.columnManager.getAll()).find(column => column.model.state.type === "scheduled");
|
|
||||||
|
$(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){
|
if (column){
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
column.reloadTweets();
|
column.reloadTweets();
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
})();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Block: Hold Shift to restore cleared column.
|
// Block: Hold Shift to restore cleared column.
|
||||||
//
|
//
|
||||||
(function(){
|
(function(){
|
||||||
|
return if !ensurePropertyExists(TD, "vo", "Column", "prototype", "clear");
|
||||||
|
|
||||||
var holdingShift = false;
|
var holdingShift = false;
|
||||||
|
|
||||||
const updateShiftState = (pressed) => {
|
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(){
|
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
|
window.setTimeout(resetActiveFocus, 0); // unfocuses the Clear button, otherwise it steals keyboard input
|
||||||
|
|
||||||
@ -933,11 +960,13 @@
|
|||||||
// Block: Refocus the textbox after switching accounts.
|
// Block: Refocus the textbox after switching accounts.
|
||||||
//
|
//
|
||||||
onAppReady.push(function(){
|
onAppReady.push(function(){
|
||||||
|
const composeInput = $$(".js-compose-text", ".js-docked-compose");
|
||||||
|
|
||||||
const refocusInput = function(){
|
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);
|
setTimeout(refocusInput, 0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -1048,7 +1077,7 @@
|
|||||||
default: throw "Invalid mustache injection operation. Only 'replace', 'append', 'prepend' are supported.";
|
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){
|
if (!prev){
|
||||||
$TD.crashDebug("Mustache injection is referencing an invalid mustache: "+name);
|
$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>';
|
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") ||
|
return if !ensurePropertyExists(TD, "components", "MediaGallery", "prototype", "_loadTweet");
|
||||||
!ensurePropertyExists(TD, "components", "BaseModal", "prototype", "setAndShowContainer") ||
|
return if !ensurePropertyExists(TD, "components", "BaseModal", "prototype", "setAndShowContainer");
|
||||||
!ensurePropertyExists(TD, "ui", "Column", "prototype", "playGifIfNotManuallyPaused"))return;
|
return if !ensurePropertyExists(TD, "ui", "Column", "prototype", "playGifIfNotManuallyPaused");
|
||||||
|
|
||||||
var cancelModal = false;
|
var cancelModal = false;
|
||||||
|
|
||||||
@ -1172,10 +1201,10 @@
|
|||||||
if (ensurePropertyExists(TD, "services", "TwitterMedia")){
|
if (ensurePropertyExists(TD, "services", "TwitterMedia")){
|
||||||
let media = TD.services.TwitterMedia;
|
let media = TD.services.TwitterMedia;
|
||||||
|
|
||||||
if (!ensurePropertyExists(media, "YOUTUBE_TINY_RE") ||
|
return if !ensurePropertyExists(media, "YOUTUBE_TINY_RE");
|
||||||
!ensurePropertyExists(media, "YOUTUBE_LONG_RE") ||
|
return if !ensurePropertyExists(media, "YOUTUBE_LONG_RE");
|
||||||
!ensurePropertyExists(media, "YOUTUBE_RE") ||
|
return if !ensurePropertyExists(media, "YOUTUBE_RE");
|
||||||
!ensurePropertyExists(media, "SERVICES", "youtube"))return;
|
return if !ensurePropertyExists(media, "SERVICES", "youtube");
|
||||||
|
|
||||||
media.YOUTUBE_TINY_RE = new RegExp(media.YOUTUBE_TINY_RE.source.replace("http:", "https?:"));
|
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);
|
media.YOUTUBE_RE = new RegExp(media.YOUTUBE_LONG_RE.source+"|"+media.YOUTUBE_TINY_RE.source);
|
||||||
@ -1187,12 +1216,11 @@
|
|||||||
//
|
//
|
||||||
onAppReady.push(function(){
|
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">
|
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"/>
|
<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"/>
|
<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="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"/>
|
<path d="M6.572,5.676l2.182,2.183l5.532,0l2.182,-2.183l0,-1.455l-9.896,0l0,1.455Z"/>
|
||||||
</svg>`
|
</svg>`).appendTo(".js-docked-compose .js-compose-header");
|
||||||
).appendTo(".js-docked-compose .js-compose-header");
|
|
||||||
|
|
||||||
ele.click(function(){
|
ele.click(function(){
|
||||||
if (TD.settings.getComposeStayOpen()){
|
if (TD.settings.getComposeStayOpen()){
|
||||||
@ -1213,26 +1241,31 @@
|
|||||||
//
|
//
|
||||||
// Block: Make temporary search column appear as the first one and clear the input box.
|
// Block: Make temporary search column appear as the first one and clear the input box.
|
||||||
//
|
//
|
||||||
$(document).on("uiSearchNoTemporaryColumn", function(e, data){
|
(function(){
|
||||||
if (data.query && data.searchScope !== "users" && !data.columnKey){
|
return if !ensurePropertyExists(TD, "controller", "columnManager", "_columnOrder");
|
||||||
if ($TDX.openSearchInFirstColumn){
|
return if !ensurePropertyExists(TD, "controller", "columnManager", "move");
|
||||||
let order = TD.controller.columnManager._columnOrder;
|
|
||||||
|
$(document).on("uiSearchNoTemporaryColumn", function(e, data){
|
||||||
if (order.length > 1){
|
if (data.query && data.searchScope !== "users" && !data.columnKey){
|
||||||
let columnKey = order[order.length-1];
|
if ($TDX.openSearchInFirstColumn){
|
||||||
|
let order = TD.controller.columnManager._columnOrder;
|
||||||
order.splice(order.length-1, 1);
|
|
||||||
order.splice(1, 0, columnKey);
|
if (order.length > 1){
|
||||||
TD.controller.columnManager.move(columnKey, "left");
|
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.
|
// Block: Setup global function to add a search column with the specified query.
|
||||||
@ -1250,9 +1283,9 @@
|
|||||||
//
|
//
|
||||||
onAppReady.push(function(){
|
onAppReady.push(function(){
|
||||||
let container = $(".js-search-in-popover");
|
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");
|
hashtags.addClass("list-divider");
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1269,17 +1302,17 @@
|
|||||||
app.click(); // unfocus everything
|
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
|
(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"));
|
(e.ctrlKey || e.button === 1) && openSearchExternally(e, $(".js-app-search-input:visible"));
|
||||||
}).each(function(){
|
}).each(function(){
|
||||||
window.TDGF_prioritizeNewestEvent($(this)[0], "click");
|
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, $());
|
(e.ctrlKey || e.button === 1) && openSearchExternally(e, $());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -1460,14 +1493,19 @@
|
|||||||
// Block: Custom reload function with memory cleanup.
|
// Block: Custom reload function with memory cleanup.
|
||||||
//
|
//
|
||||||
window.TDGF_reload = function(){
|
window.TDGF_reload = function(){
|
||||||
let session = TD.storage.feedController.getAll()
|
try{
|
||||||
.filter(feed => !!feed.getTopSortIndex())
|
let session = TD.storage.feedController.getAll()
|
||||||
.reduce((obj, feed) => (obj[feed.privateState.key] = feed.getTopSortIndex(), obj), {});
|
.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();
|
$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.location.reload();
|
||||||
});
|
}
|
||||||
|
|
||||||
window.TDGF_reload = function(){}; // redefine to prevent reloading multiple times
|
window.TDGF_reload = function(){}; // redefine to prevent reloading multiple times
|
||||||
};
|
};
|
||||||
@ -1482,7 +1520,7 @@
|
|||||||
state = {};
|
state = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
var showMissedNotifications = function(){
|
const showMissedNotifications = function(){
|
||||||
let tweets = [];
|
let tweets = [];
|
||||||
let columns = {};
|
let columns = {};
|
||||||
|
|
||||||
@ -1510,18 +1548,20 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$(document).one("dataColumnsLoaded", function(){
|
if (ensurePropertyExists(TD, "controller", "columnManager", "getAll")){
|
||||||
let columns = Object.values(TD.controller.columnManager.getAll());
|
$(document).one("dataColumnsLoaded", function(){
|
||||||
let remaining = columns.length;
|
let columns = Object.values(TD.controller.columnManager.getAll());
|
||||||
|
let remaining = columns.length;
|
||||||
|
|
||||||
for(let column of columns){
|
for(let column of columns){
|
||||||
column.ui.getChirpContainer().one("dataColumnFeedUpdated", () => {
|
column.ui.getChirpContainer().one("dataColumnFeedUpdated", () => {
|
||||||
if (--remaining === 0){
|
if (--remaining === 0){
|
||||||
setTimeout(showMissedNotifications, 1);
|
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";
|
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 || {});
|
||||||
|
Loading…
Reference in New Issue
Block a user