在样式中,CodeProject读取器 Chrome 扩展读取CodeProject文章

分享于 

17分钟阅读

Web开发

  繁體
对于最新版本的代码,请在中检查项目。

介绍

如果你是将花时间自定义IDE样式的人类型,那么你可以能需要阅读 codeproject.com,的文章。

安装

你可以从 Chrome 网上商店中安装代码项目文章读者扩展。

使用扩展名

安装完成后,你将看到扩展的icon 在地址栏的右侧显示。 由于这里扩展仅适用于 codeproject.com 项目,因此通常会禁用该扩展。 当你访问codeproject文章/提示页面时,它将变为启用。

在任何codeproject文章/提示页面上,单击扩展名的icon。 将显示以下弹出式菜单。

你可以选择 16阅读主题 drop 主题主题you你可以从 customize customize来定制整个文章样式。 基于主题的编码主题下拉 has 8 prism 主题,你可以选择从本文中自定义源代码的语法突出显示 syntax。 布局下拉菜单允许你从 3不同的固定宽度布局或者流体布局中进行选择。 在阅读器阅读文章阅读文章会打开一个新标签,其中的文章将在选定主题中呈现。 主题选择也保存到本地存储中,以便保持优先级。

我个人喜欢的是与Okaidia棱镜主题一起使用的Readable的bootswatch主题。 这就是本文中的内容。

使用代码

这里有一些文章codeproject在codeproject上已经覆盖了创建一个 Chrome 扩展的基础,所以我不打算在这里重复。 相反,我将着重解释特定于这里扩展的区域。

启用扩展操作 icon的页面条件

这里扩展仅适用于codeproject和提示页面的文章。 我们希望使用扩展操作 icon的页面,通过使它仅在of和of文章上启用。 为此,我使用了声明性内容 API。 它允许你显示扩展操作页面,根据web页面的URL,而CSS选择器不需要主机权限或者注入内容脚本。

在安装或者升级扩展时,将执行以下代码。 使用声明性内容 API,它声明了页面操作 icon,当当前url与a 文章/提示页匹配时。

// When the extension is installed or upgraded.. .chrome.runtime.onInstalled.addListener(function () {
 // Replace all rules.. . chrome.declarativeContent.onPageChanged.removeRules(undefined, function () {
 // With a new rule.. . chrome.declarativeContent.onPageChanged.addRules([
 {
 // That fires when a page's URL matches a codeproject article or tips url conditions: [
 new chrome.declarativeContent.PageStateMatcher({
 pageUrl: { urlMatches: 'codeproject.com/(Articles|Tips)' },
 })
 ],
 // And shows the extension's page action. actions: [new chrome.declarativeContent.ShowPageAction()]
 }
 ]);
 });
});

我们还必须在 manifest.json 中指定 declarativeContent 许可,以便使用它。

