{"id":13565576,"url":"https://github.com/ccnmtl/mediathread-collect","last_synced_at":"2025-04-12T04:23:15.656Z","repository":{"id":2278134,"uuid":"46142272","full_name":"ccnmtl/mediathread-collect","owner":"ccnmtl","description":"Common code for the Chrome, Safari, and Firefox extensions for Mediathread","archived":false,"fork":false,"pushed_at":"2024-04-22T10:32:47.000Z","size":728,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-04-22T11:42:12.894Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ccnmtl.png","metadata":{"files":{"readme":"README.md","changelog":"ChangeLog","contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2015-11-13T19:21:19.000Z","updated_at":"2024-04-23T11:54:29.880Z","dependencies_parsed_at":"2023-07-06T13:02:01.506Z","dependency_job_id":"20ca0102-8c46-47f4-a804-29a47632e1ff","html_url":"https://github.com/ccnmtl/mediathread-collect","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ccnmtl%2Fmediathread-collect","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ccnmtl%2Fmediathread-collect/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ccnmtl%2Fmediathread-collect/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ccnmtl%2Fmediathread-collect/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ccnmtl","download_url":"https://codeload.github.com/ccnmtl/mediathread-collect/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248514679,"owners_count":21117009,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T13:01:50.459Z","updated_at":"2025-04-12T04:23:15.633Z","avatar_url":"https://github.com/ccnmtl.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# mediathread-collect\n\n[![Actions Status](https://github.com/ccnmtl/mediathread-collect/workflows/build-and-test/badge.svg)](https://github.com/ccnmtl/mediathread-collect/actions)\n\nCommon code for the Chrome, Safari, and Firefox extensions for Mediathread.\n\nARCHITECTURE:\nEverything lives within two namespaces: window.MediathreadCollect and\nwindow.MediathreadCollectOptions.\n\nMediathreadCollectOptions is a dictionary which can (and must to work\nas a extension) be created before this file is loaded.  This\nway, if required, this file could also be used as a library.  In\nthis scenario, if a site wanted an 'AnalyzeThis' button to work\nwithout a user needing to install a extension, then this file\nwould be loaded, and the button would call into\n`MediathreadCollect.runners['jump']` (or .decorate).\n\nA typical MediathreadCollectOptions set of values would be:\n\n    {\n        'action': 'jump',\n        'host_url': 'http://mediathread.example.com/save/?',\n        'flickr_apikey': 'foobar123456789'\n    }\n\nThe 'action' mostly services the extension, but in theory, this\nseparates the initialization code along with what the\nextension's action would be -- to immediately jump into\nmediathread or to display the options list (which is more often\nthe default).\n\nBasic parts:\n`.hosthandler.*` : This dictionary is a list of all special-cased\nhosts.  When these keys match anywhere (so\nuniversity proxies will work) in\ndocument.location, then this code will be\npreferred rather than searching over the normal\nmedia types.  This should be a method of last\nresort -- supporting generic media-types is much\nbetter, but this can be especially useful when\nlooking for metadata.\n\nfind: function(callback) = this is the function, which fill find assets and\nthen run callback([array of assets -- see below for datastructure])\n-- async allows you to make ajax calls, or whatever else you need\n\n`allow_save_all` = if true, there will be an interface on the\nbottom to save all assets at once.  This is\nsomewhat experimental -- used to load a\nwhole course from VITAL into MediaThread\n\n`also_find_general` = if true, then the normal media type\nqueries will be run.  This is a good way\nto implement custom metadata searches,\nwithout rewriting support for media.\nAlso, see the youtube.com example for a\nway to call into the general media types\nto search for a particular kind of media,\nwithout duplicating code.\n\n\n.assethandler.* : This is where all the methods are that look for\nmedia or metadata on the page.  Each key:value\nis run with the extension for a chance to\nfind its kind of assets, and, if found, query\nfor more data.\n\nBesides finding media, an assethandler can also find metadata,\nand if the metadata can only be pinned to 'something on the page'\nthen you should set 'page_resource': true in the assethandler dict.\n\nEach .find method is called as\nfind.apply(assethandler,callback,{window: window,document: document})\n\nnote: use the context passed into the method\nrather than global window/document\nobjects, since the extension\nsupports deeply embedded\nframes/iframes and the context might\nbe different The .find method is\nresponsible for eventually calling\ncallback([array of assets]) with a\nblank array if none are found.\n\n\nThe asset objects passed back should have the following structure:\n\n    {html:\u003cdom object of media\u003e,\n    primary_type:\u003cstring of the sources key\n    most important for this media.  e.g. 'video' \u003e,\n    sources: {\n    title:\u003ctitle string.  if omitted, it will\n    be discerned from the primary_type's filename\u003e,\n\n    url: \u003conly use if you want to\n    override the url that is\n    displayed to the user as a\n    link to get back to the\n    archive's page for the\n    asset.  mostly this is just\n    document.location\u003e\n\n    \u003ckey:values of urls that will be\n    stored in the asset's Source\n    objects in MediaThread\u003e\n\n    \u003ckey\u003e-metadata: \u003cmetadata for the source\n    key in the form of 'w\u003cwidth\u003eh\u003cheight\u003e' \u003e\n    },\n\n    metadata: { \u003ckey, value pairs for metadata.\n    Values should always be an array of strings\u003e\n    }\n\n    }\n\n`.assethandler.objects_and_embeds.*`\nSince a large subset of assethandlers look for an\nobject or embed tag, and dancing between duplicate\nversions often appear in sites, the general code is\nhandled as a big assethandler with sub-handlers for checking object\nand embed tags.  It's important to look at examples for good\npractices on how to go through these elements.  These have two main\nfunctions:\n\n`.match(embed_or_object)` = this function should `===null` if the embed/object\ntag does not match, and can return anything else, if it does match.\n`.asset(embed_or_object,matchRv,context,index,optionalCallback)`\n`@matchRv` = whatever .match returned\n`@optionalCallback` = you can just return the `asset_object` directly\nbut if you need to do ajax, or callback-based apis to get all the\ninfo/metadata, then you can return an asset object with with a\n'wait': true key, and then call\noptionalCallback(@index, asset_object) where @index is the\nindex argument passed to .asset.\n\n\nrunners : as described above, runners are alternate 'setups' that mediathread\ncan be run in.\n'jump' generally means if one asset is found on the page jump right into\nmediathread\n'decorate' means bring up the MediathreadCollect.Interface and let the user\ntake another\naction.  This is probably the best one going forward.\n\nHELP FUNCTIONS:\nconnect: quick cross-browser event-listener\nhasClass(elem,cls),\nhasBody(doc) -- does it have a doc.body value?  `\u003cframeset\u003e` pages do NOT\nclean(str), getImageDimensions(), mergeMetadata(),\nxml2dom(str,xhr), absoluteUrl(),\nelt() for creating new html in a way that is frame/browser friendly\n\nFinder() : This object is the main thing that walks through the document's\nmedia through\nany sub-frames and merges the results into a list.\n\nInterface() : This is the object that creates and manages the extension\ninterface\n(The gray widget that appears, listing the assets, and presenting the\nanalyze buttons, etc.)\n\nThis interface calls Finder() and displays the results\n\nFOOTER:\nAt the bottom of this file is the init/bootstrap code which runs the right\npart of\nMediathreadCollect.* (generally a runner) after inspecting\nMediathreadCollectOptions\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fccnmtl%2Fmediathread-collect","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fccnmtl%2Fmediathread-collect","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fccnmtl%2Fmediathread-collect/lists"}