{"id":3745,"date":"2013-03-15T15:52:12","date_gmt":"2013-03-15T14:52:12","guid":{"rendered":"http:\/\/www.palentino.es\/blog\/?p=3745"},"modified":"2013-03-15T17:07:15","modified_gmt":"2013-03-15T16:07:15","slug":"las-extensiones-de-google-chrome-al-descubierto","status":"publish","type":"post","link":"https:\/\/www.palentino.es\/blog\/las-extensiones-de-google-chrome-al-descubierto\/","title":{"rendered":"Las extensiones de google Chrome, al descubierto &#8230;"},"content":{"rendered":"<p style=\"text-align: justify;\">Las extensiones de Google Chrome son peque\u00f1os programas que agregan porciones de funcionalidad al navegador o browser.<\/p>\n<p style=\"text-align: justify;\">Su instalaci\u00f3n es muy sencilla, sin necesidad de reiniciar el navegador, y poseen la caracter\u00edstica al igual que Chome de actualizarse autom\u00e1ticamente en modo silencioso, cuando existen nuevas versiones disponibles.<\/p>\n<p style=\"text-align: justify;\">Las extensiones han sido dise\u00f1adas por el equipo de google, tendiendo a los desarrolladores web muy presentes.\u00a0 Si sabes crear p\u00e1ginas web, tienes un gran paso dado, puesto que puedes desarrollar extensiones.<\/p>\n<p style=\"text-align: justify;\">De hecho,\u00a0 las extensiones se desarrollan respetando las tecnolog\u00edas est\u00e1ndar web, como pueden ser HTML, CSS, JS, etc.<\/p>\n<p style=\"text-align: justify;\">Una extensi\u00f3n es un fichero comprimido (en formato zip), con un conjunto de ficheros dentro del archivo.<\/p>\n<p style=\"text-align: justify;\">Sepamos algo m\u00e1s sobre ellas &#8230;<\/p>\n<p><!--more--><\/p>\n<p style=\"text-align: justify;\">Uno de los archivos importantes que toda extensi\u00f3n posee es el manifesto o manifiest . Posee un nombre \u00fanico y especial, manifest.json. Como su nombre indica, un fichero manifest es un JSON con datos formateados. Este formato es muy empleado usando Javascript para el intercambio de archivos. Este formato no requiere el uso de XML necesariamente. JSON se emplea en entornos donde el tama\u00f1o de los datos entre el cliente y el navegador es de fiar y no es importante disponer de procesamiento XSLT para manipular los datos en el cliente.<\/p>\n<p style=\"text-align: justify;\">Por lo tanto en el fichero manifest.json existen metadatos de configuraci\u00f3n de la extensi\u00f3n. Los permisos, componentes y otros recursos empleados. Estos componentes ofrecen a la extensi\u00f3n su funcionalidad.<\/p>\n<p style=\"text-align: justify;\"><strong>Estructura de una extensi\u00f3n.<\/strong><\/p>\n<p style=\"text-align: justify;\">Una extensi\u00f3n al menos posee algunos de los siguientes componentes.<\/p>\n<ul>\n<li style=\"text-align: justify;\">Browser action o Page action:\u00a0 Son dos de los Interfaces que la extensi\u00f3n posee. El browser action se encuentra en la barra de cada tab del navegador. El Page action aparece selectivamente en lo que se denomina omnibox, o icono al lado derecho\u00a0 de la barra de direcciones, y que puede ser desactivado o activado para cada tab. Una extensi\u00f3n puede tener s\u00f3lo una UI o interfaz. Browser o action.<\/li>\n<li style=\"text-align: justify;\"><span style=\"text-align: justify;\">Los Scripts de contenido o Content Scripts, que son CSS y Javascript inyectado o incluido en las p\u00e1ginas html. Se usan como hacemos con los scripts. Alternativa al browser o page actions.<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"text-align: justify;\">Las Background pages, son scripts completos que nos ayudan a gestionar el estado y coordinar tareas a trav\u00e9s de los componentes de la extensi\u00f3n. Cuando una extensi\u00f3n se vuelve m\u00e1s compleja, puede ser necesario el uso de una background page.<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"text-align: justify;\">Ficheros de utilidad web, un conjunto de archivos que pueden ser im\u00e1genes, bibliotecas javascript, pel\u00edculas flash, cualquier tipo de archivo que la extensi\u00f3n pueda necesitar.<\/span><\/li>\n<\/ul>\n<p style=\"text-align: justify;\">La API de las extensiones es peque\u00f1a y \u201cf\u00e1cil\u201d de aprender. Actualmente define unos <strong>40 objetos y 40 m\u00e9todos<\/strong>.<\/p>\n<p style=\"text-align: justify;\">Chrome es el nombre del objeto superior, que es expuesto autom\u00e1ticamente a todas las extensiones.<\/p>\n<p style=\"text-align: justify;\">La API se divide en <strong>6 m\u00f3dulos<\/strong>, que son representados por objetos que se encuentran contenidos en \u201cchrome\u201d<\/p>\n<ul>\n<li>Chrome.extension.*, proporciona m\u00e9todos y propiedades que nos permiten enviar mensajes para comunicarse entre los componentes de la extensi\u00f3n y resolver las URLS de los ficheros de extensi\u00f3n.<\/li>\n<li><span style=\"text-align: justify;\">Chrome.browserAction.*, nos permite establecer la apariencia de las acciones del navegador y de sus insignias o badges. \u00c1reas de texto, superpuestas sobre las acciones del navegador.<\/span><\/li>\n<li>Chrome.PageAction.*, nos permite activar o inhabilitar las acciones de p\u00e1gina.<\/li>\n<li>Chrome.windows.*, nos deja abrir, cerrar , buscar y actualizar ventanas del navegador. Requiere permiso de tabs en el manifest. Windows y tabs se encuentran estrechamente relacionados compartiendo permisos comunes.<\/li>\n<li>Chrome.tabs.*, nos permite realizar las mismas acciones en las pesta\u00f1as. Requiere tambi\u00e9n permisos en tab.<\/li>\n<li>Crhome .bookmark.*, nos permite leer y escribir en el \u00e1rbol de los bookmarks. Requiere permisos de bookmarks.<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">En el fichero de manifest aparece el nombre, versi\u00f3n de la extensi\u00f3n, una descripci\u00f3n, los iconos empleados, su posee browser_action\u00a0 (su icono, t\u00edtulo,\u00a0 p\u00e1gina html asociada, etc). Se establecen los permisos, si son sobre tabs, bookmarks, etc, Si posee una backbround page, la url de actualizaci\u00f3n, versi\u00f3n del manifest, infinidad de opciones parametrizables para la extensi\u00f3n.<\/p>\n<p style=\"text-align: justify;\"><strong>Sigamos<\/strong>.<\/p>\n<p style=\"text-align: justify;\">Por lo tango, podemos apreciar que programar una extensi\u00f3n es como programar una web, sigue una filosof\u00eda parecida y mismas tecnolog\u00edas. Donde el empleo de javascript dentro de las p\u00e1ginas es alto. Como hemos visto, muchas cosas que las extensiones pueden realizar, se logran gracias a la API proporcionada por crhome.<\/p>\n<p style=\"text-align: justify;\">Por ejemplo, si necesitamos dialogar con un servidor, podemos emplear XmlHttpRequest. Si necesitamos datos persistentes almacenados, podemos emplear cookies, LocalStorage o HTML5 Databases. Si necesitamos mostrar una p\u00e1gina de opciones, podemos emplear html y CSS.<\/p>\n<p style=\"text-align: justify;\">La API de google Chrome tambi\u00e9n proporciona acceso a objetos propios.<\/p>\n<p style=\"text-align: justify;\">Veamos un ejemplo:<\/p>\n<p style=\"text-align: justify;\">Este es el c\u00f3digo que muestra una extensi\u00f3n simple de un icono browser action.<\/p>\n<p style=\"text-align: justify;\">Cuando el usuario hace clic sobre \u00e9l, se abre una p\u00e1gina web que se encuentra incluida en los archivos de la extensi\u00f3n.<\/p>\n<p style=\"text-align: justify;\"><span style=\"color: #008000;\"><strong>Chrome.browserAction.onClicked.addListener (function(tab)<\/strong><\/span><br \/>\n<span style=\"color: #008000;\"> <strong> Chrome.tabs.create({url:chrome.extension.getURL(\u2018holamundo.html\u2019)});<\/strong><\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"color: #008000;\"><strong>});<\/strong><\/span><\/p>\n<p style=\"text-align: justify;\">Podemos identificar en el c\u00f3digo superior que se emplea el namespace o espacio de nombes \u201cchrome\u201d . Chrome es un objeto global que toda extensi\u00f3n puede llamar y usar. Esta API de extensiones s\u00f3lo es visible en este \u00e1mbito. Usamos los m\u00f3dulos browserActions , Tabs y extension.\u00a0 Lo primero es un evento que registra la acci\u00f3n al hacer clic sobre el icono del browser.<\/p>\n<p style=\"text-align: justify;\">Un dato importante son los tipos de llamadas a las funciones. Existen funciones<strong> s\u00edncronas y as\u00edncronas<\/strong>. Muchas llamadas a la API son s\u00edncronas, pero otras son as\u00edncronas.<\/p>\n<p style=\"text-align: justify;\">La llamada s\u00edncrona espera a que finalice el m\u00e9todo, es decir, no se ejecutar la funci\u00f3n siguiente hasta que no se termine la actual. A diferencia del as\u00edncrono que no espera, contin\u00faa con otra llamada.<\/p>\n<p style=\"text-align: justify;\">Los callbacks son funciones que se ejecutan despu\u00e9s de que finalice otra, y se pueden encadenar.<\/p>\n<p style=\"text-align: justify;\">Veamos un ejemplo:<\/p>\n<p style=\"text-align: justify;\"><span style=\"color: #008000;\"><strong>Crhome.bookmarks.update(42, { title:\u201dNuevo t\u00edtulo\u201d},<\/strong><\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"color: #008000;\"><strong>Function(bookmarkNode) {<\/strong><\/span><br \/>\n<span style=\"color: #008000;\"> <strong> \u00a0\u00a0 \/\/ hacer algo con el marcador cambiado<\/strong><\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"color: #008000;\"><strong>});<\/strong><\/span><\/p>\n<p style=\"text-align: justify;\">En el ejemplo superior, le decimos a google chrome que modifique uno de los marcadores del usuario, cambiando su t\u00edtulo. Esta llamada es as\u00edncrona, lo que significa que el c\u00f3digo que realiza la llamada continuar\u00e1 ejecut\u00e1ndose y la funci\u00f3n que desplegamos realizar\u00e1 un cambio despu\u00e9s, una vez que el marcador se cambie. En este caso se explica lo que se denomina callback, har\u00e1 algo cuando el marcador se cambie, pero no espera de manera s\u00edncrona a ello.<\/p>\n<p style=\"text-align: justify;\">Las llamadas as\u00edncronas cobran sentido en google Chrome y su arquitectura multiproceso. Las p\u00e1ginas web y javascript se ejecuta en procesos separados, aislamiento y multitarea de los mismos.<\/p>\n<p style=\"text-align: justify;\">Si las llamadas como el ejemplo superior fuesen s\u00edncronas, nuestra extensi\u00f3n tendr\u00eda que parar cada vez que se realiza un cambio y esperar al que el navegador responda, perdiendo iteraci\u00f3n con el usuario.<\/p>\n<p style=\"text-align: justify;\">El uso de APIS as\u00edncronas es m\u00e1s costoso, pero ofrece un mayor servicio y experiencia al usuario.<\/p>\n<p style=\"text-align: justify;\">Por lo tango es mejor escribir c\u00f3digo de la siguiente forma as\u00edncrona:<\/p>\n<p style=\"text-align: justify;\"><span style=\"color: #008000;\"><strong>Chrome.someModule.doSomething (1,function(resultado){<\/strong><\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"color: #008000;\"><strong>Chrome.otherModule.doSomeThingElse(resultado.value,<\/strong><\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"color: #008000;\"><strong>Function(OtroResultado)<\/strong><\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"color: #008000;\"><strong>\u00a0\/\/ haz mas cosas<\/strong><\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"color: #008000;\"><strong>});});<\/strong><\/span><\/p>\n<p style=\"text-align: justify;\">En vez de esta, s\u00edncrona:<\/p>\n<p style=\"text-align: justify;\"><span style=\"color: #008000;\"><strong>var resultado=chrome.someModule.doSometing(1):<\/strong><\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"color: #008000;\"><strong>var OtroResultado=chrome.otherModule.doSomeThingElse(\u201ctest\u201d,<\/strong><\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"color: #008000;\"><strong>resultado.value);<\/strong><\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"color: #008000;\"><strong>\/\/ haz mas cosas<\/strong><\/span><\/p>\n<p style=\"text-align: justify;\"><b>Publicar una extensi\u00f3n.<\/b><\/p>\n<p style=\"text-align: justify;\">Es necesario aclarar que la primera vez que publicamos algo en el \u00e1rea de desarrolladores de google, es necesario pagar 5$. Por lo tanto el primer plugin te va a costar dinero.<\/p>\n<p style=\"text-align: justify;\">La publicaci\u00f3n de extensiones se realiza en la galer\u00eda de google. Una vez que hemos desarrollado la extensi\u00f3n, y todos los archivos se encuentran en la carpeta, lo primero que tenemos que hacer es comprobar los datos del manifest, como son el t\u00edtulo, la descripci\u00f3n, y que los recursos se encuentren todos en la carpeta. El icono tiene especial relevancia, puesto que son cosas que se muestran a los usuarios cuando lo descargan.<\/p>\n<p style=\"text-align: justify;\">Con toda la carpeta seleccionada, hacemos un fichero zip, con cualquier compresor est\u00e1ndar. Este fichero le subimos a la galer\u00eda.<\/p>\n<p style=\"text-align: justify;\"><a href=\"https:\/\/chrome.google.com\/webstore\/category\/extensions\">https:\/\/chrome.google.com\/webstore\/category\/extensions<\/a><\/p>\n<p style=\"text-align: justify;\">Para ello es necesario acceder al dashboard.<\/p>\n<p style=\"text-align: justify;\"><a href=\"https:\/\/chrome.google.com\/webstore\/developer\/dashboard\" target=\"_blank\">https:\/\/chrome.google.com\/webstore\/developer\/dashboard<\/a><\/p>\n<p style=\"text-align: justify;\">En el dashboard podemos ver todas las extensiones que hemos subido. Pulsamos en a\u00f1adir nuevo elemento y subimos el zip. Nos aparecer\u00e1n unas opciones relacionadas con el plugin que queremos subir, informaci\u00f3n, iconos, screenshots, direcciones, etc.<\/p>\n<p style=\"text-align: justify;\">Para finalizar podemos ver una preview o publicar el plugin de forma definitiva.<\/p>\n<p style=\"text-align: justify;\"><b>Singularidades<\/b><\/p>\n<p style=\"text-align: justify;\">No todas las extensiones realizadas necesitan estar publicadas en\u00a0 la web de google.\u00a0 Podemos tener archivos CRX (hablar\u00e9 sobre ellos) que se agregar\u00e1n en la opci\u00f3n extensiones del navegador, mediante drag-drop. Antiguamente se hac\u00eda haciendo doble click sobre el crx, pero esto ha cambiado.<\/p>\n<p style=\"text-align: justify;\">Todas las extensiones poseen un ID que se puede apreciar activando el modo desarrollador dentro del google chrome. Esta Id posee 32 caracteres, que identifican un\u00edvocamente de forma global a la extensi\u00f3n. Esto se realiza para evitar conflictos entre extensiones. Esta asignaci\u00f3n la realiza google crhome y evita tener una central que autorice los IDs generados. El mecanismo empleado es un par de claves p\u00fablica y privada para la extensi\u00f3n. Con el hash de la clave p\u00fablica se determina el ID de extensi\u00f3n. Todo esto se realiza de forma autom\u00e1tica por google cuando se sube un archivo zip.<\/p>\n<p style=\"text-align: justify;\">Las extensiones de google se empaquetan en archivos crx, si usamos la galer\u00eda de google para publicar archivos, con el bot\u00f3n publicar, google genera el crx por nosotros. Pero este proceso le podemos hacer nosotros desde el navegador con el bot\u00f3n \u201cPack extensi\u00f3n\u201d en las opciones de extensiones de google chrome.<\/p>\n<p style=\"text-align: justify;\">Un fichero crx es realmente un archivo zip con 2 cosas a\u00f1adidas, una clave p\u00fablica, y un signature o firma del contenido generado por la clave privada, adem\u00e1s de los contenidos l\u00f3gicamente.<\/p>\n<p style=\"text-align: justify;\">Cuando instalamos un crx, google chrome extrae la clave p\u00fablica, la firma y el contenido zip, y se asegura que el contenido es v\u00e1lido usando la clave p\u00fablica.<\/p>\n<p style=\"text-align: justify;\">Otra singularidad es que dentro del fichero manifest.json del plugin puede aparecer la opci\u00f3n update_url, es una direcci\u00f3n que el navegador comprueba cada cierto tiempo (horas) en busca de un fichero xml, indicando si existen cambios. L\u00f3gicamente nosotros no nos damos cuenta puesto que es autom\u00e1tico y silencioso. El navegador puede actualizar ficheros crx sin necesidad de conexi\u00f3n ssl porque comprueba la firma dentro del crx antes de instalarle. Si se deposita la extensi\u00f3n dentro de la galer\u00eda de google no necesitaremos preocuparnos de la autoactualizaci\u00f3n ellos lo har\u00e1n por nosotros, ni de incluir esa l\u00ednea. Pero si la hospedamos nosotros tendremos que incluir el update_url dentro del manifest. Proteger esa clave privada es muy importante cuando somos nosotros quienes hospedamos las extensiones.<\/p>\n<p style=\"text-align: justify;\">El entorno de desarrollo que proporciona google Chrome al inspeccionar un elemento, es realmente potente. Podemos a\u00f1adir breakpoints a c\u00f3digo fuente javascript y realizar un debug paso a paso con las teclas f10 y f11. Para ello segundo bot\u00f3n del rat\u00f3n sobre un elemento, inspeccionar elemento. Opci\u00f3n sources, picamos en el cuadrado peque\u00f1o superior izquierdo, seleccionamos la p\u00e1gina, y marcamos los breakpoints en el lateral. Permite a\u00f1adir expresiones a debugear, ver la pila de\u00a0llamadas,\u00a0\u00e1mbitos, etc &#8230;<\/p>\n<p style=\"text-align: justify;\">Este grado de depuraci\u00f3n no lo he\u00a0conseguido\u00a0con Firebug.<\/p>\n<p style=\"text-align: justify;\"><a href=\"http:\/\/www.palentino.es\/blog\/wp-content\/uploads\/2013\/03\/Developer-tools.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3762\" alt=\"Developer-tools\" src=\"http:\/\/www.palentino.es\/blog\/wp-content\/uploads\/2013\/03\/Developer-tools.png\" width=\"613\" height=\"442\" srcset=\"https:\/\/www.palentino.es\/blog\/wp-content\/uploads\/2013\/03\/Developer-tools.png 613w, https:\/\/www.palentino.es\/blog\/wp-content\/uploads\/2013\/03\/Developer-tools-300x216.png 300w\" sizes=\"auto, (max-width: 613px) 100vw, 613px\" \/><\/a><\/p>\n<p style=\"text-align: justify;\"><b>M\u00e1s cositas, esto es muy interesante, me ha costado averiguarlo.<\/b><\/p>\n<p style=\"text-align: justify;\"><span style=\"color: #800000;\"><strong>TRUCO o TRAMPA<\/strong><\/span><\/p>\n<p style=\"text-align: justify;\">Para aprender r\u00e1pidamente como desarrollar extensiones, podemos observar y analizar las extensiones de los dem\u00e1s, existen muchas. \u00a0Es la manera m\u00e1s r\u00e1pida de aprender a desarrollar.<\/p>\n<p style=\"text-align: justify;\">Pero,\u00a0 Tenemos un problema, cuando descargamos los crx no vemos donde se almacenan, no sabemos c\u00f3mo ver el contenido. Nos gusta una extensi\u00f3n, queremos traducirla al castellano, queremos mejorarla, aprender de ella para desarrollar otra \u00a0y no sabemos c\u00f3mo ver el contenido, ya que realmente es html y javascript. Sabemos que la ayuda se encuentra\u00a0 en ingles, no todo el mundo lo conoce y es difusa.<\/p>\n<p style=\"text-align: justify;\">No tengo ni idea de c\u00f3mo empezar.<\/p>\n<p style=\"text-align: justify;\">Tranquilos, os dir\u00e9 un truco, muy bueno\u2026, espero que google no se enfade \ud83d\ude09<\/p>\n<p style=\"text-align: justify;\"><strong>Vamos por partes. Esto es lo que he descubierto.<\/strong><\/p>\n<p style=\"text-align: justify;\">Primero sabemos que los crx son archivos zip. Pero no sabemos donde se almacenan ni c\u00f3mo recuperarlos,<\/p>\n<p style=\"text-align: justify;\">hasta ahora\u2026<\/p>\n<p style=\"text-align: justify;\">Si intentamos descargarlos con otro navegador alternativo, no podemos, puesto que nos pide google chrome para ello.<\/p>\n<p style=\"text-align: justify;\"><a href=\"http:\/\/www.palentino.es\/blog\/wp-content\/uploads\/2013\/03\/Plugin-ID.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3763\" alt=\"Plugin-ID\" src=\"http:\/\/www.palentino.es\/blog\/wp-content\/uploads\/2013\/03\/Plugin-ID.png\" width=\"780\" height=\"566\" srcset=\"https:\/\/www.palentino.es\/blog\/wp-content\/uploads\/2013\/03\/Plugin-ID.png 780w, https:\/\/www.palentino.es\/blog\/wp-content\/uploads\/2013\/03\/Plugin-ID-300x217.png 300w\" sizes=\"auto, (max-width: 780px) 100vw, 780px\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">En la ventana superior, capturado de herramientas-&gt; extensiones, vemos como hemos activado el modo desarrollador, se pueden apreciar los IDs de cada extensi\u00f3n &#8230;, acordaos de esto.<\/p>\n<ol>\n<li>Descargamos el plugin que nos interesa aprender, de la galer\u00eda de extensiones de google<\/li>\n<li>Vamos a opciones en google crhome, herramientas, extensiones.<\/li>\n<li>Activamos la casilla superior, modo de desarrollador.<\/li>\n<li>Observamos el\u00a0 Id que aparece en la extensi\u00f3n a mejorar. Un Hash de 32 bits.<\/li>\n<li>Ese ID es la carpeta que vamos a buscar en el disco duro de nuestro ordenador.<\/li>\n<li>En funci\u00f3n del sistema operativo se almacena en una ruta u otra, en este caso os dejo la ruta de<br \/>\nen Windows 7:<br \/>\n<strong><strong>C:\\Users\\mi_usuario\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Extensions\\la_clave_id_larga_generada_que_vemos<br \/>\n<\/strong><\/strong>en Windows 8:<br \/>\n<strong>C:\\Users\\golden\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Extensions<\/strong><\/li>\n<\/ol>\n<p style=\"text-align: justify;\">Recordar que la unidad puede cambiar, en funci\u00f3n de d\u00f3nde se encuentra el sistema instalado, y es muy importante activar la casilla, mostrar archivos ocultos. En la imagen se observan las carpetas con cada una de las extensiones y su respectivo ID.<\/p>\n<p style=\"text-align: justify;\"><a href=\"http:\/\/www.palentino.es\/blog\/wp-content\/uploads\/2013\/03\/extensiones-instaladas.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3770\" alt=\"extensiones-instaladas\" src=\"http:\/\/www.palentino.es\/blog\/wp-content\/uploads\/2013\/03\/extensiones-instaladas.png\" width=\"790\" height=\"501\" srcset=\"https:\/\/www.palentino.es\/blog\/wp-content\/uploads\/2013\/03\/extensiones-instaladas.png 790w, https:\/\/www.palentino.es\/blog\/wp-content\/uploads\/2013\/03\/extensiones-instaladas-300x190.png 300w\" sizes=\"auto, (max-width: 790px) 100vw, 790px\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">Voil\u00e1, ese es el c\u00f3digo fuente de \u00a0la extensi\u00f3n. \u00a0Ya pod\u00e9is estudiarla.<\/p>\n<p style=\"text-align: justify;\">Nota: Puede aparecer ofuscado, el desarrollador puede no ser tan tonto, o no querer compartir c\u00f3digo \u2026<\/p>\n<p style=\"text-align: justify;\">Esta es la direcci\u00f3n inicial<\/p>\n<p style=\"text-align: justify;\"><a href=\"https:\/\/developer.chrome.com\/extensions\/api_index.html\" target=\"_blank\">https:\/\/developer.chrome.com\/extensions\/api_index.html<\/a><\/p>\n<p style=\"text-align: justify;\">Eso es todo, a crear plugins, pero en castellano por favor\u2026 \ud83d\ude09 hay mucho en ingl\u00e9s, mejoremos chrome en nuestro idioma\u2026<\/p>\n<p style=\"text-align: justify;\">A por ellos.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Las extensiones de Google Chrome son peque\u00f1os programas que agregan porciones de funcionalidad al navegador o browser. Su instalaci\u00f3n es muy sencilla, sin necesidad de reiniciar el navegador, y poseen la caracter\u00edstica al igual que Chome de actualizarse autom\u00e1ticamente en modo silencioso, cuando existen nuevas versiones disponibles. Las extensiones han sido dise\u00f1adas por el equipo de google, tendiendo a los desarrolladores web muy presentes.\u00a0 Si sabes crear p\u00e1ginas web, tienes un gran paso dado, puesto que puedes desarrollar extensiones. De hecho,\u00a0 las extensiones se desarrollan respetando las tecnolog\u00edas est\u00e1ndar web, como pueden ser HTML, CSS, JS, etc. Una extensi\u00f3n es un fichero comprimido (en formato zip), con un conjunto de ficheros dentro del archivo. Sepamos algo m\u00e1s sobre ellas &#8230;<\/p>\n","protected":false},"author":1,"featured_media":3758,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[364,5,14,24],"tags":[683,365],"class_list":["post-3745","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-chrome","category-programacion","category-varios","category-web","tag-chrome","tag-extensiones"],"_links":{"self":[{"href":"https:\/\/www.palentino.es\/blog\/wp-json\/wp\/v2\/posts\/3745","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.palentino.es\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.palentino.es\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.palentino.es\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.palentino.es\/blog\/wp-json\/wp\/v2\/comments?post=3745"}],"version-history":[{"count":19,"href":"https:\/\/www.palentino.es\/blog\/wp-json\/wp\/v2\/posts\/3745\/revisions"}],"predecessor-version":[{"id":3774,"href":"https:\/\/www.palentino.es\/blog\/wp-json\/wp\/v2\/posts\/3745\/revisions\/3774"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.palentino.es\/blog\/wp-json\/wp\/v2\/media\/3758"}],"wp:attachment":[{"href":"https:\/\/www.palentino.es\/blog\/wp-json\/wp\/v2\/media?parent=3745"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.palentino.es\/blog\/wp-json\/wp\/v2\/categories?post=3745"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.palentino.es\/blog\/wp-json\/wp\/v2\/tags?post=3745"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}