-
Notifications
You must be signed in to change notification settings - Fork 263
Bug 837494 - re-implement contentStyle*
using the new nsIDOMWindowUtils methods
#839
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,105 @@ | |||
<!-- This Source Code Form is subject to the terms of the Mozilla Public | |||
- License, v. 2.0. If a copy of the MPL was not distributed with this | |||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. --> | |||
|
|||
The `mod` module provides functions to modify a page content. | |||
|
|||
<api name="attachTo"> | |||
@function | |||
Function applies given `modification` to a given `window`. | |||
|
|||
For example, the following code applies a style to a content window, adding | |||
a border to all divs in page: | |||
|
|||
var attachTo = require("sdk/content/mod").attachTo; | |||
var Style = require("sdk/stylesheet/style").Style; | |||
|
|||
var style = Style({ | |||
source: "div { border: 4px solid gray }" | |||
}); | |||
|
|||
// assuming window points to the content page we want to modify | |||
attachTo(style, window); | |||
|
|||
@param modification {object} | |||
The modification we want to apply to the target. | |||
|
|||
@param window {nsIDOMWindow} | |||
The window to be modified. | |||
</api> | |||
|
|||
<api name="detachFrom"> | |||
@function | |||
Function removes attached `modification` from a given `window`. | |||
If `window` is not specified, `modification` is removed from all the windows | |||
it's being attached to. | |||
|
|||
For example, the following code applies and removes a style to a content | |||
window, adding a border to all divs in page: | |||
|
|||
var { attachTo, detachFrom } = require("sdk/content/mod"); | |||
var Style = require("sdk/stylesheet/style").Style; | |||
|
|||
var style = Style({ | |||
source: "div { border: 4px solid gray }" | |||
}); | |||
|
|||
// assuming window points to the content page we want to modify | |||
attachTo(style, window); | |||
// ... | |||
detachFrom(style, window); | |||
|
|||
@param modification {object} | |||
The modification we want to remove from the target | |||
|
|||
@param window {nsIDOMWindow} | |||
The window to be modified. | |||
If `window` is not provided `modification` is removed from all targets it's | |||
being attached to. | |||
</api> | |||
|
|||
<api name="getTargetWindow"> | |||
@function | |||
Function takes `target`, value representing content (page) and returns | |||
`nsIDOMWindow` for that content. | |||
If `target` does not represents valid content `null` is returned. | |||
For example target can be a content window itself in which case it's will be | |||
returned back. | |||
|
|||
@param target {object} | |||
The object for which we want to obtain the window represented or contained. | |||
If a `nsIDOMWindow` is given, it works as an identify function, returns | |||
`target` itself. | |||
@returns {nsIDOMWindow|null} | |||
The window represented or contained by the `target`, if any. Returns `null` | |||
otherwise. | |||
</api> | |||
|
|||
<api name="attach"> | |||
@function | |||
Function applies given `modification` to a given `target` representing a | |||
content to be modified. | |||
|
|||
@param modification {object} | |||
The modification we want to apply to the target | |||
|
|||
@param target {object} | |||
Target is a value that representing content to be modified. It is valid only | |||
when `getTargetWindow(target)` returns nsIDOMWindow of content it represents. | |||
</api> | |||
|
|||
<api name="detach"> | |||
@function | |||
Function removes attached `modification`. If `target` is specified | |||
`modification` is removed from that `target` only, otherwise `modification` is | |||
removed from all the targets it's being attached to. | |||
|
|||
@param modification {object} | |||
The modification we want to remove from the target | |||
|
|||
@param target {object} | |||
Target is a value that representing content to be modified. It is valid only | |||
when `getTargetWindow(target)` returns `nsIDOMWindow` of content it represents. | |||
If `target` is not provided `modification` is removed from all targets it's | |||
being attached to. | |||
</api> |
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,53 @@ | |||
<!-- This Source Code Form is subject to the terms of the Mozilla Public | |||
- License, v. 2.0. If a copy of the MPL was not distributed with this | |||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. --> | |||
|
|||
Module provides `Style` function that can be used to construct content style | |||
modification via stylesheet files or CSS rules. | |||
|
|||
<api name="Style"> | |||
@class | |||
<api name="Style"> | |||
@constructor | |||
The Style constructor creates an object that represents style modifications | |||
via stylesheet file(s) or/and CSS rules. Stylesheet file URL(s) are verified | |||
to be local to an add-on, while CSS rules are virified to be a string or | |||
array of strings. | |||
|
|||
The style created can be applied to a content by calling `attach`, | |||
and removed using `detach`. Those functions are part of [content/mod](modules/sdk/content/mod.html) module. | |||
@param options {object} | |||
Options for the style. All these options are optional. Although if you | |||
don't supply any stylesheet or CSS rules, your style won't be very useful. | |||
|
|||
@prop uri {string,array} | |||
A string, or an array of strings, that represents local URI to stylesheet. | |||
@prop source {string,array} | |||
A string, or an array of strings, that contains CSS rules. Those rules | |||
are applied after the rules in the stylesheet specified with `uri` options, | |||
if provided. | |||
@prop [type="author"] {string} | |||
The type of the sheet. It accepts the following values: `"agent"`, `"user"` | |||
and `"author"`. | |||
If not provided, the default value is `"author"`. | |||
</api> | |||
|
|||
<api name="source"> | |||
@property {string} | |||
An array of strings that contains the CSS rule(s) specified in the constructor's | |||
option; `null` if no `source` option was given to the constructor. | |||
This property is read-only. | |||
</api> | |||
<api name="uri"> | |||
@property {string} | |||
An array of strings that contains the stylesheet local URI(s) specified in the | |||
constructor's option; `null` if no `uri` option was given to the | |||
constructor. | |||
This property is read-only. | |||
</api> | |||
<api name="type"> | |||
@property {string} | |||
The type of the sheet. If no type is provided in constructor's option, | |||
it returns the default value, `"author"`. This property is read-only. | |||
</api> | |||
</api> | |||
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,41 @@ | |||
<!-- This Source Code Form is subject to the terms of the Mozilla Public | |||
- License, v. 2.0. If a copy of the MPL was not distributed with this | |||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. --> | |||
|
|||
Module provides helper functions for working with stylesheets. | |||
|
|||
<api name="loadSheet"> | |||
@function | |||
Synchronously loads a style sheet from `uri` and adds it to the list of | |||
additional style sheets of the document. | |||
The sheets added takes effect immediately, and only on the document of the | |||
`window` given. | |||
@param window {nsIDOMWindow} | |||
@param uri {string, nsIURI} | |||
@param [type="author"] {string} | |||
The type of the sheet. It accepts the following values: `"agent"`, `"user"` | |||
and `"author"`. | |||
If not provided, the default value is `"author"`. | |||
</api> | |||
|
|||
<api name="removeSheet"> | |||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't remember if it was me who suggested it in first place but I think it's better to have load/unload or add/remove Sheet There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was made to be consistent with the platform's name. I think they're actually good and they express exactly what they did. Why you think is no good with them? |
|||
@function | |||
Remove the document style sheet at `sheetURI` from the list of additional | |||
style sheets of the document. The removal takes effect immediately. | |||
@param window {nsIDOMWindow} | |||
@param uri {string, nsIURI} | |||
@param [type="author"] {string} | |||
The type of the sheet. It accepts the following values: `"agent"`, `"user"` | |||
and `"author"`. | |||
If not provided, the default value is `"author"`. | |||
</api> | |||
|
|||
<api name="isTypeValid"> | |||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I checked with native language speaker (aka, @jsantell) about if noun should be before or after the the "valid" part, and he said that About the too generic name: we have tons of generic name, but I always though that the module worked as context (see for instance |
|||
@function | |||
Verifies that the `type` given is a valid stylesheet's type. | |||
The values considered valid are: `"agent"`, `"user"` and `"author"`. | |||
@param type {string} | |||
The type of the sheet. | |||
@returns {boolean} | |||
`true` if the `type` given is valid, otherwise `false`. | |||
</api> |
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,60 @@ | |||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | |||
/* vim:set ts=2 sw=2 sts=2 et: */ | |||
/* This Source Code Form is subject to the terms of the Mozilla Public | |||
* License, v. 2.0. If a copy of the MPL was not distributed with this | |||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |||
"use strict"; | |||
|
|||
module.metadata = { | |||
"stability": "experimental" | |||
}; | |||
|
|||
const { Ci } = require("chrome"); | |||
const method = require("method/core"); | |||
const { add, remove, iterator } = require("../lang/weak-set"); | |||
|
|||
let getTargetWindow = method("getTargetWindow"); | |||
|
|||
getTargetWindow.define(function (target) { | |||
if (target instanceof Ci.nsIDOMWindow) | |||
return target; | |||
if (target instanceof Ci.nsIDOMDocument) | |||
return target.defaultView || null; | |||
|
|||
return null; | |||
}); | |||
|
|||
exports.getTargetWindow = getTargetWindow; | |||
|
|||
let attachTo = method("attachTo"); | |||
exports.attachTo = attachTo; | |||
|
|||
let detachFrom = method("detatchFrom"); | |||
exports.detachFrom = detachFrom; | |||
|
|||
function attach(modification, target) { | |||
let window = getTargetWindow(target); | |||
|
|||
attachTo(modification, window); | |||
|
|||
// modification are stored per content; `window` reference can still be the | |||
// same even if the content is changed, therefore `document` is used instead. | |||
add(modification, window.document); | |||
} | |||
exports.attach = attach; | |||
|
|||
function detach(modification, target) { | |||
if (target) { | |||
let window = getTargetWindow(target); | |||
detachFrom(modification, window); | |||
remove(modification, window.document); | |||
} | |||
else { | |||
let documents = iterator(modification); | |||
for (let document of documents) { | |||
detachFrom(modification, document.defaultView); | |||
remove(modification, document); | |||
} | |||
} | |||
} | |||
exports.detach = detach; |
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,56 @@ | |||
"use strict"; | |||
|
|||
const { Cu } = require("chrome"); | |||
|
|||
function makeGetterFor(Type) { | |||
let cache = new WeakMap(); | |||
|
|||
return function getFor(target) { | |||
if (!cache.has(target)) | |||
cache.set(target, new Type()); | |||
|
|||
return cache.get(target); | |||
} | |||
} | |||
|
|||
let getLookupFor = makeGetterFor(WeakMap); | |||
let getRefsFor = makeGetterFor(Set); | |||
|
|||
function add(target, value) { | |||
if (has(target, value)) | |||
return; | |||
|
|||
getLookupFor(target).set(value, true); | |||
getRefsFor(target).add(Cu.getWeakReference(value)); | |||
} | |||
exports.add = add; | |||
|
|||
function remove(target, value) { | |||
getLookupFor(target).delete(value); | |||
} | |||
exports.remove = remove; | |||
|
|||
function has(target, value) { | |||
return getLookupFor(target).has(value); | |||
} | |||
exports.has = has; | |||
|
|||
function clear(target) { | |||
getLookupFor(target).clear(); | |||
getRefsFor(target).clear(); | |||
} | |||
exports.clear = clear; | |||
|
|||
function iterator(target) { | |||
let refs = getRefsFor(target); | |||
|
|||
for (let ref of refs) { | |||
let value = ref.get(); | |||
|
|||
if (has(target, value)) | |||
yield value; | |||
else | |||
refs.delete(ref); | |||
} | |||
} | |||
exports.iterator = iterator; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would also mention in docs that style can be applied to a content by calling
attach(style, window)
or removed usingdetach(style, window)
and would refer tocontent/mod
docs for more details.