"permissions" : [
 "declarativeContent",

注意,Chrome 扩展api文档提到了显示和隐藏页面 icon 操作。 根据我的经验,icon 仅启用或者禁用。

使用Bootswatch主题

阅读主题是来自 bootswatch的主题。 相反,我们将为每个可以用主题定义 cssCdn,并在渲染时使用ado的css来定义所有的css文件。

/**
 * define available bootswatch themes.
 */var bootswatchThemes =
{
 "version": "3.3.6",
 "themes": [
 {
 "name": "Cerulean",
 "description": "A calm blue sky",
 "cssCdn": "https://maxcdn.bootstrapcdn.com/bootswatch/latest/cerulean/bootstrap.min.css" },
 {
 "name": "Cosmo",
 "description": "An ode to Metro",
 "cssCdn": "https://maxcdn.bootstrapcdn.com/bootswatch/latest/cosmo/bootstrap.min.css" },
 {
 "name": "Cyborg",
 "description": "Jet black and electric blue",
 "cssCdn": "https://maxcdn.bootstrapcdn.com/bootswatch/latest/cyborg/bootstrap.min.css" },
 {
 "name": "Darkly",
 "description": "Flatly in night mode",
 "cssCdn": "https://maxcdn.bootstrapcdn.com/bootswatch/latest/darkly/bootstrap.min.css" },
 {
 "name": "Flatly",
 "description": "Flat and modern",
 "cssCdn": "https://maxcdn.bootstrapcdn.com/bootswatch/latest/flatly/bootstrap.min.css" },
 {
 "name": "Journal",
 "description": "Crisp like a new sheet of paper",
 "cssCdn": "https://maxcdn.bootstrapcdn.com/bootswatch/latest/journal/bootstrap.min.css" },
 {
 "name": "Lumen",
 "description": "Light and shadow",
 "cssCdn": "https://maxcdn.bootstrapcdn.com/bootswatch/latest/lumen/bootstrap.min.css" },
 {
 "name": "Paper",
 "description": "Material is the metaphor",
 "cssCdn": "https://maxcdn.bootstrapcdn.com/bootswatch/latest/paper/bootstrap.min.css" },
 {
 "name": "Readable",
 "description": "Optimized for legibility",
 "cssCdn": "https://maxcdn.bootstrapcdn.com/bootswatch/latest/readable/bootstrap.min.css" },
 {
 "name": "Sandstone",
 "description": "A touch of warmth",
 "cssCdn": "https://maxcdn.bootstrapcdn.com/bootswatch/latest/sandstone/bootstrap.min.css" },
 {
 "name": "Simplex",
 "description": "Mini and minimalist",
 "cssCdn": "https://maxcdn.bootstrapcdn.com/bootswatch/latest/simplex/bootstrap.min.css" },
 {
 "name": "Slate",
 "description": "Shades of gunmetal gray",
 "cssCdn": "https://maxcdn.bootstrapcdn.com/bootswatch/latest/slate/bootstrap.min.css" },
 {
 "name": "Spacelab",
 "description": "Silvery and sleek",
 "cssCdn": "https://maxcdn.bootstrapcdn.com/bootswatch/latest/spacelab/bootstrap.min.css" },
 {
 "name": "Superhero",
 "description": "The brave and the blue",
 "cssCdn": "https://maxcdn.bootstrapcdn.com/bootswatch/latest/superhero/bootstrap.min.css" },
 {
 "name": "United",
 "description": "Ubuntu orange and unique font",
 "cssCdn": "https://maxcdn.bootstrapcdn.com/bootswatch/latest/united/bootstrap.min.css" },
 {
 "name": "Yeti",
 "description": "A friendly foundation",
 "cssCdn": "https://maxcdn.bootstrapcdn.com/bootswatch/latest/yeti/bootstrap.min.css" }
 ]
}

在呈现文章时,我们将插入一个带有cssCdn路径的样式表链接元素来应用主题。 就像这个:

function applyBootstrapTheme() {
 var source = chrome.extension.getBackgroundPage().getUserBootswatchTheme().cssCdn;
 $('head').append('<link href="' + source + '" rel="stylesheet" type="text/css"/>');
}

使用 Prism

编码主题来自 Prism。 Prism是一个轻量级的。可以扩展的语法高亮显示。 它有一些很棒的主题。 bootswatch主题相比,包括扩展的所有css文件,我们将为每个可以用主题定义 cssCdn。

/**
 * define available prism themes
 */var prismThemes = 
{
 "themes" : [
 {
 "name" : "Default",
 "cssCdn" : "https://cdnjs.cloudflare.com/ajax/libs/prism/1.4.1/themes/prism.min.css" },
 {
 "name" : "Coy",
 "cssCdn" : "https://cdnjs.cloudflare.com/ajax/libs/prism/1.4.1/themes/prism-coy.min.css" },
 {
 "name" : "Dark",
 "cssCdn" : "https://cdnjs.cloudflare.com/ajax/libs/prism/1.4.1/themes/prism-dark.min.css" },
 { 
 "name" : "Funky",
 "cssCdn" : "https://cdnjs.cloudflare.com/ajax/libs/prism/1.4.1/themes/prism-funky.min.css" },
 { 
 "name" : "Okaidia",
 "cssCdn" : "https://cdnjs.cloudflare.com/ajax/libs/prism/1.4.1/themes/prism-okaidia.min.css" },
 { 
 "name" : "Solarizedlight",
 "cssCdn" : "https://cdnjs.cloudflare.com/ajax/libs/prism/1.4.1/themes/prism-solarizedlight.min.css" },
 { 
 "name" : "Tomorrow",
 "cssCdn" : "https://cdnjs.cloudflare.com/ajax/libs/prism/1.4.1/themes/prism-tomorrow.min.css" },
 { 
 "name" : "Twilight",
 "cssCdn" : "https://cdnjs.cloudflare.com/ajax/libs/prism/1.4.1/themes/prism-twilight.min.css" } 
 ]
};

我们呈现一篇文章,我们将在cssCdn路径中插入一个样式表链接元素。 就像这个:

function applyPrismjsTheme() {
 var source = chrome.extension.getBackgroundPage().getUserPrismTheme().cssCdn; 
 $('head').append('<link href="' + source + '" rel="stylesheet" type="text/css"/>'); 
}

我们还需要调用prism方法的highlightAll() 来应用语法高亮。

Prism.highlightAll();

在CodeProject和Prism之间映射语言名称

语法荧光笔需要了解语言才能正确执行突出显示。 当你在codeproject文章中插入代码 block 时,你可以选择about种不同的语言。 在Prism里有成百上千种不同的语言。 名称同样的语言在CodeProject和Prism之间也是不同的。 例如CodeProject使用"cs",而Prism使用"csharp"。 为了处理这种差异,我们将使用下面的代码来映射语言名称。
/**
 * Define a map that maps 
 * the languages supported in codeproject http://www.codeproject.com/info/Submit.aspx
 * to 
 * the languages supported in prismjs http://prismjs.com/#languages-list 
 */var languages = {
 "asm" : "clike",
 "aspnet" : "aspnet",
 "bat" : "bash",
 "cs" : "csharp",
 "c++" : "cpp",
 "css" : "css",
 "dolphi" : "clike",
 "F#" : "fsharp",
 "html" : "markup",
 "java" : "java",
 "jscript" : "javascript",
 "mc++" : "cpp",
 "midl" : "clike",
 "msil" : "clike",
 "php" : "php",
 "sql" : "sql",
 "vbnet" : "basic",
 "vb.net" : "basic",
 "vbscript" : "basic",
 "xml" : "markup",
};/**
 * Given the language name used in codeproject, find the language name used in prismjs
*/function getPrismLanguageName(name) {
 if (languages[name]!= undefined) {
 return languages[name];
 }
 // use clike as the default languagereturn"clike";
}

捕获和渲染CodeProject文章

用户单击读者按钮中的读者文章时,我们将使用所选主题在新标签中呈现用户的文章查看。 涉及多个步骤。

首先,我们使用 chrome.tabs.query api获取标签的当前 url。 url始终是codeproject文章/提示页的url。 由于本文前面提到的,我们使用声明性内容 API,仅在codeproject文章/提示url上启用页面操作( icon )。 以下代码获取选项卡的当前url并将它的保存到脚本变量的background articleUrl

chrome.tabs.query({'active': true, 'lastFocusedWindow': true}, function (tabs) {
 chrome.extension.getBackgroundPage().articleUrl = tabs[0].url;
});

此时,我们还将保存用户选择的主题,这样用户的偏好就会被记住。 下面的代码获取所选主题名并调用 saveUserThemes 方法将它们保存到 localStorage

var bootswatchSelectList = document.getElementById("bootswatch-theme-select");var bootswatchThemeName = bootswatchSelectList.options[bootswatchSelectList.selectedIndex].value;var prismSelectList = document.getElementById("prism-theme-select");var prismThemeName = prismSelectList.options[prismSelectList.selectedIndex].value;
chrome.extension.getBackgroundPage().saveUserThemes(
 bootswatchThemeName, prismThemeName
)
/**
 * save user's preferred themes to local storage.
 */function saveUserThemes(bootswatchThemeName, prismThemeName) {
 localStorage["UserBootstrapThemeName"] = bootswatchThemeName;
 localStorage["UserPrismThemeName"] = prismThemeName; 
}

现在我们有了文章url和主题,我们将使用 chrome.tabs.create api来显示文章呈现的render.html 页面。

// show the article page in a new tabchrome.tabs.create({ url: "render.html" });

Render.html 针对文章的不同元素拥有不同的占位符。

<divclass="container"id="article-container"style="display:none;"><divclass="jumbotron"><divclass="container"><h2><spanid="article-title">CodeProject Reader Chrome Extension</span><small></small></h2><pclass="lead"<spanid="article-summary"></span></p><divclass="lead small"> By <spanid="article-author"></span><b>&nbsp;&middot;&nbsp;</b> 
 <spanid="article-date">date</span><b>&nbsp;&middot;&nbsp;</b> 
 <spanid="article-rating"></span> (<spanid="article-count"></span> votes)
 </div></div></div><divid="article-body"></div></div><!-- article-container -->

Render.html 将加载 render.js 脚本。 脚本将首先使用jQuery加载方法将文章url的内容下载到一个隐藏的div中。 然后解析文章的各个元素并将它的插入到 render.html 占位符中。

 $( "#articledata" ).load( articleUrl + " div.article", function() { 
 // prepend http://www.codeproject.com to any img tags that uses relative paths (src attribute starts with slash/).  $('img[src^="/"]').each(function(index, element) {
 var newSrc = "http://www.codeproject.com" + $(this).attr("src");
 $(this).attr("src", newSrc);
 });
 // prepend http://www.codeproject.com to any a tags that uses relative paths (href attribute starts with slash/).  $('a[href^="/"]').each(function(index, element) {
 var newHref = "http://www.codeproject.com" + $(this).attr("href");
 $(this).attr("href", newHref);
 }); 
 $("#article-title").html($("div.title").first().text());
 $("#article-summary").html($("div.summary").first().text());
 $("#article-author").html($("span.author").first().text());
 $("#article-date").html($("span.date").first().text());
 $("#article-rating").html($("span.rating").first().text() == ""? "0.00" : $("span.rating").first().text());
 $("#article-count").html($("span.count").first().text() == ""? "0" : $("span.count").first().text());
 $("#article-body").html($("#contentdiv").html());
 $("pre").each(function(index, element){
 var cpLanguageName = $(this).attr("lang");
 var prismLanguageName = getPrismLanguageName(cpLanguageName);
 $(this).wrapInner("<code class='language-" + prismLanguageName + "'></code>");
 });
 Prism.highlightAll();
 $("#loading-container").hide();
 $("#article-container").show();
}); 

结束语

在本文中,我们将介绍CodeProject阅读器 Google Chrome 扩展的特性和内部工作。 我为实验 Chrome 扩展开发开始了一个有趣的项目,但后来发现它足以放入 Chrome web存储。 我希望你也会觉得有用。

cod  ext  style  CHR  chrome  ART  
相关文章